コード例 #1
0
    def authenticate_and_fetch_profile(self,
                                       username,
                                       password,
                                       username_for_profile=None):
        """Authenticates a user with credentials username and password against AD.

        If authentication is successful then it
        fetches a profile of a user identified by username_for_profile and if found the profile is returned.

        :param username: LDAP username
        :param password: LDAP password
        :param username_for_profile: Username of the profile to be fetched
        :return: user profile base on the LDAP_USER_ATTRIBUTES
        """

        if username_for_profile is None:
            username_for_profile = username

        if self.fqdn is not None:
            username = username + "@" + self.fqdn

        try:
            ldap_conn = Connection(self.ldap_server,
                                   auto_bind=True,
                                   user=username,
                                   password=password)

            user_filter = self.user_filter.format(username_for_profile)
            logger.info('base filter:{} user filter:{}'.format(
                self.base_filter, user_filter))

            with ldap_conn:
                result = ldap_conn.search(self.base_filter,
                                          user_filter,
                                          SEARCH_SCOPE_WHOLE_SUBTREE,
                                          attributes=list(
                                              self.profile_attrs.keys()))

                if not result:
                    # the search returns false in case of user not a security group member.
                    raise CredentialsAuthError(
                        credentials={'username': username},
                        message='User does not belong to security Group or '
                        'could not find the user profile.')

                response = dict()
                user_profile = ldap_conn.response[0]['attributes']

                for ad_profile_attr, sd_profile_attr in self.profile_attrs.items(
                ):
                    response[sd_profile_attr] = \
                        user_profile[ad_profile_attr] if user_profile.__contains__(ad_profile_attr) else ''

                    response[sd_profile_attr] = response[sd_profile_attr][0] \
                        if isinstance(response[sd_profile_attr], list) else response[sd_profile_attr]

                return response
        except LDAPException as e:
            raise CredentialsAuthError(credentials={'username': username},
                                       error=e)
コード例 #2
0
ファイル: db.py プロジェクト: girgen79/superdesk
    def authenticate(self, credentials):
        user = get_resource_service('auth_users').find_one(req=None, username=credentials.get('username'))
        if not user:
            raise CredentialsAuthError(credentials)

        if 'is_enabled' in user and not user.get('is_enabled', False):
            raise UserDisabledError()

        if not user.get('is_active', False):
            raise UserInactiveError()

        password = credentials.get('password').encode('UTF-8')
        hashed = user.get('password').encode('UTF-8')

        if not (password and hashed):
            raise CredentialsAuthError(credentials)

        try:
            rehashed = bcrypt.hashpw(password, hashed)
            if hashed != rehashed:
                raise CredentialsAuthError(credentials)
        except ValueError:
            raise CredentialsAuthError(credentials)

        return user
コード例 #3
0
    def authenticate(self, credentials):
        auth_url = app.config['XMPP_AUTH_URL']
        if not auth_url:
            raise SuperdeskApiError.notConfiguredError()
        domain = app.config['XMPP_AUTH_DOMAIN']
        jid = credentials.get('jid')
        if not jid:
            raise CredentialsAuthError(credentials)
        user = get_resource_service('auth_users').find_one(req=None, jid=jid)
        if not user:
            raise CredentialsAuthError(credentials)

        try:
            r = requests.post(app.config['XMPP_AUTH_URL'],
                              data={
                                  "jid":
                                  jid,
                                  "domain":
                                  domain,
                                  "transaction_id":
                                  credentials.get('transactionId')
                              })
        except Exception:
            raise CredentialsAuthError(credentials)
        else:
            if r.status_code != 200:
                raise CredentialsAuthError(credentials)

        return user
コード例 #4
0
ファイル: auth.py プロジェクト: superdesk/superdesk-core
    def authenticate(self, credentials):
        auth_header = request.headers.get("Authorization", "").split(" ", 1)
        if auth_header[0] != "Bearer" and len(auth_header) != 2:
            raise CredentialsAuthError(credentials)
        token = auth_header[1]
        is_valid = self.oidc.validate_token(token,
                                            ["openid", "email", "profile"])
        if not is_valid:
            raise CredentialsAuthError(credentials)

        users_service = get_resource_service("users")
        username = g.oidc_token_info["username"]
        user = users_service.find_one(req=None, username=username) or {}

        sync_data = {
            "username": username,
            "email": g.oidc_token_info.get("email", user.get("email")),
            "display_name": g.oidc_token_info.get("name"),
        }

        # first name and last name is optional in Keycloak
        if "given_name" in g.oidc_token_info:
            sync_data["first_name"] = g.oidc_token_info.get("given_name")
        if "family_name" in g.oidc_token_info:
            sync_data["last_name"] = g.oidc_token_info.get("family_name")

        if not user:
            # email is optional in Keycloak
            if not sync_data["email"]:
                raise CredentialsAuthError(
                    sync_data,
                    message=_("Please update your account email address"))
            user_role = None
            client_id = g.oidc_token_info.get("client_id", "")
            keycloak_roles = g.oidc_token_info.get("resource_access", {}).get(
                client_id, {}).get("roles", [])
            for role_name in keycloak_roles:
                role = get_resource_service("roles").find_one(
                    req=None, name=ignorecase_query(role_name))
                if role:
                    user_role = role.get("_id")
                    break
            sync_data.update({
                "password": "",
                "user_type": "user",
                "role": user_role,
                "needs_activation": False,
            })
            users_service.post([sync_data])
        else:
            users_service.patch(user[config.ID_FIELD], sync_data)

        user.update(sync_data)
        return user
コード例 #5
0
ファイル: db.py プロジェクト: vincerdesk/superdesk-core
    def authenticate(self, credentials):
        user = get_resource_service('auth_users').find_one(req=None, username=credentials.get('username'))
        if not user:
            raise CredentialsAuthError(credentials)

        password = credentials.get('password').encode('UTF-8')
        hashed = user.get('password').encode('UTF-8')

        if not (password and hashed):
            raise CredentialsAuthError(credentials)

        if not bcrypt.checkpw(password, hashed):
            raise CredentialsAuthError(credentials)

        return user
コード例 #6
0
    class ImportUsersTestCase(SuperdeskTestCase):
        """
        for testing import user using ldap.
        """
        def test_import_user_using_command(self, mock_ldap_connection):
            user = {'username': '******', 'password': '******', 'user_to_import': 'barf'}
            cmd = ImportUserProfileFromADCommand()

            cmd.run(user['username'], user['password'], user['user_to_import'])
            auth_user = get_resource_service('auth').authenticate({'username': '******', 'password': '******'})
            self.assertEqual(auth_user['username'], user['user_to_import'])

            cmd.run(user['username'], user['password'], 'BARF')
            auth_user2 = get_resource_service('auth').authenticate({'username': '******', 'password': '******'})
            self.assertEqual(auth_user2['username'], user['user_to_import'])

            self.assertEqual(auth_user2['_id'], auth_user['_id'])

        @mock.patch('apps.ldap.ldap.get_user', return_value={'username': '******'})
        def test_import_profile_for_already_imported_user_raises_exception(self, mock_ldap_connection, mock_get_user):
            with self.assertRaises(SuperdeskApiError) as context:
                service = get_resource_service('import_profile')
                doc = {'username': '******', 'password': '******', 'profile_to_import': 'barf'}
                users = service.post([doc])
                self.assertIsNotNone(users)
                self.assertEqual(len(users), 1)
                doc = {'username': '******', 'password': '******', 'profile_to_import': 'BARF '}
                service.post([doc])

            ex = context.exception
            self.assertEqual(ex.message, 'User already exists in the system.')
            self.assertEqual(ex.status_code, 400)
            self.assertDictEqual(ex.payload, {'profile_to_import': 1})

        @mock.patch('apps.ldap.ldap.get_user', return_value={'username': '******'})
        def test_import_user_by_not_logged_in_user_raises_exception(self, mock_ldap_connection, mock_get_user):
            with self.assertRaises(SuperdeskApiError) as context:
                service = get_resource_service('import_profile')
                doc = {'username': '******', 'password': '******', 'profile_to_import': 'barf'}
                service.post([doc])

            ex = context.exception
            self.assertEqual(ex.message, 'Invalid Credentials.')
            self.assertEqual(ex.status_code, 403)
            self.assertDictEqual(ex.payload, {'credentials': 1})

        @mock.patch('apps.ldap.ldap.ADAuth.authenticate_and_fetch_profile',
                    side_effect=CredentialsAuthError(credentials={'username': '******'}, error='test'))
        @mock.patch('apps.ldap.ldap.get_user', return_value={'username': '******'})
        def test_user_import_profile_with_invalid_credentials(self, mock_ldap_connection, mock_auth, mock_get_user):
                with self.assertRaises(SuperdeskApiError) as context:
                    service = get_resource_service('import_profile')
                    doc = {'username': '******', 'password': '******', 'profile_to_import': 'barf'}
                    service.post([doc])

                ex = context.exception
                self.assertEqual(ex.message, 'Invalid Credentials.')
                self.assertEqual(ex.status_code, 403)
                self.assertDictEqual(ex.payload, {'credentials': 1})
コード例 #7
0
ファイル: db.py プロジェクト: superdesk/superdesk-core
    def authenticate(self, credentials, ignore_expire=False):
        user = get_resource_service("auth_users").find_one(req=None, username=credentials.get("username"))
        if not user:
            raise CredentialsAuthError(credentials)

        password = credentials.get("password").encode("UTF-8")
        hashed = user.get("password").encode("UTF-8")

        if not (password and hashed):
            raise CredentialsAuthError(credentials)

        if not bcrypt.checkpw(password, hashed):
            raise CredentialsAuthError(credentials)

        if not ignore_expire and app.settings.get("PASSWORD_EXPIRY_DAYS", 0) > 0:
            days = app.settings.get("PASSWORD_EXPIRY_DAYS")
            date = user.get("password_changed_on")
            if date is None or (date + datetime.timedelta(days=days)) < utcnow():
                raise PasswordExpiredError()

        return user
コード例 #8
0
 def disable_sd_desktop_notification(self, credentials):
     user = get_resource_service('users').find_one(
         req=None, username=credentials.get('username'))
     if not user:
         raise CredentialsAuthError(credentials)
     user_updates = user
     user_preferences = user_updates.get('user_preferences')
     if user_preferences:
         desktop_notification = user_preferences.get('desktop:notification')
         if desktop_notification:
             enabled = desktop_notification.get('enabled')
             if enabled:
                 user_updates['user_preferences']['desktop:notification'][
                     'enabled'] = False
     get_resource_service('users').system_update(user['_id'], user_updates,
                                                 user)
コード例 #9
0
    def create(self, docs, **kwargs):
        for doc in docs:
            username = doc['username']
            credentials = {
                'username': username,
                'password': doc['old_password']
            }
            try:
                get_resource_service('auth_db').authenticate(credentials, True)
            except Exception as e:
                raise CredentialsAuthError(credentials=credentials, error=e)

            user = superdesk.get_resource_service('users').find_one(
                req=None, username=username)
            superdesk.get_resource_service('users').update_password(
                user['_id'], doc['new_password'])
            del doc['old_password']
            del doc['new_password']
            return [user['_id']]
コード例 #10
0
    def create(self, docs, **kwargs):
        for doc in docs:
            username = doc["username"]
            credentials = {"username": username, "password": doc["old_password"]}
            try:
                get_resource_service("auth_db").authenticate(credentials, True)
            except Exception as e:
                raise CredentialsAuthError(credentials=credentials, error=e)

            user = superdesk.get_resource_service("users").find_one(req=None, username=username)
            superdesk.get_resource_service("users").update_password(user["_id"], doc["new_password"])
            del doc["old_password"]
            del doc["new_password"]

            # return etag for further user updates
            user = superdesk.get_resource_service("users").find_one(req=None, _id=user["_id"])
            doc["_etag"] = user["_etag"]

            return [user["_id"]]
コード例 #11
0
    class ImportUsersTestCase(TestCase):
        """for testing import user using ldap."""
        def test_import_user_using_command(self, mock_ldap_connection):
            user = {
                "username": "******",
                "password": "******",
                "user_to_import": "barf"
            }
            cmd = ImportUserProfileFromADCommand()

            cmd.run(user["username"], user["password"], user["user_to_import"])
            auth_user = get_resource_service("auth_db").authenticate({
                "username":
                "******",
                "password":
                "******"
            })
            self.assertEqual(auth_user["username"], user["user_to_import"])

            cmd.run(user["username"], user["password"], "BARF")
            auth_user2 = get_resource_service("auth_db").authenticate({
                "username":
                "******",
                "password":
                "******"
            })
            self.assertEqual(auth_user2["username"], user["user_to_import"])

            self.assertEqual(auth_user2["_id"], auth_user["_id"])

        @mock.patch("apps.ldap.ldap.get_user",
                    return_value={"username": "******"})
        def test_import_profile_for_already_imported_user_raises_exception(
                self, mock_ldap_connection, mock_get_user):
            with self.assertRaises(SuperdeskApiError) as context:
                service = get_resource_service("import_profile")
                doc = {
                    "username": "******",
                    "password": "******",
                    "profile_to_import": "barf"
                }
                users = service.post([doc])
                self.assertIsNotNone(users)
                self.assertEqual(len(users), 1)
                doc = {
                    "username": "******",
                    "password": "******",
                    "profile_to_import": "BARF "
                }
                service.post([doc])

            ex = context.exception
            self.assertEqual(ex.message, "User already exists in the system.")
            self.assertEqual(ex.status_code, 400)
            self.assertDictEqual(ex.payload, {"profile_to_import": 1})

        @mock.patch("apps.ldap.ldap.get_user",
                    return_value={"username": "******"})
        def test_import_user_by_not_logged_in_user_raises_exception(
                self, mock_ldap_connection, mock_get_user):
            with self.assertRaises(SuperdeskApiError) as context:
                service = get_resource_service("import_profile")
                doc = {
                    "username": "******",
                    "password": "******",
                    "profile_to_import": "barf"
                }
                service.post([doc])

            ex = context.exception
            self.assertEqual(ex.message, "Invalid Credentials.")
            self.assertEqual(ex.status_code, 403)
            self.assertDictEqual(ex.payload, {"credentials": 1})

        @mock.patch(
            "apps.ldap.ldap.ADAuth.authenticate_and_fetch_profile",
            side_effect=CredentialsAuthError(credentials={"username": "******"},
                                             error="test"),
        )
        @mock.patch("apps.ldap.ldap.get_user",
                    return_value={"username": "******"})
        def test_user_import_profile_with_invalid_credentials(
                self, mock_ldap_connection, mock_auth, mock_get_user):
            with self.assertRaises(SuperdeskApiError) as context:
                service = get_resource_service("import_profile")
                doc = {
                    "username": "******",
                    "password": "******",
                    "profile_to_import": "barf"
                }
                service.post([doc])

            ex = context.exception
            self.assertEqual(ex.message, "Invalid Credentials.")
            self.assertEqual(ex.status_code, 403)
            self.assertDictEqual(ex.payload, {"credentials": 1})