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.
18 import access_management.db.amdb as amdb
19 from am_api_base import *
20 from keystoneauth1 import exceptions
21 from cmframework.apis import cmclient
24 class UsersOwnpasswords(AMApiBase):
27 User set password operations
29 .. :quickref: User ownpasswords;User set password operations
31 .. http:post:: /am/v1/users/ownpasswords
33 **Start User set password**
39 POST am/v1/users/ownpasswords HTTP/1.1
40 Host: haproxyvip:61200
41 Accept: application/json
43 "npassword: "Passwd_1",
44 "opassword: "Passwd_2",
45 "username": "test_user"
48 :> json string npassword: The user's new password
49 :> json string opassword: The user's old password
50 :> json string username: The user's username
51 :> json string id: The user's ID
52 Only one of username or id needs to be present.
61 "description": "User password changed successfully!"
64 :> json int code: the status code
65 :> json string description: the error description, present if code is non zero
68 endpoints = ['users/ownpasswords']
69 parser_arguments = ['npassword',
73 FAILURE_RESPONSE = AMApiBase.embed_data({}, 1, "Password change failed!")
76 self.logger.info("Received a set password request!")
77 args = self.parse_args()
80 state_open, message_open = self._open_db()
84 user["name"] = args["username"]
85 user["uuid"] = self.db.get_user_uuid(args["username"])
87 user["uuid"] = args["id"]
88 user["name"] = self.db.get_user_name(args["id"])
91 keystone = self.auth_keystone_with_pass(args["opassword"], user["name"])
92 passstate = self.passwd_validator(args["npassword"])
93 if passstate is not None:
94 self.logger.error(passstate)
95 return AMApiBase.embed_data({}, 1, passstate)
96 keystone.users.update_password(args["opassword"], args["npassword"])
98 except exceptions.http.Unauthorized as ex:
99 if "password is expired" in ex.message:
100 passstate = self.passwd_validator(args["npassword"])
101 if passstate is not None:
102 self.logger.error(passstate)
103 return AMApiBase.embed_data({}, 1, passstate)
104 state = self.change_password_with_request(args, user["uuid"])
106 self.logger.error("{0}".format(ex))
108 except Exception as ex:
109 self.logger.error("{0}".format(ex))
110 return self.FAILURE_RESPONSE
113 state = self.set_ownpass_in_db(args, user)
115 self.logger.info("User password changed successfully!")
116 return AMApiBase.embed_data({}, 0, "User password changed successfully!")
118 return self.FAILURE_RESPONSE
120 return self.FAILURE_RESPONSE
122 except amdb.NotExist as ex:
123 self.logger.error("User does not exist")
124 return self.FAILURE_RESPONSE
125 except Exception as ex:
126 self.logger.error("Internal error: {0}".format(ex))
127 return self.FAILURE_RESPONSE
129 state_close, message_close = self._close_db()
133 return self.FAILURE_RESPONSE
135 def change_password_with_request(self, args, uuid):
136 url = self.config["Keystone"]["auth_uri"] + "/users/" + uuid + "/password"
137 parameter = {"user": {"password": args["npassword"], "original_password": args["opassword"]}}
138 header = {"Content-Type": "application/json"}
139 s_user_out = requests.post(url, data=json.dumps(parameter), headers=header, timeout=30)
141 if s_user_out.status_code != 204:
142 s_user_out = s_user_out.json()
143 self.logger.error(s_user_out["error"]["message"])
147 def set_ownpass_in_db(self, args, user):
148 linux_user_role = False
149 chroot_user_role = False
150 state_open, message_open = self._open_db()
153 roles = self.db.get_user_roles(user["uuid"])
156 if self.db.is_chroot_role(role):
157 chroot_user_role = True
158 if role == "linux_user":
159 linux_user_role = True
161 # if the user has a chroot or linux account, change the pwd of that also
163 self.linux_chroot_pass_handling("Chroot", "cloud.chroot", args["npassword"], user["name"])
165 self.linux_chroot_pass_handling("Linux", "cloud.linuxuser", args["npassword"], user["name"])
167 except amdb.NotExist as ex:
168 self.logger.error("User does not exist")
170 except Exception as ex:
171 self.logger.error("Internal error: {0}".format(ex))
174 state_close, message_close = self._close_db()
178 self.logger.error("Could not open DB")
183 def linux_chroot_pass_handling(self, user_type, list_name, passwd, username):
184 cmc = cmclient.CMClient()
185 user_list = cmc.get_property(list_name)
186 user_list = json.loads(user_list)
187 self.logger.debug("{0} user list before the change: {1}".format(user_type, json.dumps(user_list)))
188 if user_list is not None:
189 self.logger.debug("The {0} user list exists!".format(user_type))
190 self.logger.debug("Username: {0}".format(username))
191 for val in user_list:
192 if val["name"] == username:
193 val["password"] = crypt.crypt(passwd, crypt.mksalt(crypt.METHOD_SHA512))
195 self.logger.debug("{0} user list after the change: {1}".format(user_type, json.dumps(user_list)))
196 cmc.set_property(list_name, json.dumps(user_list))