3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
16 import access_management.db.amdb as amdb
17 from am_api_base import *
18 from cmframework.apis import cmclient
21 class UsersRoles(AMApiBase):
24 User add role operations
26 .. :quickref: User roles;User add role operations
28 .. http:post:: /am/v1/users/roles
30 **Start User add role**
36 POST am/v1/users/roles HTTP/1.1
37 Host: haproxyvip:61200
38 Accept: application/json
40 "user": <uuid> or <username>
41 "role_name": test_role
44 :> json string user: The user's id or name.
45 :> json string role_name: The user's new role.
54 "description": "Role add to user."
57 :> json int code: the status code
58 :> json string description: the error description, present if code is non zero
60 User remove role operations
62 .. :quickref: User roles;User remove role operations
64 .. http:delete:: /am/v1/users/roles
66 **Start User remove role**
72 DELETE am/v1/users/roles HTTP/1.1
73 Host: haproxyvip:61200
74 Accept: application/json
76 "user": <uuid> or <username>
77 "role_name": test_role
80 :> json string user: The user's id or name.
81 :> json string role_name: Remove this role from the user.
90 "description": "Role removed from user."
93 :> json int code: the status code
94 :> json string description: the error description, present if code is non zero
97 endpoints = ['users/roles']
98 parser_arguments = ['user',
102 self.logger.info("Received a user add role request!")
103 args = self.parse_args()
105 if args["role_name"] is None:
106 self.logger.error("Role name parameter is missing!")
107 return AMApiBase.embed_data({}, 1, "Role name parameter is missing!")
109 state, user_info = self.get_uuid_and_name(args["user"])
111 username, def_project = self.get_user_from_uuid(user_info["id"])
112 state, message = self._add_role(args['role_name'], def_project, user_info)
115 self.logger.info("The {0} role is added to the {1} user!".format(args["role_name"], user_info["name"]))
116 return AMApiBase.embed_data({}, 0, "Role add to user.")
118 self.logger.error("The {0} role addition to the {1} user failed: {2}".format(args["role_name"], user_info["name"], message))
119 return AMApiBase.construct_error_response(1, message)
121 self.logger.error(user_info)
122 return AMApiBase.embed_data({}, 1, user_info)
125 self.logger.info("Received a user remove role request!")
126 args = self.parse_args()
128 if args["role_name"] is None:
129 self.logger.error("Role name parameter is missing!")
130 return AMApiBase.embed_data({}, 1, "Role name parameter is missing!")
132 state, user_info = self.get_uuid_and_name(args["user"])
134 token_owner = self.get_uuid_from_token()
135 if user_info["id"] == token_owner and args["role_name"] == defaults.INF_ADMIN_ROLE_NAME:
136 self.logger.error("The {0} user tried to removed own ".format(user_info["name"])+defaults.INF_ADMIN_ROLE_NAME+" role!")
137 return AMApiBase.embed_data({}, 1, "You cannot remove own "+defaults.INF_ADMIN_ROLE_NAME+" role!")
139 username, def_project = self.get_user_from_uuid(user_info["id"])
140 state, message = self._remove_role(args["role_name"], def_project, user_info)
143 self.logger.info("The {0} role removed from the {1} user!".format(args["role_name"], user_info["name"]))
144 return AMApiBase.embed_data({}, 0, "Role removed from user.")
146 self.logger.error("Removal of {0} role from {1} user failed: {2}".format(args["role_name"], user_info["name"], message))
147 return AMApiBase.construct_error_response(1, message)
149 self.logger.error(user_info)
150 return AMApiBase.embed_data({}, 1, user_info)
152 def _remove_role(self, role_name, project, user_info):
153 state_open, message_open = self._open_db()
155 need_admin_role = True
157 roles = self.db.get_user_roles(user_info["id"])
159 return False, 'User {0} does not exist.'.format(user_info["name"])
160 except Exception as ex:
161 return False, 'Error retrieving roles for user {0}: {1}'.format(user_info["name"], ex)
162 if (role_name == defaults.INF_ADMIN_ROLE_NAME and defaults.OS_ADMIN_ROLE_NAME in roles) or (role_name == defaults.OS_ADMIN_ROLE_NAME and defaults.INF_ADMIN_ROLE_NAME in roles):
163 need_admin_role = False
164 state, message = self.modify_role_in_keystone(role_name, user_info["id"], "delete", project, need_admin_role)
166 return state, message
170 # remove chroot user only if the role is chroot role
171 self.logger.debug("Check the chroot role, when removing a role!")
172 if self.db.is_chroot_role(role_name):
173 self.logger.debug("This is a chroot role!")
175 self.remove_chroot_linux_role_handling(user_info["name"], "Chroot", "cloud.chroot")
177 if self.check_chroot_linux_state(user_info["name"], "cloud.chroot", "absent"):
178 self.db.delete_user_role(user_info["id"], role_name)
179 return True, "Success"
181 self.logger.error("The {0} user cannot remove {1} role, because the cm framework set_property's function failed.".format(user_info["name"], role_name))
182 return False, "The chroot user is not removed. Please try again!"
184 if role_name == "linux_user":
185 self.logger.debug("This is a linux_user role!")
187 self.remove_chroot_linux_role_handling(user_info["name"], "Linux", "cloud.linuxuser")
189 if self.check_chroot_linux_state(user_info["name"], "cloud.linuxuser", "absent"):
190 self.db.delete_user_role(user_info["id"], role_name)
191 return True, "Success"
193 self.logger.error("The {0} user cannot remove {1} role, because the cm framework set_property's function failed.".format(user_info["name"], role_name))
194 return False, "The linux user is not removed. Please try again!"
196 self.db.delete_user_role(user_info["id"], role_name)
197 except amdb.NotAllowedOperation:
198 return False, 'Service role cannot be deleted: {0}'.format(user_info["name"])
199 except amdb.NotExist:
200 return False, 'User {0} has no role {1}.'.format(user_info["name"], role_name)
201 except amdb.AlreadyExist:
202 return False, 'Role for user already exists in table: {0}:{1}'.format(user_info["name"], role_name)
203 except Exception as ex:
206 state_close, message_close = self._close_db()
209 return True, "Success"
211 return False, message_open
213 def _add_role(self, role_name, project, user_info):
214 state, message = self.modify_role_in_keystone(role_name, user_info["id"], "put", project)
216 return state, message
218 state, message = self.add_role_db_functions(role_name, user_info)
219 return state, message
221 def add_role_db_functions(self, role_name, user_info):
222 state_open, message_open = self._open_db()
225 roles = self.db.get_user_roles(user_info["id"])
226 self.db.add_user_role(user_info["id"], role_name)
228 # create chroot user only if the role is chroot role
229 self.logger.debug("Check the chroot role, when adding a role!")
230 if self.db.is_chroot_role(role_name):
231 self.logger.debug("This is a chroot role!")
233 if "linux_user" in roles:
234 self.logger.error("The {0} user cannot get {1} chroot role, because this user has a linux_user role".format(user_info["name"], role_name))
235 self.db.delete_user_role(user_info["id"], role_name)
236 return False, "The {0} user cannot get {1} chroot role, because this user has a linux_user role".format(user_info["name"], role_name)
239 self.add_chroot_linux_role_handling(user_info["id"], "Chroot", "cloud.chroot", role_name)
241 if self.check_chroot_linux_state(user_info["name"], "cloud.chroot", "present"):
242 return True, "Success"
244 self.db.delete_user_role(user_info["id"], role_name)
245 self.logger.error("The {0} user cannot get {1} role, because the cm framework set_property's function failed.".format(user_info["name"], role_name))
246 return False, "The chroot user is not created. Please try again!"
248 # create linux user only if the role is linux_user role
249 if role_name == "linux_user":
250 self.logger.debug("This is a linux_user role!")
251 have_a_chroot = False
252 self.logger.debug("role list: {0}".format(roles))
254 if self.db.is_chroot_role(role):
258 self.logger.error("The {0} user cannot get {1} role, because this user has a chroot role".format(user_info["name"], role_name))
259 self.db.delete_user_role(user_info["id"], role_name)
260 return False, "The {0} user cannot get {1} role, because this user has a chroot role".format(user_info["name"], role_name)
263 self.add_chroot_linux_role_handling(user_info["id"], "Linux", "cloud.linuxuser", None)
265 if self.check_chroot_linux_state(user_info["name"], "cloud.linuxuser", "present"):
266 return True, "Success"
268 self.db.delete_user_role(user_info["id"], role_name)
269 self.logger.error("The {0} user cannot get {1} role, because the cm framework set_property's function failed.".format(user_info["name"], role_name))
270 return False, "The linux user is not created. Please try again!"
272 except amdb.NotExist:
273 return False, 'The user {} or role {} not exist.'.format(user_info["name"], role_name)
274 except amdb.AlreadyExist:
275 return False, 'Role for user already exists in table: {0}:{1}'.format(user_info["name"], role_name)
276 except Exception as ex:
279 state_close, message_close = self._close_db()
282 return True, "Success"
284 return False, message_open
286 def add_chroot_linux_role_handling(self, user_id, user_type, list_name, group):
287 cmc = cmclient.CMClient()
288 user_list = cmc.get_property(list_name)
289 if user_list is None:
290 cmc.set_property(list_name, json.dumps([]))
291 user_list = cmc.get_property(list_name)
292 user_list = json.loads(user_list)
293 self.logger.debug("{0} user list before the change: {1}".format(user_type, json.dumps(user_list)))
295 self.logger.debug("The {0} user list exists!".format(user_type))
296 username, def_project = self.get_user_from_uuid(user_id)
297 self.logger.debug("Username: {0}".format(username))
298 for element in user_list:
299 if element["name"] == username:
300 if element["state"] == "present":
301 self.logger.error("The {0} user has an active {1} chroot role".format(username, element["group"]))
302 self.db.delete_user_role(user_id, group)
303 return False, "The {0} users have an active {1} chroot role".format(username, element["group"])
305 self.logger.debug("The {0} user has an active linux_user role".format(username))
306 if group is not None:
307 element["group"] = group
308 element["state"] = "present"
309 element["remove"] = "no"
312 new_user = {"name": username, "password": "", "state": "present", "remove": "no", "lock_state": "-u", "public_key": ""}
313 if group is not None:
314 new_user["group"]= group
315 user_list.append(new_user)
316 self.logger.debug("{0} user list after the change: {1}".format(user_type, json.dumps(user_list)))
317 cmc.set_property(list_name, json.dumps(user_list))
319 def remove_chroot_linux_role_handling(self, username, user_type, list_name):
320 cmc = cmclient.CMClient()
321 user_list = cmc.get_property(list_name)
322 user_list = json.loads(user_list)
323 self.logger.debug("{0} user list before the change: {1}".format(user_type, json.dumps(user_list)))
324 if user_list is not None:
325 self.logger.debug("The {0} user list exists!".format(user_type))
326 for val in user_list:
327 if val["name"] == username:
328 val["public_key"] = ""
329 val["state"] = "absent"
330 val["remove"] = "yes"
333 self.logger.debug("{0} user list after the change: {1}".format(user_type, json.dumps(user_list)))
334 cmc.set_property(list_name, json.dumps(user_list))