2 # Copyright 2018 Telefonica Investigacion y Desarrollo S.A.U.
6 # Licensed under the Apache License, Version 2.0 (the "License"); you may
7 # not use this file except in compliance with the License. You may obtain
8 # a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 # License for the specific language governing permissions and limitations
22 from osmclient
.common
.exceptions
import ClientException
23 from osmclient
.common
.exceptions
import NotFound
29 def __init__(self
, http
=None, client
=None):
32 self
._logger
= logging
.getLogger("osmclient")
33 self
._apiName
= "/admin"
34 self
._apiVersion
= "/v1"
35 self
._apiResource
= "/users"
36 self
._apiBase
= "{}{}{}".format(
37 self
._apiName
, self
._apiVersion
, self
._apiResource
40 def create(self
, name
, user
):
41 """Creates a new OSM user"""
42 self
._logger
.debug("")
43 self
._client
.get_token()
44 if not user
["projects"] or (
45 len(user
["projects"]) == 1 and not user
["projects"][0]
48 elif len(user
["projects"]) == 1:
49 user
["projects"] = user
["projects"][0].split(",")
51 if user
["project_role_mappings"]:
52 project_role_mappings
= []
54 for set_mapping
in user
["project_role_mappings"]:
55 set_mapping_clean
= [m
.strip() for m
in set_mapping
.split(",")]
56 project
, roles
= set_mapping_clean
[0], set_mapping_clean
[1:]
59 mapping
= {"project": project
, "role": role
}
61 if mapping
not in project_role_mappings
:
62 project_role_mappings
.append(mapping
)
63 user
["project_role_mappings"] = project_role_mappings
65 del user
["project_role_mappings"]
67 http_code
, resp
= self
._http
.post_cmd(
68 endpoint
=self
._apiBase
, postfields_dict
=user
, skip_query_admin
=True
70 # print('HTTP CODE: {}'.format(http_code))
71 # print('RESP: {}'.format(resp))
72 # if http_code in (200, 201, 202, 204):
74 resp
= json
.loads(resp
)
75 if not resp
or "id" not in resp
:
76 raise ClientException("unexpected response from server - {}".format(resp
))
82 # msg = json.loads(resp)
85 # raise ClientException("failed to create user {} - {}".format(name, msg))
87 def update(self
, name
, user
):
88 """Updates an existing OSM user identified by name"""
89 self
._logger
.debug("")
90 self
._client
.get_token()
92 myuser
= self
.get(name
)
94 "add_project_role_mappings": [],
95 "remove_project_role_mappings": [],
98 # if password is defined, update the password
100 update_user
["password"] = user
["password"]
102 update_user
["username"] = user
["username"]
104 if user
["set-project"]:
105 # Remove project and insert project role mapping
106 for set_project
in user
["set-project"]:
108 set_project_clean
= [m
.strip() for m
in set_project
.split(",")]
109 project
, roles
= set_project_clean
[0], set_project_clean
[1:]
111 update_user
["remove_project_role_mappings"].append({"project": project
})
114 mapping
= {"project": project
, "role": role
}
115 update_user
["add_project_role_mappings"].append(mapping
)
117 if user
["remove-project"]:
118 for remove_project
in user
["remove-project"]:
119 update_user
["remove_project_role_mappings"].append(
120 {"project": remove_project
}
123 if user
["add-project-role"]:
124 for add_project_role
in user
["add-project-role"]:
125 add_project_role_clean
= [
126 m
.strip() for m
in add_project_role
.split(",")
128 project
, roles
= add_project_role_clean
[0], add_project_role_clean
[1:]
131 mapping
= {"project": project
, "role": role
}
132 update_user
["add_project_role_mappings"].append(mapping
)
134 if user
["remove-project-role"]:
135 for remove_project_role
in user
["remove-project-role"]:
136 remove_project_role_clean
= [
137 m
.strip() for m
in remove_project_role
.split(",")
140 remove_project_role_clean
[0],
141 remove_project_role_clean
[1:],
145 mapping
= {"project": project
, "role": role
}
146 update_user
["remove_project_role_mappings"].append(mapping
)
148 if not update_user
["remove_project_role_mappings"]:
149 del update_user
["remove_project_role_mappings"]
150 if not update_user
["add_project_role_mappings"]:
151 del update_user
["add_project_role_mappings"]
153 raise ClientException("At least something should be changed.")
155 http_code
, resp
= self
._http
.patch_cmd(
156 endpoint
="{}/{}".format(self
._apiBase
, myuser
["_id"]),
157 postfields_dict
=update_user
,
158 skip_query_admin
=True,
160 # print('HTTP CODE: {}'.format(http_code))
161 # print('RESP: {}'.format(resp))
162 if http_code
in (200, 201, 202):
164 resp
= json
.loads(resp
)
165 if not resp
or "id" not in resp
:
166 raise ClientException(
167 "unexpected response from server - {}".format(resp
)
170 elif http_code
== 204:
176 # msg = json.loads(resp)
179 # raise ClientException("failed to update user {} - {}".format(name, msg))
181 def delete(self
, name
, force
=False):
182 """Deletes an existing OSM user identified by name"""
183 self
._logger
.debug("")
184 self
._client
.get_token()
185 user
= self
.get(name
)
188 querystring
= "?FORCE=True"
189 http_code
, resp
= self
._http
.delete_cmd(
190 "{}/{}{}".format(self
._apiBase
, user
["_id"], querystring
),
191 skip_query_admin
=True,
193 # print('HTTP CODE: {}'.format(http_code))
194 # print('RESP: {}'.format(resp))
196 print("Deletion in progress")
197 elif http_code
== 204:
199 elif resp
and "result" in resp
:
205 # msg = json.loads(resp)
208 raise ClientException("failed to delete user {} - {}".format(name
, msg
))
210 def list(self
, filter=None):
211 """Returns the list of OSM users"""
212 self
._logger
.debug("")
213 self
._client
.get_token()
216 filter_string
= "?{}".format(filter)
217 _
, resp
= self
._http
.get2_cmd(
218 "{}{}".format(self
._apiBase
, filter_string
), skip_query_admin
=True
220 # print('RESP: {}'.format(resp))
222 return json
.loads(resp
)
226 """Returns an OSM user based on name or id"""
227 self
._logger
.debug("")
228 self
._client
.get_token()
229 # keystone with external LDAP contains large ids, not uuid format
230 # utils.validate_uuid4(name) cannot be used
231 user_list
= self
.list()
232 for user
in user_list
:
233 if name
== user
["_id"]:
235 for user
in user_list
:
236 if name
== user
["username"]:
238 raise NotFound("User {} not found".format(name
))