def test_create_person(self): person = persons_service.create_person( "*****@*****.**", auth.encrypt_password("passwordhash"), "John", "Doe", ) person = persons_service.get_person_by_email(person["email"]) self.assertEqual(person["first_name"], "John") person = persons_service.create_person( " [email protected] \n", auth.encrypt_password("passwordhash"), "John", "Doe", ) person = persons_service.get_person_by_email("*****@*****.**") self.assertEqual(person["first_name"], "John") person = persons_service.create_person( " [email protected] \n", auth.encrypt_password("passwordhash"), "John", "Doe", departments=[None], ) person = persons_service.get_person_by_email("*****@*****.**") self.assertEqual(person["first_name"], "John")
def test_add_logs(self): person = persons_service.get_person_by_email("*****@*****.**") person_raw = Person.get(person["id"]) person_raw.update({"email": "*****@*****.**"}) person = persons_service.get_person_by_email("*****@*****.**") person = persons_service.update_person( person["id"], {"email": "*****@*****.**"}) with pytest.raises(PersonNotFoundException): persons_service.get_person_by_email("*****@*****.**") person = persons_service.get_person_by_email("*****@*****.**")
def check_credentials(email, password, app=None): """ Check if given password and email match an user in database. Password hash comparison is based on BCrypt. """ try: person = persons_service.get_person_by_email(email) except PersonNotFoundException: try: person = persons_service.get_person_by_desktop_login(email) except PersonNotFoundException: if app is not None: app.logger.error("Person not found: %s" % (email)) raise WrongPasswordException() try: password_hash = person["password"] or u'' if bcrypt.check_password_hash(password_hash, password): return person else: if app is not None: app.logger.error("Wrong password for person: %s" % person) raise WrongPasswordException() except ValueError: if app is not None: app.logger.error("Wrong password for: %s" % person) raise WrongPasswordException()
def get(self): """ Returns information if the user is authenticated else it returns a 401 response. --- description: It can be used by third party tools, especially browser frontend, to know if current user is still logged in. tags: - Authentification responses: 200: description: User authenticated 401: description: Person not found """ try: person = persons_service.get_person_by_email(get_jwt_identity(), relations=True) organisation = persons_service.get_organisation() return { "authenticated": True, "user": person, "organisation": organisation, "ldap": app.config["AUTH_STRATEGY"] == "auth_remote_ldap", } except PersonNotFoundException: abort(401)
def create_admin(email, password): "Create an admin user to allow usage of the API when database is empty." "Set password is 'default'." # If a user already exists, change its role to admin try: person = persons_service.get_person_by_email(email) if person['role'] != 'admin': persons_service.update_person(person['id'], {'role': 'admin'}) except PersonNotFoundException: try: # Allow "*****@*****.**" to be invalid. if email != "*****@*****.**": auth.validate_email(email) password = auth.encrypt_password(password) persons_service.create_person(email, password, "Super", "Admin", role="admin") print("Admin successfully created.") except IntegrityError: print("User already exists for this email.") sys.exit(1) except auth.PasswordsNoMatchException: print("Passwords don't match.") sys.exit(1) except auth.PasswordTooShortException: print("Password is too short.") sys.exit(1) except auth.EmailNotValidException: print("Email is not valid.") sys.exit(1)
def post(self): args = self.get_arguments() token = uuid.uuid4() try: user = persons_service.get_person_by_email(args["email"]) except PersonNotFoundException: return { "error": True, "message": "Email not listed in database." }, 400 auth_tokens_store.add("reset-%s" % token, args["email"], ttl=3600 * 2) message_text = """Hello %s, You have requested for a password reset. You can connect here to change your password: https://%s/reset-change-password/%s Regards, CGWire Team """ % (user["first_name"], current_app.config["DOMAIN_NAME"], token) if current_app.config["MAIL_DEBUG"]: print(message_text) else: message = Message(body=message_text, subject="CGWire password recovery", recipients=[args["email"]]) mail.send(message) return {"success": "Reset token sent"}
def update_person_list_with_ldap_users(users): for user in users: first_name = user["first_name"] last_name = user["last_name"] desktop_login = user["desktop_login"] email = user["email"] active = user.get("active", True) if "thumbnail" in user and len(user["thumbnail"]) > 0: thumbnail = user["thumbnail"][0] else: thumbnail = "" person = None try: person = persons_service.get_person_by_desktop_login( desktop_login) except PersonNotFoundException: try: person = persons_service.get_person_by_email(email) except PersonNotFoundException: pass if len(email) == 0 or email == "[]" or type(email) != str: email = "%s@%s" % (desktop_login, EMAIL_DOMAIN) if person is None and active is True: try: person = persons_service.create_person( email, "default".encode("utf-8"), first_name, last_name, desktop_login=desktop_login, ) print("User %s created." % desktop_login) except: print("User %s creation failed (email duplicated?)." % (desktop_login)) elif person is not None: try: active = True persons_service.update_person( person["id"], { "email": email, "first_name": first_name, "last_name": last_name, "active": active, }, ) print("User %s updated." % desktop_login) except: print("User %s update failed (email duplicated?)." % (desktop_login)) if person is not None and len(thumbnail) > 0: save_thumbnail(person, thumbnail)
def test_create_person(self): person = persons_service.create_person( "*****@*****.**", auth.encrypt_password("passwordhash"), "John", "Doe" ) person = persons_service.get_person_by_email(person["email"]) self.assertEquals(person["first_name"], "John")
def ldap_auth_strategy(email, password, app): """ Connect to an active directory server to know if given user can be authenticated. """ person = None try: person = persons_service.get_person_by_email(email) except PersonNotFoundException: person = persons_service.get_person_by_desktop_login(email) try: SSL = app.config["LDAP_SSL"] if app.config["LDAP_IS_AD_SIMPLE"]: user = "******" % ( person["full_name"], app.config["LDAP_BASE_DN"], ) SSL = True authentication = SIMPLE elif app.config["LDAP_IS_AD"]: user = "******" % ( app.config["LDAP_DOMAIN"], person["desktop_login"], ) authentication = NTLM else: user = "******" % ( person["desktop_login"], app.config["LDAP_BASE_DN"], ) authentication = SIMPLE ldap_server = "%s:%s" % ( app.config["LDAP_HOST"], app.config["LDAP_PORT"], ) server = Server(ldap_server, get_info=ALL, use_ssl=SSL) conn = Connection( server, user=user, password=password, authentication=authentication, raise_exceptions=True, ) conn.bind() return person except LDAPSocketOpenError: app.logger.error("Cannot connect to LDAP/Active directory server %s " % (ldap_server)) return ldap_auth_strategy_fallback(email, password, app, person) except LDAPInvalidCredentialsResult: app.logger.error("LDAP cannot authenticate user: %s" % email) return ldap_auth_strategy_fallback(email, password, app, person)
def test_get_person_by_email(self): self.assertRaises(PersonNotFoundException, persons_service.get_person_by_email, "wrong-email") person = persons_service.get_person_by_email(self.person_email) self.assertEqual(self.person_id, person["id"]) persons_service.delete_person(person["id"]) self.assertRaises(PersonNotFoundException, persons_service.get_person_by_email, self.person_email)
def ldap_auth_strategy_fallback(email, password, app, person): """ When ldap auth fails, admin users can try to connect with default auth strategy. (only if fallback is activated (via LDAP_FALLBACK flag) in configuration) """ if app.config["LDAP_FALLBACK"] and persons_service.is_admin(person): person = persons_service.get_person_by_email(email) return local_auth_strategy(email, password, app) else: raise WrongPasswordException
def get(self): try: person = persons_service.get_person_by_email(get_jwt_identity()) organisation = persons_service.get_organisation() return { "authenticated": True, "user": person, "organisation": organisation, "ldap": app.config["AUTH_STRATEGY"] == "auth_remote_ldap", } except PersonNotFoundException: abort(401)
def no_password_auth_strategy(email): """ If no password auth strategy is configured, it just checks that given email matches an user in the database. """ try: person = persons_service.get_person_by_email(email) except PersonNotFoundException: try: person = persons_service.get_person_by_desktop_login(email) except PersonNotFoundException: return None return person
def test_get_person_by_desktop_login(self): self.assertRaises(PersonNotFoundException, persons_service.get_person_by_desktop_login, "wrong-login") person = persons_service.get_person_by_desktop_login( self.person_desktop_login) person = persons_service.get_person_by_email(person["email"]) self.assertEqual(self.person_id, person["id"]) persons_service.delete_person(person["id"]) self.assertRaises(PersonNotFoundException, persons_service.get_person_by_desktop_login, self.person_desktop_login)
def post(self): """ Ressource to allow a user to change his password when he forgets it. --- description: "It uses a classic scheme: a token is sent by email to the user. Then he can change his password." tags: - Authentification parameters: - in: body name: Email description: The email of the user schema: type: object required: - email properties: email: type: string responses: 200: description: Reset token sent 400: description: Email not listed in database """ args = self.get_arguments() try: user = persons_service.get_person_by_email(args["email"]) except PersonNotFoundException: return ( { "error": True, "message": "Email not listed in database." }, 400, ) token = uuid.uuid4() auth_tokens_store.add("reset-%s" % token, args["email"], ttl=3600 * 2) message_text = """Hello %s, You have requested for a password reset. You can connect here to change your password: %s://%s/reset-change-password/%s Regards, CGWire Team """ % ( user["first_name"], current_app.config["DOMAIN_PROTOCOL"], current_app.config["DOMAIN_NAME"], token, ) if current_app.config["MAIL_DEBUG"]: print(message_text) else: message = Message( body=message_text, subject="CGWire password recovery", recipients=[args["email"]], ) mail.send(message) return {"success": "Reset token sent"}
def get(self): try: person = persons_service.get_person_by_email(get_jwt_identity()) return {"authenticated": True, "user": person} except PersonNotFoundException: abort(401)