d28514e8ea5dfe6f530e5eca9cfaf86fd98b3ddd
[osm/osmclient.git] / osmclient / sol005 / user.py
1 #
2 # Copyright 2018 Telefonica Investigacion y Desarrollo S.A.U.
3 #
4 # All Rights Reserved.
5 #
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
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
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
16 # under the License.
17
18 """
19 OSM user mgmt API
20 """
21
22 from osmclient.common.exceptions import ClientException
23 from osmclient.common.exceptions import NotFound
24 import json
25 import logging
26
27
28 class User(object):
29 def __init__(self, http=None, client=None):
30 self._http = http
31 self._client = client
32 self._logger = logging.getLogger('osmclient')
33 self._apiName = '/admin'
34 self._apiVersion = '/v1'
35 self._apiResource = '/users'
36 self._apiBase = '{}{}{}'.format(self._apiName,
37 self._apiVersion, self._apiResource)
38
39 def create(self, name, user):
40 """Creates a new OSM user
41 """
42 self._logger.debug("")
43 self._client.get_token()
44 if not user["projects"] or (len(user["projects"]) == 1 and not user["projects"][0]):
45 del user["projects"]
46 elif len(user["projects"]) == 1:
47 user["projects"] = user["projects"][0].split(",")
48
49 if user["project_role_mappings"]:
50 project_role_mappings = []
51
52 for set_mapping in user["project_role_mappings"]:
53 set_mapping_clean = [m.strip() for m in set_mapping.split(",")]
54 project, roles = set_mapping_clean[0], set_mapping_clean[1:]
55
56 for role in roles:
57 mapping = {"project": project, "role": role}
58
59 if mapping not in project_role_mappings:
60 project_role_mappings.append(mapping)
61 user["project_role_mappings"] = project_role_mappings
62 else:
63 del user["project_role_mappings"]
64
65 http_code, resp = self._http.post_cmd(endpoint=self._apiBase,
66 postfields_dict=user,
67 skip_query_admin=True)
68 #print('HTTP CODE: {}'.format(http_code))
69 #print('RESP: {}'.format(resp))
70 #if http_code in (200, 201, 202, 204):
71 if resp:
72 resp = json.loads(resp)
73 if not resp or 'id' not in resp:
74 raise ClientException('unexpected response from server - {}'.format(
75 resp))
76 print(resp['id'])
77 #else:
78 # msg = ""
79 # if resp:
80 # try:
81 # msg = json.loads(resp)
82 # except ValueError:
83 # msg = resp
84 # raise ClientException("failed to create user {} - {}".format(name, msg))
85
86 def update(self, name, user):
87 """Updates an existing OSM user identified by name
88 """
89 self._logger.debug("")
90 self._client.get_token()
91 # print(user)
92 myuser = self.get(name)
93 update_user = {
94 "add_project_role_mappings": [],
95 "remove_project_role_mappings": [],
96 }
97
98 # if password is defined, update the password
99 if user["password"]:
100 update_user["password"] = user["password"]
101 if user["username"]:
102 update_user["username"] = user["username"]
103
104 if user["set-project"]:
105 # Remove project and insert project role mapping
106 for set_project in user["set-project"]:
107
108 set_project_clean = [m.strip() for m in set_project.split(",")]
109 project, roles = set_project_clean[0], set_project_clean[1:]
110
111 update_user["remove_project_role_mappings"].append({"project": project})
112
113 for role in roles:
114 mapping = {"project": project, "role": role}
115 update_user["add_project_role_mappings"].append(mapping)
116
117 if user["remove-project"]:
118 for remove_project in user["remove-project"]:
119 update_user["remove_project_role_mappings"].append({"project": remove_project})
120
121 if user["add-project-role"]:
122 for add_project_role in user["add-project-role"]:
123 add_project_role_clean = [m.strip() for m in add_project_role.split(",")]
124 project, roles = add_project_role_clean[0], add_project_role_clean[1:]
125
126 for role in roles:
127 mapping = {"project": project, "role": role}
128 update_user["add_project_role_mappings"].append(mapping)
129
130 if user["remove-project-role"]:
131 for remove_project_role in user["remove-project-role"]:
132 remove_project_role_clean = [m.strip() for m in remove_project_role.split(",")]
133 project, roles = remove_project_role_clean[0], remove_project_role_clean[1:]
134
135 for role in roles:
136 mapping = {"project": project, "role": role}
137 update_user["remove_project_role_mappings"].append(mapping)
138
139 if not update_user["remove_project_role_mappings"]:
140 del update_user["remove_project_role_mappings"]
141 if not update_user["add_project_role_mappings"]:
142 del update_user["add_project_role_mappings"]
143 if not update_user:
144 raise ClientException("At least something should be changed.")
145
146 http_code, resp = self._http.patch_cmd(endpoint='{}/{}'.format(self._apiBase, myuser['_id']),
147 postfields_dict=update_user, skip_query_admin=True)
148 # print('HTTP CODE: {}'.format(http_code))
149 # print('RESP: {}'.format(resp))
150 if http_code in (200, 201, 202):
151 if resp:
152 resp = json.loads(resp)
153 if not resp or 'id' not in resp:
154 raise ClientException('unexpected response from server - {}'.format(
155 resp))
156 print(resp['id'])
157 elif http_code == 204:
158 print('Updated')
159 #else:
160 # msg = ""
161 # if resp:
162 # try:
163 # msg = json.loads(resp)
164 # except ValueError:
165 # msg = resp
166 # raise ClientException("failed to update user {} - {}".format(name, msg))
167
168 def delete(self, name, force=False):
169 """Deletes an existing OSM user identified by name
170 """
171 self._logger.debug("")
172 self._client.get_token()
173 user = self.get(name)
174 querystring = ''
175 if force:
176 querystring = '?FORCE=True'
177 http_code, resp = self._http.delete_cmd('{}/{}{}'.format(self._apiBase,
178 user['_id'], querystring), skip_query_admin=True)
179 #print('HTTP CODE: {}'.format(http_code))
180 #print('RESP: {}'.format(resp))
181 if http_code == 202:
182 print('Deletion in progress')
183 elif http_code == 204:
184 print('Deleted')
185 elif resp and 'result' in resp:
186 print('Deleted')
187 else:
188 msg = resp or ""
189 # if resp:
190 # try:
191 # msg = json.loads(resp)
192 # except ValueError:
193 # msg = resp
194 raise ClientException("failed to delete user {} - {}".format(name, msg))
195
196 def list(self, filter=None):
197 """Returns the list of OSM users
198 """
199 self._logger.debug("")
200 self._client.get_token()
201 filter_string = ''
202 if filter:
203 filter_string = '?{}'.format(filter)
204 _, resp = self._http.get2_cmd('{}{}'.format(self._apiBase,filter_string), skip_query_admin=True)
205 #print('RESP: {}'.format(resp))
206 if resp:
207 return json.loads(resp)
208 return list()
209
210 def get(self, name):
211 """Returns an OSM user based on name or id
212 """
213 self._logger.debug("")
214 self._client.get_token()
215 # keystone with external LDAP contains large ids, not uuid format
216 # utils.validate_uuid4(name) cannot be used
217 user_list = self.list()
218 for user in user_list:
219 if name == user['_id']:
220 return user
221 for user in user_list:
222 if name == user['username']:
223 return user
224 raise NotFound("User {} not found".format(name))
225