async def authenticate(request, *args, **kwargs):
    """Set up JWT auth."""

    user_service = UserService(request[REQUEST_DB_SESSION_KEY])
    rjs = request.json

    # enterprise SSO single-use-token login
    if rjs and rjs.get("single_use_token") is not None:
        user = user_service.single_use_token_login(rjs["single_use_token"],
                                                   return_api_token=True)
        if user:
            return user
        else:
            raise exceptions.AuthenticationFailed(
                "Wrong authentication token.")

    if not rjs:
        raise exceptions.AuthenticationFailed("Missing username or password.")

    # standard auth with username and password in request
    username = rjs.get("username", None)
    password = rjs.get("password", None)

    if username and password:
        return user_service.login(username, password, return_api_token=True)

    raise exceptions.AuthenticationFailed("Missing username or password.")
예제 #2
0
def create_community_user(session: orm.Session,
                          app: Optional[sanic.Sanic] = None) -> None:
    from rasax.community.services.role_service import RoleService
    from rasax.community.services.settings_service import SettingsService

    role_service = RoleService(session)
    role_service.init_roles(project_id=constants.COMMUNITY_PROJECT_NAME)

    settings_service = SettingsService(session)
    password = settings_service.get_community_user_password()
    is_password_generated = False

    # only re-assign password in local mode or if it doesn't exist
    if config.LOCAL_MODE or not password:
        password = os.environ.get(constants.ENV_RASA_X_PASSWORD)
        if not password:
            password = random_password()
            is_password_generated = True
        settings_service.save_community_user_password(password)

    user_service = UserService(session)
    user_service.insert_or_update_user(constants.COMMUNITY_USERNAME, password,
                                       constants.COMMUNITY_TEAM_NAME)

    if app:
        run_operation_in_single_sanic_worker(
            app, AppStartedCallable(password, is_password_generated))
예제 #3
0
    def update_role_users(
        self,
        role: Text,
        username_to_exclude: Text,
        users_to_update: List[Text],
        user_service: UserService,
    ) -> List[Dict[Text, Any]]:
        """Update all users associated with this role.

        Exclude user `username_to_exclude` from this operation. Returns a list of
        users associated with `role`.
        """

        # delete this role from all users
        for user in self.fetch_role_users(role):
            username = user["username"]

            # exclude `username_to_exclude`
            if username == username_to_exclude:
                continue

            user_service.delete_user_role(username, role)

        # add role to all users_to_update
        for username in users_to_update:

            # exclude `username_to_exclude`
            if username == username_to_exclude:
                continue

            existing_user = user_service.fetch_user(username)
            if existing_user:
                user_service.add_role_to_user(username, role)

        return self.fetch_role_users(role)
async def retrieve_user(
    request: Request,
    payload: Dict,
    allow_api_token: bool,
    extract_user_from_jwt: bool,
    *args: Any,
    **kwargs: Any,
) -> Optional[Dict]:
    if extract_user_from_jwt and payload and has_role(payload.get("user"),
                                                      GUEST):
        return payload["user"]

    user_service = UserService(request[REQUEST_DB_SESSION_KEY])

    if allow_api_token:
        api_token = rasa_x_utils.default_arg(request, "api_token")
        if api_token:
            return user_service.api_token_auth(api_token)

    if payload:
        username = payload.get("username", None)
        if username is not None:
            return user_service.fetch_user(username)
        else:
            # user is first-time enterprise user and has username None
            # in this case we'll fetch the profile using name_id
            name_id = payload.get("user", {}).get("name_id", None)
            return user_service.fetch_user(name_id)

    return None
    async def delete_user(request: Request, username: Text,
                          user: Dict) -> HTTPResponse:
        user_service = UserService(request[REQUEST_DB_SESSION_KEY])

        try:
            deleted = user_service.delete_user(
                username, requesting_user=user["username"])
            return response.json(deleted)
        except UserException as e:
            return rasa_x_utils.error(404, "UserDeletionError", e)
    async def change_password(request: Request) -> HTTPResponse:
        rjs = request.json
        user_service = UserService(request[REQUEST_DB_SESSION_KEY])

        try:
            user = user_service.change_password(rjs)
            if user is None:
                return rasa_x_utils.error(404, "UserNotFound",
                                          "user not found")
            return response.json(user)
        except MismatchedPasswordsException:
            return rasa_x_utils.error(403, "WrongPassword", "wrong password")
    async def create_user(request: Request) -> HTTPResponse:
        rjs = request.json
        user_service = UserService(request[REQUEST_DB_SESSION_KEY])
        team = rjs.get("team") or config.team_name
        user_service.create_user(
            username=rjs["username"],
            raw_password=rjs["password"],
            team=team,
            roles=rjs["roles"],
        )

        return response.json(rjs, 201)
def _create_system_user(session: Session) -> None:
    user_service = UserService(session)
    if user_service.fetch_user(rasa_x_config.SYSTEM_USER):
        logger.debug(
            f"Found existing system system user '{rasa_x_config.SYSTEM_USER}'."
        )
        return

    user_service.create_user(
        rasa_x_config.SYSTEM_USER, None, rasa_x_config.team_name, ADMIN
    )
    logger.debug(f"Created new system user '{rasa_x_config.SYSTEM_USER}'.")
    async def create_project(request: Request, project_id: Text,
                             user: Dict) -> HTTPResponse:
        settings_service = SettingsService(request[REQUEST_DB_SESSION_KEY])

        try:
            project = settings_service.init_project(user["team"], project_id)
        except ProjectException as e:
            return rasa_x_utils.error(404, "ProjectCreationError", details=e)

        user_service = UserService(request[REQUEST_DB_SESSION_KEY])
        user_service.assign_project_to_user(user, project_id)

        return response.json(project)
    async def list_users(request: Request) -> HTTPResponse:
        user_service = UserService(request[REQUEST_DB_SESSION_KEY])
        username_query = utils.default_arg(request, "username", None)
        role_query = utils.default_arg(request, "role", None)
        users = user_service.fetch_all_users(config.team_name, username_query,
                                             role_query)
        if not users:
            return rasa_x_utils.error(404, "NoUsersFound", "No users found")

        profiles = [user_service.fetch_user(u["username"]) for u in users]

        return response.json(profiles,
                             headers={"X-Total-Count": len(profiles)})
예제 #11
0
    def _update_role_name(self, new_name: Text, old_name: Text,
                          user_service: UserService) -> None:
        """Update the name of a role and move its users."""

        # a rename should preserve old description and its `is_default` status
        existing_role = self.get_role(old_name)
        self.save_role(new_name, existing_role.description,
                       existing_role.is_default)

        # move users with old role name to new role name
        users = self.fetch_role_users(old_name)
        for user in users:
            user_service.replace_user_roles(user["username"], [new_name])
        if old_name in self.roles:
            self.delete_role(old_name)
예제 #12
0
def initialise_services(_session):
    return (
        UserService(_session),
        SettingsService(_session),
        DomainService(_session),
        RoleService(_session),
    )
    async def update_username(request: Request, user: Dict) -> HTTPResponse:
        rjs = request.json

        try:
            user_service = UserService(request[REQUEST_DB_SESSION_KEY])
            user_profile = user_service.update_saml_username(
                user["name_id"], rjs["username"])

        except UserException as e:
            return rasa_x_utils.error(
                404,
                "UserException",
                "Could not assign username {} to name_id {}"
                "".format(rjs["username"], user["name_id"]),
                details=e,
            )

        return response.json(user_profile)
예제 #14
0
    def get_user_permissions(
        self,
        username: Text,
        user_service: UserService,
        project_id: Text = config.project_name,
    ) -> List[Text]:
        """Retrieve list of API permissions associated with `username`."""

        user = user_service.fetch_user(username)
        return self._permissions_for(user, project_id)
예제 #15
0
    def run_analytics_caching() -> None:
        import rasax.community.database.utils as database_utils

        with database_utils.session_scope() as session:
            # Use new session for all sql operations
            analytics_service = AnalyticsService(session)

            now = time.time()
            user_service = UserService(session)
            platform_users = user_service.fetch_all_users(config.team_name)
            platform_user_ids = [u["username"] for u in platform_users]

            for k, v in CACHED_ANALYTICS_CONFIG.items():
                window = rasa_x_utils.duration_to_seconds(v["window"])
                start = now - rasa_x_utils.duration_to_seconds(v["range"])

                for include_platform_users in [False, True]:
                    result = analytics_service.calculate_analytics(
                        start, now, window, platform_user_ids)
                    analytics_service._persist_analytics(
                        k, result, include_platform_users)
def _user_service(request: Request) -> UserService:
    return UserService(request[REQUEST_DB_SESSION_KEY])
 async def profile(request: Request, user: Dict) -> HTTPResponse:
     user_service = UserService(request[REQUEST_DB_SESSION_KEY])
     return response.json(
         user_service.fetch_user(user["username"], return_api_token=True))
        async def decorated_function(request, *args, **kwargs):
            user_service = UserService(request[REQUEST_DB_SESSION_KEY])

            if initialized_on and isinstance(initialized_on, Blueprint):
                instance = initialized_on
            else:
                instance = request.app

            with instant_config(instance, request=request, **kw):
                if request.method == "OPTIONS":
                    return await sanic_jwt_utils.call(f, request, *args, **kwargs)

                is_authenticated = False
                user_scopes = None
                reasons = None
                status = None

                if allow_rasa_x_token:
                    rasa_x_token = default_arg(request, "token", None)
                    if rasa_x_token == config.rasa_x_token:
                        return await await_and_return_response(args, kwargs, request)

                if allow_api_token:
                    # if decorator allows api_tokens for authentication
                    # skip the usual JWT authentication
                    api_token = default_arg(request, "api_token")
                    if api_token:
                        user = user_service.api_token_auth(api_token)
                        is_authenticated = True
                        status = 200
                        permissions = user["permissions"]
                        user_scopes = normalise_permissions(permissions)

                if not is_authenticated:
                    try:
                        (
                            is_authenticated,
                            status,
                            reasons,
                        ) = instance.auth._check_authentication(
                            request, request_args=args, request_kwargs=kwargs
                        )
                    except AttributeError:
                        raise exceptions.SanicJWTException(
                            "Authentication instance not found. Perhaps you "
                            "used @scoped without passing in a blueprint? "
                            "Try @scoped(..., initialized_on=blueprint)",
                            status_code=500,
                        )
                    except exceptions.SanicJWTException as e:
                        status = e.status_code
                        reasons = e.args[0]

                if is_authenticated:
                    is_authorized, reasons, status = await authorise_user(
                        args, kwargs, instance, reasons, request, status, user_scopes
                    )
                else:
                    is_authorized = False

                if is_authorized:
                    # the user is authorized.
                    # run the handler method and return the response
                    # NOTE: it's possible to use return await.utils(f, ...) in
                    # here, but inside the @protected decorator it wont work,
                    # so this is left as is for now
                    return await await_and_return_response(args, kwargs, request)

                else:
                    raise exceptions.Unauthorized(reasons, status_code=status)