28
28
use OCA \User_SAML \Exceptions \NoUserFoundException ;
29
29
use OCA \User_SAML \SAMLSettings ;
30
30
use OCA \User_SAML \UserBackend ;
31
+ use OCA \User_SAML \UserData ;
32
+ use OCA \User_SAML \UserResolver ;
31
33
use OCP \AppFramework \Controller ;
32
34
use OCP \AppFramework \Http ;
33
35
use OCP \IConfig ;
@@ -58,12 +60,14 @@ class SAMLController extends Controller {
58
60
private $ config ;
59
61
/** @var IURLGenerator */
60
62
private $ urlGenerator ;
61
- /** @var IUserManager */
62
- private $ userManager ;
63
63
/** @var ILogger */
64
64
private $ logger ;
65
65
/** @var IL10N */
66
66
private $ l ;
67
+ /** @var UserResolver */
68
+ private $ userResolver ;
69
+ /** @var UserData */
70
+ private $ userData ;
67
71
/**
68
72
* @var ICrypto
69
73
*/
@@ -78,94 +82,81 @@ class SAMLController extends Controller {
78
82
* @param UserBackend $userBackend
79
83
* @param IConfig $config
80
84
* @param IURLGenerator $urlGenerator
81
- * @param IUserManager $userManager
82
85
* @param ILogger $logger
83
86
* @param IL10N $l
84
87
*/
85
- public function __construct ($ appName ,
86
- IRequest $ request ,
87
- ISession $ session ,
88
- IUserSession $ userSession ,
89
- SAMLSettings $ SAMLSettings ,
90
- UserBackend $ userBackend ,
91
- IConfig $ config ,
92
- IURLGenerator $ urlGenerator ,
93
- IUserManager $ userManager ,
94
- ILogger $ logger ,
95
- IL10N $ l ,
96
- ICrypto $ crypto ) {
88
+ public function __construct (
89
+ $ appName ,
90
+ IRequest $ request ,
91
+ ISession $ session ,
92
+ IUserSession $ userSession ,
93
+ SAMLSettings $ SAMLSettings ,
94
+ UserBackend $ userBackend ,
95
+ IConfig $ config ,
96
+ IURLGenerator $ urlGenerator ,
97
+ ILogger $ logger ,
98
+ IL10N $ l ,
99
+ UserResolver $ userResolver ,
100
+ UserData $ userData ,
101
+ ICrypto $ crypto
102
+ ) {
97
103
parent ::__construct ($ appName , $ request );
98
104
$ this ->session = $ session ;
99
105
$ this ->userSession = $ userSession ;
100
106
$ this ->SAMLSettings = $ SAMLSettings ;
101
107
$ this ->userBackend = $ userBackend ;
102
108
$ this ->config = $ config ;
103
109
$ this ->urlGenerator = $ urlGenerator ;
104
- $ this ->userManager = $ userManager ;
105
110
$ this ->logger = $ logger ;
106
111
$ this ->l = $ l ;
112
+ $ this ->userResolver = $ userResolver ;
113
+ $ this ->userData = $ userData ;
107
114
$ this ->crypto = $ crypto ;
108
115
}
109
116
110
117
/**
111
- * @param array $auth
112
118
* @throws NoUserFoundException
113
119
*/
114
- private function autoprovisionIfPossible (array $ auth ) {
120
+ private function autoprovisionIfPossible () {
121
+ $ auth = $ this ->userData ->getAttributes ();
115
122
116
- $ prefix = $ this ->SAMLSettings ->getPrefix ();
117
- $ uidMapping = $ this ->config ->getAppValue ('user_saml ' , $ prefix . 'general-uid_mapping ' );
118
- if (isset ($ auth [$ uidMapping ])) {
119
- if (is_array ($ auth [$ uidMapping ])) {
120
- $ uid = $ auth [$ uidMapping ][0 ];
121
- } else {
122
- $ uid = $ auth [$ uidMapping ];
123
- }
124
-
125
- // make sure that a valid UID is given
126
- if (empty ($ uid )) {
127
- $ this ->logger ->error ('Uid " ' . $ uid . '" is not a valid uid please check your attribute mapping ' , ['app ' => $ this ->appName ]);
128
- throw new \InvalidArgumentException ('No valid uid given, please check your attribute mapping. Given uid: ' . $ uid );
129
- }
130
-
131
- $ uid = $ this ->userBackend ->testEncodedObjectGUID ($ uid );
132
-
133
- // if this server acts as a global scale master and the user is not
134
- // a local admin of the server we just create the user and continue
135
- // no need to update additional attributes
136
- $ isGsEnabled = $ this ->config ->getSystemValue ('gs.enabled ' , false );
137
- $ isGsMaster = $ this ->config ->getSystemValue ('gss.mode ' , 'slave ' ) === 'master ' ;
138
- $ isGsMasterAdmin = in_array ($ uid , $ this ->config ->getSystemValue ('gss.master.admin ' , []));
139
- if ($ isGsEnabled && $ isGsMaster && !$ isGsMasterAdmin ) {
140
- $ this ->userBackend ->createUserIfNotExists ($ uid );
141
- return ;
142
- }
143
- $ userExists = $ this ->userManager ->userExists ($ uid );
144
- $ autoProvisioningAllowed = $ this ->userBackend ->autoprovisionAllowed ();
145
- if ($ userExists === true ) {
146
- if ($ autoProvisioningAllowed ) {
147
- $ this ->userBackend ->updateAttributes ($ uid , $ auth );
148
- }
149
- return ;
150
- }
123
+ if (!$ this ->userData ->hasUidMappingAttribute ()) {
124
+ throw new NoUserFoundException ('IDP parameter for the UID not found. Possible parameters are: ' . json_encode (array_keys ($ auth )));
125
+ }
151
126
152
- if (!$ userExists && !$ autoProvisioningAllowed ) {
153
- // it is possible that the user was not logged in before and
154
- // thus is not known to the original backend. A search can
155
- // help with it and make the user known
156
- $ this ->userManager ->search ($ uid );
157
- if ($ this ->userManager ->userExists ($ uid )) {
158
- return ;
159
- }
160
- throw new NoUserFoundException ('Auto provisioning not allowed and user ' . $ uid . ' does not exist ' );
161
- } elseif (!$ userExists && $ autoProvisioningAllowed ) {
162
- $ this ->userBackend ->createUserIfNotExists ($ uid , $ auth );
127
+ if ($ this ->userData ->getOriginalUid () === '' ) {
128
+ $ this ->logger ->error ('Uid is not a valid uid please check your attribute mapping ' , ['app ' => $ this ->appName ]);
129
+ throw new \InvalidArgumentException ('No valid uid given, please check your attribute mapping. ' );
130
+ }
131
+ $ uid = $ this ->userData ->getEffectiveUid ();
132
+ $ userExists = $ uid !== '' ;
133
+
134
+ // if this server acts as a global scale master and the user is not
135
+ // a local admin of the server we just create the user and continue
136
+ // no need to update additional attributes
137
+ $ isGsEnabled = $ this ->config ->getSystemValue ('gs.enabled ' , false );
138
+ $ isGsMaster = $ this ->config ->getSystemValue ('gss.mode ' , 'slave ' ) === 'master ' ;
139
+ $ isGsMasterAdmin = in_array ($ uid , $ this ->config ->getSystemValue ('gss.master.admin ' , []));
140
+ if ($ isGsEnabled && $ isGsMaster && !$ isGsMasterAdmin ) {
141
+ $ this ->userBackend ->createUserIfNotExists ($ this ->userData ->getOriginalUid ());
142
+ return ;
143
+ }
144
+ $ autoProvisioningAllowed = $ this ->userBackend ->autoprovisionAllowed ();
145
+ if ($ userExists ) {
146
+ if ($ autoProvisioningAllowed ) {
163
147
$ this ->userBackend ->updateAttributes ($ uid , $ auth );
164
- return ;
165
148
}
149
+ return ;
166
150
}
167
151
168
- throw new NoUserFoundException ('IDP parameter for the UID ( ' . $ uidMapping . ') not found. Possible parameters are: ' . json_encode (array_keys ($ auth )));
152
+ $ uid = $ this ->userData ->getOriginalUid ();
153
+ if (!$ userExists && !$ autoProvisioningAllowed ) {
154
+ throw new NoUserFoundException ('Auto provisioning not allowed and user ' . $ uid . ' does not exist ' );
155
+ } elseif (!$ userExists && $ autoProvisioningAllowed ) {
156
+ $ this ->userBackend ->createUserIfNotExists ($ uid , $ auth );
157
+ $ this ->userBackend ->updateAttributes ($ uid , $ auth );
158
+ return ;
159
+ }
169
160
}
170
161
171
162
/**
@@ -221,11 +212,9 @@ public function login($idp) {
221
212
}
222
213
$ this ->session ->set ('user_saml.samlUserData ' , $ _SERVER );
223
214
try {
224
- $ this ->autoprovisionIfPossible ($ this ->session ->get ('user_saml.samlUserData ' ));
225
- $ user = $ this ->userManager ->get ($ this ->userBackend ->getCurrentUserId ());
226
- if (!($ user instanceof IUser)) {
227
- throw new NoUserFoundException ('User ' . $ this ->userBackend ->getCurrentUserId () . ' not valid or not found ' );
228
- }
215
+ $ this ->userData ->setAttributes ($ this ->session ->get ('user_saml.samlUserData ' ));
216
+ $ this ->autoprovisionIfPossible ();
217
+ $ user = $ this ->userResolver ->findExistingUser ($ this ->userBackend ->getCurrentUserId ());
229
218
$ user ->updateLastLoginTimestamp ();
230
219
} catch (NoUserFoundException $ e ) {
231
220
if ($ e ->getMessage ()) {
@@ -342,7 +331,8 @@ public function assertionConsumerService(): Http\RedirectResponse {
342
331
// Check whether the user actually exists, if not redirect to an error page
343
332
// explaining the issue.
344
333
try {
345
- $ this ->autoprovisionIfPossible ($ auth ->getAttributes ());
334
+ $ this ->userData ->setAttributes ($ auth ->getAttributes ());
335
+ $ this ->autoprovisionIfPossible ();
346
336
} catch (NoUserFoundException $ e ) {
347
337
$ this ->logger ->error ($ e ->getMessage (), ['app ' => $ this ->appName ]);
348
338
$ response = new Http \RedirectResponse ($ this ->urlGenerator ->linkToRouteAbsolute ('user_saml.SAML.notProvisioned ' ));
@@ -358,14 +348,13 @@ public function assertionConsumerService(): Http\RedirectResponse {
358
348
$ this ->session ->set ('user_saml.samlSessionIndex ' , $ auth ->getSessionIndex ());
359
349
$ this ->session ->set ('user_saml.samlSessionExpiration ' , $ auth ->getSessionExpiration ());
360
350
try {
361
- $ user = $ this ->userManager ->get ($ this ->userBackend ->getCurrentUserId ());
362
- if (!($ user instanceof IUser)) {
363
- throw new \InvalidArgumentException ('User is not valid ' );
364
- }
351
+ $ user = $ this ->userResolver ->findExistingUser ($ this ->userBackend ->getCurrentUserId ());
365
352
$ firstLogin = $ user ->updateLastLoginTimestamp ();
366
- if ($ firstLogin ) {
353
+ if ($ firstLogin ) {
367
354
$ this ->userBackend ->initializeHomeDir ($ user ->getUID ());
368
355
}
356
+ } catch (NoUserFoundException $ e ) {
357
+ throw new \InvalidArgumentException ('User " ' . $ this ->userBackend ->getCurrentUserId () . '" is not valid ' );
369
358
} catch (\Exception $ e ) {
370
359
$ this ->logger ->logException ($ e , ['app ' => $ this ->appName ]);
371
360
$ response = new Http \RedirectResponse ($ this ->urlGenerator ->linkToRouteAbsolute ('user_saml.SAML.notProvisioned ' ));
0 commit comments