Commit e01f0872910427ccd9b6e97da75eb1ff1f4a0330
1 parent
4d9ee90d
Exists in
master
and in
8 other branches
Automatic user registration (#6978)
Showing
15 changed files
with
546 additions
and
288 deletions
Show diff stats
CMakeLists.txt
... | ... | @@ -39,8 +39,10 @@ get_filename_component(NETCDFLIB_DIR ${NETCDFLIBRARIES} PATH) |
39 | 39 | get_filename_component(DDCLIENTLIB_DIR ${DDCLIENTLIBRARIES} PATH) |
40 | 40 | set(DDSERVICE_URL $ENV{DDSERVICE_URL}) |
41 | 41 | set(DDRESPATH $ENV{DDRESPATH}) |
42 | +set(DDBASEPATH "$ENV{DDBASEPATH}") | |
42 | 43 | set(DDBASEDATA "$ENV{DDBASEPATH}/DATA") |
43 | 44 | set(DDBASEINFO "$ENV{DDBASEPATH}/INFO") |
45 | +set(USERMANAGER "$ENV{INSTALL_DIR}/bin/USERMANAGER") | |
44 | 46 | set(PROXY_HOST $ENV{PROXY_HOST}) |
45 | 47 | set(PROXY_USERPWD $ENV{PROXY_USERPWD}) |
46 | 48 | ... | ... |
CMakeLists.txt.All
... | ... | @@ -42,8 +42,10 @@ get_filename_component(NETCDFLIB_DIR ${NETCDFLIBRARIES} PATH) |
42 | 42 | get_filename_component(DDCLIENTLIB_DIR ${DDCLIENTLIBRARIES} PATH) |
43 | 43 | set(DDSERVICE_URL $ENV{DDSERVICE_URL}) |
44 | 44 | set(DDRESPATH $ENV{DDRESPATH}) |
45 | +set(DDBASEPATH "$ENV{DDBASEPATH}") | |
45 | 46 | set(DDBASEDATA "$ENV{DDBASEPATH}/DATA") |
46 | 47 | set(DDBASEINFO "$ENV{DDBASEPATH}/INFO") |
48 | +set(USERMANAGER "$ENV{INSTALL_DIR}/bin/USERMANAGER") | |
47 | 49 | set(PROXY_HOST $ENV{PROXY_HOST}) |
48 | 50 | set(PROXY_USERPWD $ENV{PROXY_USERPWD}) |
49 | 51 | ... | ... |
CMakeLists.txt.DDServerOnly
... | ... | @@ -36,8 +36,10 @@ find_package( DDClient REQUIRED ) |
36 | 36 | get_filename_component(NETCDFLIB_DIR ${NETCDFLIBRARIES} PATH) |
37 | 37 | get_filename_component(DDCLIENTLIB_DIR ${DDCLIENTLIBRARIES} PATH) |
38 | 38 | set(DDRESPATH $ENV{DDRESPATH}) |
39 | +set(DDBASEPATH "$ENV{DDBASEPATH}") | |
39 | 40 | set(DDBASEDATA "$ENV{DDBASEPATH}/DATA") |
40 | 41 | set(DDBASEINFO "$ENV{DDBASEPATH}/INFO") |
42 | +set(USERMANAGER "$ENV{INSTALL_DIR}/bin/USERMANAGER") | |
41 | 43 | set(PROXY_HOST $ENV{PROXY_HOST}) |
42 | 44 | set(PROXY_USERPWD $ENV{PROXY_USERPWD}) |
43 | 45 | ... | ... |
CMakeLists.txt.ServicesOnly
... | ... | @@ -39,8 +39,10 @@ get_filename_component(NETCDFLIB_DIR ${NETCDFLIBRARIES} PATH) |
39 | 39 | get_filename_component(DDCLIENTLIB_DIR ${DDCLIENTLIBRARIES} PATH) |
40 | 40 | set(DDSERVICE_URL $ENV{DDSERVICE_URL}) |
41 | 41 | set(DDRESPATH $ENV{DDRESPATH}) |
42 | +set(DDBASEPATH "$ENV{DDBASEPATH}") | |
42 | 43 | set(DDBASEDATA "$ENV{DDBASEPATH}/DATA") |
43 | 44 | set(DDBASEINFO "$ENV{DDBASEPATH}/INFO") |
45 | +set(USERMANAGER "$ENV{INSTALL_DIR}/bin/USERMANAGER") | |
44 | 46 | set(PROXY_HOST $ENV{PROXY_HOST}) |
45 | 47 | set(PROXY_USERPWD $ENV{PROXY_USERPWD}) |
46 | 48 | ... | ... |
CMakeLists.txt.TOOLS
... | ... | @@ -42,8 +42,10 @@ get_filename_component(NETCDFLIB_DIR ${NETCDFLIBRARIES} PATH) |
42 | 42 | get_filename_component(DDCLIENTLIB_DIR ${DDCLIENTLIBRARIES} PATH) |
43 | 43 | set(DDSERVICE_URL $ENV{DDSERVICE_URL}) |
44 | 44 | set(DDRESPATH $ENV{DDRESPATH}) |
45 | +set(DDBASEPATH "$ENV{DDBASEPATH}") | |
45 | 46 | set(DDBASEDATA "$ENV{DDBASEPATH}/DATA") |
46 | 47 | set(DDBASEINFO "$ENV{DDBASEPATH}/INFO") |
48 | +set(USERMANAGER "$ENV{INSTALL_DIR}/bin/USERMANAGER") | |
47 | 49 | set(PROXY_HOST $ENV{PROXY_HOST}) |
48 | 50 | set(PROXY_USERPWD $ENV{PROXY_USERPWD}) |
49 | 51 | ... | ... |
scripts/DDServer.env.in
1 | 1 | #!/bin/bash |
2 | 2 | |
3 | +DDBASEROOT=@DDBASEPATH@ | |
3 | 4 | DDBASE=@DDBASEDATA@ |
4 | 5 | DDINFO=@DDBASEINFO@ |
5 | 6 | DDPATH=@DDRESPATH@ |
... | ... | @@ -13,8 +14,8 @@ USERMANAGER=@CMAKE_INSTALL_PREFIX@/bin/USERMANAGER |
13 | 14 | PROXY_HOST="@PROXY_HOST@" |
14 | 15 | PROXY_USERPWD="@PROXY_USERPWD@" |
15 | 16 | |
16 | -export DDBASE DDPATH DDBASEBIN DDLIB LD_LIBRARY_PATH DDINFO | |
17 | +export DDBASEROOT DDBASE DDPATH DDBASEBIN DDLIB LD_LIBRARY_PATH DDINFO | |
17 | 18 | export DATAMANAGER REMOTEDATA CALLEXT USERMANAGER |
18 | 19 | export PROXY_HOST PROXY_USERPWD |
19 | 20 | export AMDA_USERS_INFO=AMDA_Users_Info.xml |
20 | -export AMDA_GROUPS_INFO=AMDA_Users.xml | |
21 | 21 | \ No newline at end of file |
22 | +export AMDA_GROUPS_INFO=AMDA_Users.xml | ... | ... |
... | ... | @@ -0,0 +1,37 @@ |
1 | +#!/bin/sh | |
2 | + | |
3 | +usage=" | |
4 | + \n ### Generate new public / private keys for DDService### | |
5 | + \n | |
6 | + \n Usage : $0 -d <Client description> | |
7 | + \n | |
8 | + \n $0 -d \"AMDA Dev instance\" | |
9 | + \n | |
10 | + \n | |
11 | + \n ###" | |
12 | + | |
13 | +while getopts "d:h" options; do | |
14 | + case $options in | |
15 | + d ) CLIENT_DESCRIPTION=`echo $OPTARG`;; | |
16 | + h ) echo -e $usage | |
17 | + exit 1;; | |
18 | + \? ) echo -e $usage | |
19 | + exit 1;; | |
20 | + * ) echo -e $usage | |
21 | + exit 1;; | |
22 | + esac | |
23 | +done | |
24 | + | |
25 | +if [ "$CLIENT_DESCRIPTION" = "" ] | |
26 | +then | |
27 | + echo "[ERROR] Missing client description" | |
28 | + echo -e $usage | |
29 | + exit 1 | |
30 | +fi | |
31 | + | |
32 | +BASEDIR=$(dirname "$0") | |
33 | + | |
34 | +. ${BASEDIR}/DDServer.env | |
35 | + | |
36 | +php ${USERMANAGER}/GenerateNewPubPrivKeys.php --description "$CLIENT_DESCRIPTION" | |
37 | + | ... | ... |
... | ... | @@ -0,0 +1,58 @@ |
1 | +<?php | |
2 | + | |
3 | +$shortopts = "d:"; | |
4 | +$longopts = array("description:"); | |
5 | +$options = getopt($shortopts, $longopts); | |
6 | +$client_description = ""; | |
7 | +if (array_key_exists("description",$options)) { | |
8 | + $client_description = $options["description"]; | |
9 | +} | |
10 | +else if (array_key_exists("d",$options)) { | |
11 | + $client_description = $options["d"]; | |
12 | +} | |
13 | + | |
14 | +if (empty($client_description)) { | |
15 | + echo "[ERROR] Missing client description".PHP_EOL; | |
16 | + exit(1); | |
17 | +} | |
18 | + | |
19 | +$keys_file = getenv("DDBASEROOT")."/ddservice_clients_keys.json"; | |
20 | + | |
21 | +$existing_keys = array(); | |
22 | +if (file_exists($keys_file)) { | |
23 | + $keys_content = file_get_contents($keys_file); | |
24 | + if (empty($keys_content)) { | |
25 | + echo "[ERROR] Cannot load DDService clients keys file: $keys_file".PHP_EOL; | |
26 | + exit(1); | |
27 | + } | |
28 | + $existing_keys = json_decode($keys_content, TRUE); | |
29 | + if ($existing_keys == NULL) { | |
30 | + echo "[ERROR] DDService clients keys file seems to be corrupted: $keys_file".PHP_EOL; | |
31 | + exit(1); | |
32 | + } | |
33 | +} | |
34 | + | |
35 | +$public_key=md5(microtime()); | |
36 | + | |
37 | +sleep(1); | |
38 | + | |
39 | +$private_key=md5(microtime()); | |
40 | + | |
41 | +$existing_keys[] = array( | |
42 | + "public" => $public_key, | |
43 | + "private" => $private_key, | |
44 | + "description" => $client_description, | |
45 | +); | |
46 | + | |
47 | +if (!file_put_contents($keys_file, json_encode($existing_keys))) { | |
48 | + echo "[ERROR] Cannot write clients keys file: $keys_file".PHP_EOL; | |
49 | + exit(1); | |
50 | +} | |
51 | + | |
52 | +echo "DESCRIPTION: $client_description".PHP_EOL; | |
53 | +echo "PUBLIC_KEY: $public_key".PHP_EOL; | |
54 | +echo "PRIVATE_KEY: $private_key".PHP_EOL; | |
55 | + | |
56 | +exit(0); | |
57 | + | |
58 | +?> | ... | ... |
... | ... | @@ -0,0 +1,30 @@ |
1 | +<?php | |
2 | + | |
3 | +$keys_file = getenv("DDBASEROOT")."/ddservice_clients_keys.json"; | |
4 | + | |
5 | +if (!file_exists($keys_file)) { | |
6 | + echo "[ERROR] DDService clients keys file not exists: $keys_file".PHP_EOL; | |
7 | + exit(1); | |
8 | +} | |
9 | + | |
10 | +$keys_content = file_get_contents($keys_file); | |
11 | +if (empty($keys_content)) { | |
12 | + echo "[ERROR] Cannot load DDService clients keys file: $keys_file".PHP_EOL; | |
13 | + exit(1); | |
14 | +} | |
15 | +$existing_keys = json_decode($keys_content, TRUE); | |
16 | +if ($existing_keys == NULL) { | |
17 | + echo "[ERROR] DDService clients keys file seems to be corrupted: $keys_file".PHP_EOL; | |
18 | + exit(1); | |
19 | +} | |
20 | + | |
21 | +foreach ($existing_keys as $key_info) { | |
22 | + echo "DESCRIPTION: ".$key_info['description'].PHP_EOL; | |
23 | + echo "PUBLIC_KEY: ".$key_info['public'].PHP_EOL; | |
24 | + echo "PRIVATE_KEY: ".$key_info['private'].PHP_EOL; | |
25 | + echo "".PHP_EOL; | |
26 | +} | |
27 | + | |
28 | +exit(0); | |
29 | + | |
30 | +?> | ... | ... |
src/DDADMIN/MANAGER/UserManager.php
1 | 1 | <?php |
2 | + require_once(dirname(__FILE__) . '/UserManagerClass.php'); | |
2 | 3 | |
3 | -class UserManagerClass | |
4 | -{ | |
5 | - protected $infoXml; | |
6 | - protected $stderr; | |
7 | - protected $rootElement; | |
8 | - | |
9 | - function __construct($stderr) | |
10 | - { | |
11 | - $this->stderr = $stderr; | |
12 | - | |
13 | - $this->infoXml = new DomDocument("1.0","UTF-8"); | |
14 | - $this->infoXml->preserveWhiteSpace = false; | |
15 | - $this->infoXml->formatOutput = true; | |
16 | - | |
17 | - } | |
18 | - | |
19 | - function GetInfoXmlFilePath() | |
20 | - { | |
21 | - return getenv("DDINFO")."/".getenv("AMDA_USERS_INFO"); | |
22 | - } | |
23 | - | |
24 | - function GetGroupsXmlFilePath() | |
25 | - { | |
26 | - return getenv("DDINFO")."/".getenv("AMDA_GROUPS_INFO"); | |
27 | - } | |
28 | - | |
29 | - function LoadInfoXmlFile() | |
30 | - { | |
31 | - if (file_exists($this->GetInfoXmlFilePath())) | |
32 | - { | |
33 | - $this->infoXml->load($this->GetInfoXmlFilePath()); | |
34 | - $this->rootElement = $this->infoXml->documentElement; | |
35 | - } | |
36 | - else | |
37 | - { | |
38 | - $this->rootElement = $this->infoXml->createElement("users"); | |
39 | - $this->infoXml->appendChild($this->rootElement); | |
40 | - } | |
41 | - | |
42 | - return 1; | |
43 | - } | |
44 | - | |
45 | - function AddUser($login, $pwd_hash, $first_name, $last_name, $email, $news, $groups) | |
46 | - { | |
47 | - if (!$this->LoadInfoXmlFile()) | |
48 | - return 0; | |
49 | - | |
50 | - $users = $this->infoXml->getElementsByTagName("user"); | |
51 | - | |
52 | - //test if login is already used | |
53 | - for ($i = 0; $i < $users->length; $i++) | |
54 | - { | |
55 | - $crtLogin = $users->item($i)->getAttribute("login"); | |
56 | - if ($crtLogin == $login) | |
57 | - { | |
58 | - fprintf($this->stderr,"Login already exist on users info file\n"); | |
59 | - return 0; | |
60 | - } | |
61 | - } | |
62 | - | |
63 | - date_default_timezone_set('UTC'); | |
64 | - $user = $this->infoXml->createElement("user"); | |
65 | - $user->setAttribute("login",$login); | |
66 | - $user->setAttribute("name",$last_name); | |
67 | - $user->setAttribute("first_name",$first_name); | |
68 | - $user->setAttribute("group",$groups); | |
69 | - $user->setAttribute("email",$email); | |
70 | - $user->setAttribute("date",date('j/m/y')); | |
71 | - $user->setAttribute("news",$news); | |
72 | - | |
73 | - $this->rootElement->appendChild($user); | |
74 | - | |
75 | - | |
76 | - exec('DDadmin -a '.$login.' '.$pwd_hash,$output,$return); | |
77 | - | |
78 | - if ($return != 0) | |
79 | - { | |
80 | - fprintf($this->stderr,"DDadmin error : ".$output[0]."\n"); | |
81 | - return 0; | |
82 | - } | |
83 | - else | |
84 | - $this->infoXml->save($this->GetInfoXmlFilePath()); | |
85 | - | |
86 | - return 1; | |
87 | - } | |
88 | - | |
89 | - function ModifyUserPwd($login, $pwd_hash, $pwd_hash_new) | |
90 | - { | |
91 | - exec('DDadmin -m '.$login.' '.$pwd_hash.' '.$pwd_hash_new,$output,$return); | |
92 | - | |
93 | - if ($return != 0) | |
94 | - { | |
95 | - fprintf($this->stderr,"DDadmin error : ".$output[0]."\n"); | |
96 | - return 0; | |
97 | - } | |
98 | - | |
99 | - return 1; | |
100 | - } | |
101 | - | |
102 | - function ModifyUserGroup($login,$groups) | |
103 | - { | |
104 | - if (!$this->LoadInfoXmlFile()) | |
105 | - return 0; | |
106 | - | |
107 | - $users = $this->infoXml->getElementsByTagName("user"); | |
108 | - | |
109 | - for ($i = 0; $i < $users->length; $i++) | |
110 | - { | |
111 | - $crtLogin = $users->item($i)->getAttribute("login"); | |
112 | - if ($crtLogin == $login) | |
113 | - { | |
114 | - $users->item($i)->setAttribute("group",$groups); | |
115 | - $this->infoXml->save($this->GetInfoXmlFilePath()); | |
116 | - return 1; | |
117 | - } | |
118 | - } | |
119 | - | |
120 | - fprintf($this->stderr,"Cannot found user\n"); | |
121 | - return 0; | |
122 | - } | |
123 | - | |
124 | - function ResetUserPwd($login) | |
125 | - { | |
126 | - exec('DDadmin -r '.$login,$output,$return); | |
127 | - | |
128 | - if ($return != 0) | |
129 | - { | |
130 | - fprintf($this->stderr,"DDadmin error : ".$output."\n"); | |
131 | - return 0; | |
132 | - } | |
133 | - else | |
134 | - fprintf($this->stderr,"New password is : ".$output[0]."\n"); | |
135 | - | |
136 | - return 1; | |
137 | - } | |
138 | - | |
139 | - function DeleteUser($login) | |
140 | - { | |
141 | - if (!$this->LoadInfoXmlFile()) | |
142 | - return 0; | |
143 | - | |
144 | - $users = $this->infoXml->getElementsByTagName("user"); | |
145 | - | |
146 | - for ($i = 0; $i < $users->length; $i++) | |
147 | - { | |
148 | - $crtLogin = $users->item($i)->getAttribute("login"); | |
149 | - if ($crtLogin == $login) | |
150 | - { | |
151 | - $this->rootElement->removeChild($users->item($i)); | |
152 | - break; | |
153 | - } | |
154 | - } | |
155 | - | |
156 | - exec('DDadmin -d '.$login,$output,$return); | |
157 | - | |
158 | - if ($return != 0) | |
159 | - { | |
160 | - fprintf($this->stderr,"DDadmin error : ".$output[0]."\n"); | |
161 | - return 0; | |
162 | - } | |
163 | - | |
164 | - $this->infoXml->save($this->GetInfoXmlFilePath()); | |
165 | - | |
166 | - return 1; | |
167 | - } | |
168 | - | |
169 | - //This function will be deprecated for AMDA-NG | |
170 | - function GenerateGroupsXmlFile() | |
171 | - { | |
172 | - if (!$this->LoadInfoXmlFile()) | |
173 | - return 0; | |
174 | - | |
175 | - $users = $this->infoXml->getElementsByTagName("user"); | |
176 | - | |
177 | - $groupsXml = new DomDocument("1.0","UTF-8"); | |
178 | - $groupsXml->preserveWhiteSpace = false; | |
179 | - $groupsXml->formatOutput = true; | |
180 | - $rootGroupsElement = $groupsXml->createElement("AMDA_USERS"); | |
181 | - $groupsXml->appendChild($rootGroupsElement); | |
182 | - | |
183 | - for ($i = 0; $i < $users->length; $i++) | |
184 | - { | |
185 | - if (strcmp($users->item($i)->getAttribute("group"),"") == 0) | |
186 | - continue; | |
187 | - $u = $groupsXml->createElement("user",$users->item($i)->getAttribute("login")); | |
188 | - $u->setAttribute("group",$users->item($i)->getAttribute("group")); | |
189 | - $rootGroupsElement->appendChild($u); | |
190 | - } | |
191 | - | |
192 | - $groupsXml->save($this->GetGroupsXmlFilePath()); | |
193 | - | |
194 | - return 1; | |
195 | - } | |
196 | - | |
197 | - function SendRegistrationMail($login,$pwd,$first_name, $last_name, $email) | |
198 | - { | |
199 | - $subject = 'AMDA registration'; | |
200 | - | |
201 | - $msg = "Dear $first_name $last_name, \r\n\r\n"; | |
202 | - $msg .= "Thanks for your interest in AMDA\r\n\r\n"; | |
203 | - $msg .= "Your login: $login \r\n"; | |
204 | - $msg .= " password: $pwd \r\n\r\n"; | |
205 | - $msg .= "at http://amda.cdpp.eu \r\n\r\n"; | |
206 | - $msg .= "Please contact us in case of any problems or questions.\r\n\r\n"; | |
207 | - $msg .= "Best regards,\r\n\r\n"; | |
208 | - $msg .= "CDPP-AMDA Team"; | |
209 | - | |
210 | - $headers = "From: amda@irap.omp.eu " . "\r\n". | |
211 | - "Reply-To: amda@irap.omp.eu " . "\r\n". | |
212 | - "Cc: amda@irap.omp.eu" . "\r\n". | |
213 | - "Content-type: text/plain; charset=utf-8\r\n"; | |
214 | - mail($email, $subject, $msg, $headers); | |
215 | - | |
216 | - } | |
217 | - | |
218 | - function Check() | |
219 | - { | |
220 | - if (!$this->LoadInfoXmlFile()) | |
221 | - return 0; | |
222 | - | |
223 | - $users = $this->infoXml->getElementsByTagName("user"); | |
224 | - | |
225 | - exec('DDadmin -l',$output,$return); | |
226 | - | |
227 | - if ($return != 0) | |
228 | - { | |
229 | - fprintf($this->stderr,"DDadmin error : ".$output[0]."\n"); | |
230 | - return 0; | |
231 | - } | |
232 | - | |
233 | - $ddAdminUsers = explode(',',$output[0]); | |
234 | - | |
235 | - for ($i = 0; $i < $users->length; $i++) | |
236 | - { | |
237 | - $found = false; | |
238 | - for ($j = 0; $j < count($ddAdminUsers); $j++) | |
239 | - if (strcmp($users->item($i)->getAttribute("login"),$ddAdminUsers[$j]) == 0) | |
240 | - { | |
241 | - $found = true; | |
242 | - break; | |
243 | - } | |
244 | - if (!$found) | |
245 | - fprintf($this->stderr,"User ".$users->item($i)->getAttribute("login")." not found on nc file\n"); | |
246 | - } | |
247 | - | |
248 | - for ($i = 0; $i < count($ddAdminUsers); $i++) | |
249 | - { | |
250 | - $found = false; | |
251 | - for ($j = 0; $j < $users->length; $j++) | |
252 | - if (strcmp($users->item($j)->getAttribute("login"),$ddAdminUsers[$i]) == 0) | |
253 | - { | |
254 | - $found = true; | |
255 | - break; | |
256 | - } | |
257 | - if (!$found) | |
258 | - fprintf($this->stderr,"User ".$ddAdminUsers[$i]." not found on info file\n"); | |
259 | - } | |
260 | - | |
261 | - return 1; | |
262 | - } | |
263 | -} | |
264 | - | |
265 | -//----------------------------------------------------------------------------------------------------- | |
266 | - //crypt the password with the salt corresponding to the login | |
267 | - function cryptPwd($login,$pwd) | |
268 | - { | |
269 | - exec('DDadmin -s '.$login,$output,$return); | |
270 | - | |
271 | - if ($return != 0) | |
272 | - { | |
273 | - fprintf($this->stderr,"DDadmin error : ".$output."\n"); | |
274 | - return ''; | |
275 | - } | |
276 | - | |
277 | - $salt = $output[0]; | |
278 | - | |
279 | - return crypt($pwd,$salt); | |
280 | - } | |
281 | - | |
282 | -//---------------------------------------------------------------------------------------------------- | |
283 | 4 | putenv("LD_LIBRARY_PATH=".getenv("LD_LIBRARY_PATH")); |
284 | 5 | putenv("PATH=./:".getenv("DDBASEBIN").":/bin:/usr/bin"); |
285 | 6 | |
... | ... | @@ -378,7 +99,7 @@ class UserManagerClass |
378 | 99 | } |
379 | 100 | |
380 | 101 | if (isset($args->pwd_hashed) && !($args->pwd_hashed)) |
381 | - $pwd_hash = cryptPwd($args->login,$args->pwd); | |
102 | + $pwd_hash = $userManager->cryptPwd($args->login,$args->pwd); | |
382 | 103 | else |
383 | 104 | $pwd_hash = $args->pwd; |
384 | 105 | ... | ... |
... | ... | @@ -0,0 +1,281 @@ |
1 | +<?php | |
2 | + | |
3 | +class UserManagerClass | |
4 | +{ | |
5 | + protected $infoXml; | |
6 | + protected $stderr; | |
7 | + protected $rootElement; | |
8 | + | |
9 | + function __construct($stderr) | |
10 | + { | |
11 | + $this->stderr = $stderr; | |
12 | + | |
13 | + $this->infoXml = new DomDocument("1.0","UTF-8"); | |
14 | + $this->infoXml->preserveWhiteSpace = false; | |
15 | + $this->infoXml->formatOutput = true; | |
16 | + | |
17 | + } | |
18 | + | |
19 | + function GetInfoXmlFilePath() | |
20 | + { | |
21 | + return getenv("DDINFO")."/".getenv("AMDA_USERS_INFO"); | |
22 | + } | |
23 | + | |
24 | + function GetGroupsXmlFilePath() | |
25 | + { | |
26 | + return getenv("DDINFO")."/".getenv("AMDA_GROUPS_INFO"); | |
27 | + } | |
28 | + | |
29 | + function LoadInfoXmlFile() | |
30 | + { | |
31 | + if (file_exists($this->GetInfoXmlFilePath())) | |
32 | + { | |
33 | + $this->infoXml->load($this->GetInfoXmlFilePath()); | |
34 | + $this->rootElement = $this->infoXml->documentElement; | |
35 | + } | |
36 | + else | |
37 | + { | |
38 | + $this->rootElement = $this->infoXml->createElement("users"); | |
39 | + $this->infoXml->appendChild($this->rootElement); | |
40 | + } | |
41 | + | |
42 | + return 1; | |
43 | + } | |
44 | + | |
45 | + function AddUser($login, $pwd_hash, $first_name, $last_name, $email, $news, $groups) | |
46 | + { | |
47 | + if (!$this->LoadInfoXmlFile()) | |
48 | + return 0; | |
49 | + | |
50 | + $users = $this->infoXml->getElementsByTagName("user"); | |
51 | + | |
52 | + //test if login is already used | |
53 | + for ($i = 0; $i < $users->length; $i++) | |
54 | + { | |
55 | + $crtLogin = $users->item($i)->getAttribute("login"); | |
56 | + if ($crtLogin == $login) | |
57 | + { | |
58 | + fprintf($this->stderr,"Login already exist on users info file\n"); | |
59 | + return 0; | |
60 | + } | |
61 | + } | |
62 | + | |
63 | + date_default_timezone_set('UTC'); | |
64 | + $user = $this->infoXml->createElement("user"); | |
65 | + $user->setAttribute("login",$login); | |
66 | + $user->setAttribute("name",$last_name); | |
67 | + $user->setAttribute("first_name",$first_name); | |
68 | + $user->setAttribute("group",$groups); | |
69 | + $user->setAttribute("email",$email); | |
70 | + $user->setAttribute("date",date('j/m/y')); | |
71 | + $user->setAttribute("news",$news); | |
72 | + | |
73 | + $this->rootElement->appendChild($user); | |
74 | + | |
75 | + | |
76 | + exec('DDadmin -a '.$login.' '.$pwd_hash,$output,$return); | |
77 | + | |
78 | + if ($return != 0) | |
79 | + { | |
80 | + fprintf($this->stderr,"DDadmin error : ".$output[0]."\n"); | |
81 | + return 0; | |
82 | + } | |
83 | + else | |
84 | + $this->infoXml->save($this->GetInfoXmlFilePath()); | |
85 | + | |
86 | + return 1; | |
87 | + } | |
88 | + | |
89 | + function ModifyUserPwd($login, $pwd_hash, $pwd_hash_new) | |
90 | + { | |
91 | + exec('DDadmin -m '.$login.' '.$pwd_hash.' '.$pwd_hash_new,$output,$return); | |
92 | + | |
93 | + if ($return != 0) | |
94 | + { | |
95 | + fprintf($this->stderr,"DDadmin error : ".$output[0]."\n"); | |
96 | + return 0; | |
97 | + } | |
98 | + | |
99 | + return 1; | |
100 | + } | |
101 | + | |
102 | + function ModifyUserGroup($login,$groups) | |
103 | + { | |
104 | + if (!$this->LoadInfoXmlFile()) | |
105 | + return 0; | |
106 | + | |
107 | + $users = $this->infoXml->getElementsByTagName("user"); | |
108 | + | |
109 | + for ($i = 0; $i < $users->length; $i++) | |
110 | + { | |
111 | + $crtLogin = $users->item($i)->getAttribute("login"); | |
112 | + if ($crtLogin == $login) | |
113 | + { | |
114 | + $users->item($i)->setAttribute("group",$groups); | |
115 | + $this->infoXml->save($this->GetInfoXmlFilePath()); | |
116 | + return 1; | |
117 | + } | |
118 | + } | |
119 | + | |
120 | + fprintf($this->stderr,"Cannot found user\n"); | |
121 | + return 0; | |
122 | + } | |
123 | + | |
124 | + function ResetUserPwd($login) | |
125 | + { | |
126 | + exec('DDadmin -r '.$login,$output,$return); | |
127 | + | |
128 | + if ($return != 0) | |
129 | + { | |
130 | + fprintf($this->stderr,"DDadmin error : ".$output."\n"); | |
131 | + return 0; | |
132 | + } | |
133 | + else | |
134 | + fprintf($this->stderr,"New password is : ".$output[0]."\n"); | |
135 | + | |
136 | + return 1; | |
137 | + } | |
138 | + | |
139 | + function DeleteUser($login) | |
140 | + { | |
141 | + if (!$this->LoadInfoXmlFile()) | |
142 | + return 0; | |
143 | + | |
144 | + $users = $this->infoXml->getElementsByTagName("user"); | |
145 | + | |
146 | + for ($i = 0; $i < $users->length; $i++) | |
147 | + { | |
148 | + $crtLogin = $users->item($i)->getAttribute("login"); | |
149 | + if ($crtLogin == $login) | |
150 | + { | |
151 | + $this->rootElement->removeChild($users->item($i)); | |
152 | + break; | |
153 | + } | |
154 | + } | |
155 | + | |
156 | + exec('DDadmin -d '.$login,$output,$return); | |
157 | + | |
158 | + if ($return != 0) | |
159 | + { | |
160 | + fprintf($this->stderr,"DDadmin error : ".$output[0]."\n"); | |
161 | + return 0; | |
162 | + } | |
163 | + | |
164 | + $this->infoXml->save($this->GetInfoXmlFilePath()); | |
165 | + | |
166 | + return 1; | |
167 | + } | |
168 | + | |
169 | + //This function will be deprecated for AMDA-NG | |
170 | + function GenerateGroupsXmlFile() | |
171 | + { | |
172 | + if (!$this->LoadInfoXmlFile()) | |
173 | + return 0; | |
174 | + | |
175 | + $users = $this->infoXml->getElementsByTagName("user"); | |
176 | + | |
177 | + $groupsXml = new DomDocument("1.0","UTF-8"); | |
178 | + $groupsXml->preserveWhiteSpace = false; | |
179 | + $groupsXml->formatOutput = true; | |
180 | + $rootGroupsElement = $groupsXml->createElement("AMDA_USERS"); | |
181 | + $groupsXml->appendChild($rootGroupsElement); | |
182 | + | |
183 | + for ($i = 0; $i < $users->length; $i++) | |
184 | + { | |
185 | + if (strcmp($users->item($i)->getAttribute("group"),"") == 0) | |
186 | + continue; | |
187 | + $u = $groupsXml->createElement("user",$users->item($i)->getAttribute("login")); | |
188 | + $u->setAttribute("group",$users->item($i)->getAttribute("group")); | |
189 | + $rootGroupsElement->appendChild($u); | |
190 | + } | |
191 | + | |
192 | + $groupsXml->save($this->GetGroupsXmlFilePath()); | |
193 | + | |
194 | + return 1; | |
195 | + } | |
196 | + | |
197 | + function SendRegistrationMail($login,$pwd,$first_name, $last_name, $email) | |
198 | + { | |
199 | + $subject = 'AMDA registration'; | |
200 | + | |
201 | + $msg = "Dear $first_name $last_name, \r\n\r\n"; | |
202 | + $msg .= "Thanks for your interest in AMDA\r\n\r\n"; | |
203 | + $msg .= "Your login: $login \r\n"; | |
204 | + $msg .= " password: $pwd \r\n\r\n"; | |
205 | + $msg .= "at http://amda.cdpp.eu \r\n\r\n"; | |
206 | + $msg .= "Please contact us in case of any problems or questions.\r\n\r\n"; | |
207 | + $msg .= "Best regards,\r\n\r\n"; | |
208 | + $msg .= "CDPP-AMDA Team"; | |
209 | + | |
210 | + $headers = "From: amda@irap.omp.eu " . "\r\n". | |
211 | + "Reply-To: amda@irap.omp.eu " . "\r\n". | |
212 | + "Cc: amda@irap.omp.eu" . "\r\n". | |
213 | + "Content-type: text/plain; charset=utf-8\r\n"; | |
214 | + mail($email, $subject, $msg, $headers); | |
215 | + | |
216 | + } | |
217 | + | |
218 | + function Check() | |
219 | + { | |
220 | + if (!$this->LoadInfoXmlFile()) | |
221 | + return 0; | |
222 | + | |
223 | + $users = $this->infoXml->getElementsByTagName("user"); | |
224 | + | |
225 | + exec('DDadmin -l',$output,$return); | |
226 | + | |
227 | + if ($return != 0) | |
228 | + { | |
229 | + fprintf($this->stderr,"DDadmin error : ".$output[0]."\n"); | |
230 | + return 0; | |
231 | + } | |
232 | + | |
233 | + $ddAdminUsers = explode(',',$output[0]); | |
234 | + | |
235 | + for ($i = 0; $i < $users->length; $i++) | |
236 | + { | |
237 | + $found = false; | |
238 | + for ($j = 0; $j < count($ddAdminUsers); $j++) | |
239 | + if (strcmp($users->item($i)->getAttribute("login"),$ddAdminUsers[$j]) == 0) | |
240 | + { | |
241 | + $found = true; | |
242 | + break; | |
243 | + } | |
244 | + if (!$found) | |
245 | + fprintf($this->stderr,"User ".$users->item($i)->getAttribute("login")." not found on nc file\n"); | |
246 | + } | |
247 | + | |
248 | + for ($i = 0; $i < count($ddAdminUsers); $i++) | |
249 | + { | |
250 | + $found = false; | |
251 | + for ($j = 0; $j < $users->length; $j++) | |
252 | + if (strcmp($users->item($j)->getAttribute("login"),$ddAdminUsers[$i]) == 0) | |
253 | + { | |
254 | + $found = true; | |
255 | + break; | |
256 | + } | |
257 | + if (!$found) | |
258 | + fprintf($this->stderr,"User ".$ddAdminUsers[$i]." not found on info file\n"); | |
259 | + } | |
260 | + | |
261 | + return 1; | |
262 | + } | |
263 | + | |
264 | + //crypt the password with the salt corresponding to the login | |
265 | + function cryptPwd($login,$pwd) | |
266 | + { | |
267 | + exec('DDadmin -s '.$login,$output,$return); | |
268 | + | |
269 | + if ($return != 0) | |
270 | + { | |
271 | + fprintf($this->stderr,"DDadmin error : ".$output."\n"); | |
272 | + return ''; | |
273 | + } | |
274 | + | |
275 | + $salt = $output[0]; | |
276 | + | |
277 | + return crypt($pwd,$salt); | |
278 | + } | |
279 | +} | |
280 | + | |
281 | +?> | ... | ... |
src/DDSERVICES/SOAP/DDserverWeb.php
... | ... | @@ -14,6 +14,10 @@ |
14 | 14 | private $alias = array(baseDir => webAlias); |
15 | 15 | private $extAlias = array(extBaseDir => extWebAlias); |
16 | 16 | |
17 | + function base64url_decode($data) { | |
18 | + return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT)); | |
19 | + } | |
20 | + | |
17 | 21 | /** |
18 | 22 | * Checks if Remote Data Set has been already added |
19 | 23 | */ |
... | ... | @@ -158,13 +162,70 @@ |
158 | 162 | else return NOUSERGROUPSSPECIFIED; |
159 | 163 | } |
160 | 164 | |
165 | + function checkProtectedAPI($data, $key, $check) | |
166 | + { | |
167 | + $data_decoded = $this->base64url_decode($data); | |
168 | + if (empty($data_decoded)) { | |
169 | + return array( | |
170 | + "valid" => FALSE, | |
171 | + ); | |
172 | + } | |
173 | + | |
174 | + $data_array = json_decode($data_decoded, TRUE); | |
175 | + if (empty($data_array) || empty($data_array["timestamp"])) { | |
176 | + return array( | |
177 | + "valid" => FALSE, | |
178 | + ); | |
179 | + } | |
180 | + | |
181 | + if (time() - intval($data_array["timestamp"]) > 30) { | |
182 | + return $data_array + array("valid" => FALSE); | |
183 | + } | |
184 | + | |
185 | + $keys_file = rootDir."/ddservice_clients_keys.json"; | |
186 | + if (!file_exists($keys_file)) { | |
187 | + return $data_array + array("valid" => FALSE); | |
188 | + } | |
189 | + | |
190 | + $keys_content = file_get_contents($keys_file); | |
191 | + if (empty($keys_content)) { | |
192 | + return $data_array + array("valid" => FALSE); | |
193 | + } | |
194 | + | |
195 | + $existing_keys = json_decode($keys_content, TRUE); | |
196 | + if (empty($existing_keys)) { | |
197 | + return $data_array + array("valid" => FALSE); | |
198 | + } | |
199 | + | |
200 | + $private = ""; | |
201 | + foreach ($existing_keys as $keys) { | |
202 | + if ($keys["public"] == $key) { | |
203 | + $private = $keys["private"]; | |
204 | + break; | |
205 | + } | |
206 | + } | |
207 | + | |
208 | + if (empty($private)) { | |
209 | + return $data_array + array("valid" => FALSE); | |
210 | + } | |
211 | + | |
212 | + $computed_check = md5($data.$key.$private); | |
213 | + if ($computed_check != $check) { | |
214 | + return $data_array + array("valid" => FALSE); | |
215 | + } | |
216 | + | |
217 | + return $data_array + array("valid" => TRUE); | |
218 | + } | |
219 | + | |
161 | 220 | /* |
162 | 221 | * Return info about a user |
163 | 222 | */ |
164 | 223 | |
165 | - function getUserInfo($login,$hash) | |
224 | + function getUserInfo($data, $key, $check) | |
166 | 225 | { |
167 | - if (md5(PRIVATEKEY.$login.__FUNCTION__) != $hash) | |
226 | + $data_array = $this->checkProtectedAPI($data, $key, $check); | |
227 | + if ($data_array['valid'] == FALSE) { | |
228 | + $login = array_key_exists("login", $data_array) ? $data_array["login"] : "undefined"; | |
168 | 229 | return array("success" => FALSE, |
169 | 230 | "login" => $login, |
170 | 231 | "name" => "undefined", |
... | ... | @@ -173,11 +234,13 @@ |
173 | 234 | "email" => "undefined", |
174 | 235 | "date" => "undefined", |
175 | 236 | "news" => "0"); |
237 | + } | |
176 | 238 | |
177 | 239 | $UsrDom = new DomDocument("1.0"); |
178 | 240 | $UsrDom->load(extWebAlias."AMDA_Users_Info.xml"); |
179 | 241 | $xp = new domxpath($UsrDom); |
180 | - $theUser = $xp->query("//user[@login='".$login."']"); | |
242 | + $theUser = $xp->query("//user[@login='".$data_array["login"]."']"); | |
243 | + $login = array_key_exists("login", $data_array) ? $data_array["login"] : "undefined"; | |
181 | 244 | |
182 | 245 | return array("success" => TRUE, |
183 | 246 | "login" => $login, |
... | ... | @@ -189,6 +252,29 @@ |
189 | 252 | "news" => ($theUser->length > 0) ? $theUser->item(0)->getAttribute("news") : "0"); |
190 | 253 | } |
191 | 254 | |
255 | + function createUser($data, $key, $check) | |
256 | + { | |
257 | + $data_array = $this->checkProtectedAPI($data, $key, $check); | |
258 | + if ($data_array['valid'] == FALSE) { | |
259 | + return FALSE; | |
260 | + } | |
261 | + | |
262 | + if (empty($data_array['pwd']) || empty($data_array['login']) || empty($data_array['first_name']) || empty($data_array['last_name']) || empty($data_array['email'])) { | |
263 | + return FALSE; | |
264 | + } | |
265 | + | |
266 | + require_once userMgrDir."/UserManagerClass.php"; | |
267 | + putenv("PATH=./:".DDBASEBIN.":/bin:/usr/bin"); | |
268 | + putenv("DDINFO=".extBaseDir); | |
269 | + putenv("DDBASE=".baseDir); | |
270 | + putenv("AMDA_USERS_INFO=AMDA_Users_Info.xml"); | |
271 | + putenv("AMDA_GROUPS_INFO=AMDA_Users.xml"); | |
272 | + $stderr = fopen("php://stderr","w"); | |
273 | + $userManager = new UserManagerClass($stderr); | |
274 | + $pwd_hash = crypt($data_array['pwd'],chr(rand(97,122)).chr(rand(97,122))); | |
275 | + return ($userManager->AddUser($data_array['login'], $pwd_hash, $data_array['first_name'], $data_array['last_name'], $data_array['email'], 1, '') == 1); | |
276 | + } | |
277 | + | |
192 | 278 | /* |
193 | 279 | * Return a list of group for which a user is a member |
194 | 280 | */ | ... | ... |
src/DDSERVICES/SOAP/DDserverWeb_ini.php.in
... | ... | @@ -16,8 +16,10 @@ |
16 | 16 | |
17 | 17 | /* Compound Definitions: Nothing to modify */ |
18 | 18 | |
19 | + define("rootDir", "@DDBASEPATH@"); | |
19 | 20 | define("baseDir", "@DDBASEDATA@"); |
20 | 21 | define("extBaseDir", "@DDBASEINFO@"); |
22 | + define ("userMgrDir", "@USERMANAGER@"); | |
21 | 23 | // define("extBaseXml", "Bases.xml"); |
22 | 24 | |
23 | 25 | define("webAlias", rootAlias."/DATA/"); | ... | ... |
src/DDSERVICES/SOAP/dd.wsdl.in
... | ... | @@ -142,12 +142,21 @@ |
142 | 142 | <part name='Result' type='xsd:string'/> |
143 | 143 | </message> |
144 | 144 | <message name='getUserInfoRequest'> |
145 | - <part name='login' type='xsd:string'/> | |
146 | - <part name='hash' type='xsd:string'/> | |
145 | + <part name='data' type='xsd:string'/> | |
146 | + <part name='key' type='xsd:string'/> | |
147 | + <part name='check' type='xsd:string'/> | |
147 | 148 | </message> |
148 | 149 | <message name='getUserInfoResponse'> |
149 | 150 | <part name='Result' type='tns:UserInfoData'/> |
150 | 151 | </message> |
152 | +<message name='createUserRequest'> | |
153 | + <part name='data' type='xsd:string'/> | |
154 | + <part name='key' type='xsd:string'/> | |
155 | + <part name='check' type='xsd:string'/> | |
156 | +</message> | |
157 | +<message name='createUserResponse'> | |
158 | + <part name='Result' type='xsd:boolean'/> | |
159 | +</message> | |
151 | 160 | <message name='getTimeRestrictionRequest'> |
152 | 161 | <part name='dataSet' type='xsd:string'/> |
153 | 162 | </message> |
... | ... | @@ -224,6 +233,10 @@ |
224 | 233 | <operation name='getUserInfo'> |
225 | 234 | <input message='tns:getUserInfoRequest'/> |
226 | 235 | <output message='tns:getUserInfoResponse'/> |
236 | + </operation> | |
237 | + <operation name='createUser'> | |
238 | + <input message='tns:createUserRequest'/> | |
239 | + <output message='tns:createUserResponse'/> | |
227 | 240 | </operation> |
228 | 241 | <operation name='getTimeRestriction'> |
229 | 242 | <input message='tns:getTimeRestrictionRequest'/> |
... | ... | @@ -414,6 +427,17 @@ |
414 | 427 | encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> |
415 | 428 | </output> |
416 | 429 | </operation> |
430 | + <operation name='createUser'> | |
431 | + <soap:operation soapAction='createUser'/> | |
432 | + <input> | |
433 | + <soap:body use='encoded' | |
434 | + encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> | |
435 | + </input> | |
436 | + <output> | |
437 | + <soap:body use='encoded' | |
438 | + encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/> | |
439 | + </output> | |
440 | + </operation> | |
417 | 441 | <operation name='getTimeRestriction'> |
418 | 442 | <soap:operation soapAction='getTimeRestriction'/> |
419 | 443 | <input> | ... | ... |