예제 #1
0
파일: middlewares.py 프로젝트: ambrozic/dms
    async def authenticate(
        self, request: Request
    ) -> typing.Tuple[AuthCredentials, BaseUser]:

        auth = request.session.pop("auth", None)
        if auth:
            sun, spw = state.items.storage().split(":", 1)
            aun, apw = auth.split(":", 1)
            if sun and sun == aun and hasher.verify(apw, spw):
                request.session.update(user=hasher.hash(auth))
                messages.add(
                    request=request,
                    text="Logged in successfully",
                    type=messages.SUCCESS,
                )
                return AuthCredentials(scopes=["authenticated"]), SimpleUser("admin")
            messages.add(
                request=request, text="Invalid credentials", type=messages.DANGER
            )

        if "user" not in request.session:
            return AuthCredentials(scopes=["anonymous"]), UnauthenticatedUser()

        user = request.session["user"]
        if hasher.identify(user):
            return AuthCredentials(scopes=["authenticated"]), SimpleUser("admin")

        request.session.pop("user")
        return AuthCredentials(scopes=["anonymous"]), UnauthenticatedUser()
예제 #2
0
    async def authenticate(self, conn: HTTPConnection):
        if "Authorization" not in conn.headers:
            return AuthCredentials(), None

        auth_header = conn.headers["Authorization"]
        try:
            scheme, token = auth_header.split()
            if scheme.lower() != "bearer":
                return AuthCredentials(), None
        except Exception as error:
            raise AuthenticationError(
                "Invalid authentication credentials") from error

        try:
            payload: JWTPayloadSchema = TokensHandler.read_code(
                code=token, convert_to=JWTPayloadSchema)
            user_model: UserModel = await UsersHandler(
                request=conn).retrieve_user(request=conn,
                                            query={
                                                "_id": payload.object_id,
                                                "is_active": True
                                            })
        except HandlerException as error:
            raise AuthenticationError(str(error)) from error

        # request.auth, request.user
        return AuthCredentials(), user_model
예제 #3
0
    async def authenticate(self, request):
        from helpdesk.models.user import User
        from helpdesk.models.provider import get_provider
        from helpdesk.config import ENABLED_PROVIDERS, AUTH_UNSUPPORT_PROVIDERS
        logger.debug('request.session: %s, user: %s', request.session,
                     request.session.get('user'))

        for provider_type in ENABLED_PROVIDERS:
            if provider_type in AUTH_UNSUPPORT_PROVIDERS:
                continue
            if not all([
                    request.session.get('user'),
                    request.session.get(f'{provider_type}_token'),
                    request.session.get(f'{provider_type}_expiry')
            ]):
                logger.debug(f'{provider_type} auth error, unauth')
                return AuthCredentials([]), UnauthenticatedUser()
            # check token expiry, e.g. '2019-05-28T10:34:03.240708Z'
            expiry = request.session[f'{provider_type}_expiry']
            if datetime.strptime(expiry, "%Y-%m-%dT%H:%M:%S.%fZ"
                                 ) < datetime.utcnow() + timedelta(minutes=1):
                logger.debug('token expiry time is in 1 minute, unauth.')
                unauth(request)
                return AuthCredentials([]), UnauthenticatedUser()

        username = request.session['user']
        providers = {
            provider_type:
            get_provider(provider_type,
                         token=request.session.get(f'{provider_type}_token'),
                         user=username)
            for provider_type in ENABLED_PROVIDERS
        }
        user = User(username=username, providers=providers)
        return user.auth_credentials, user
예제 #4
0
파일: backends.py 프로젝트: scott2b/Webster
 async def authenticate(self, request):
     if 'user_id' in request.session:
         user_id = request.session['user_id']
         user = User.objects.get(user_id)
         creds = ['app_auth']
         if user.is_superuser:
             creds.append('admin_auth')
         if user.user_data and 'asUser' in user.user_data:
             if request.url.path == '/auth/logout':
                 data = copy.copy(user.user_data)
                 del data['asUser']
                 user.user_data = data
                 user.save()
             else:
                 spoof_user = User.objects.get_by_email(
                     user.user_data['asUser'])
                 return AuthCredentials(creds), spoof_user
         return AuthCredentials(creds), user
     if request.headers.get('authorization'):
         bearer = request.headers['authorization'].split()
         if bearer[0] != 'Bearer':
             return
         bearer = bearer[1]
         token = oauth2token.OAuth2Token.objects.get_by_access_token(bearer)
         if token is None or token.revoked:
             return  # return without authorization
         if datetime.datetime.utcnow() > token.access_token_expires_at:
             return  # return without authorization
         # passed all tests
         request.scope['token'] = token
         return AuthCredentials(['api_auth']), None
예제 #5
0
 async def authenticate(self, conn: HTTPConnection):
     user = self.get_user(conn)
     if user and user.is_authenticated:
         scopes = ["authenticated"] + sorted([str(s) for s in user.scopes])
         return AuthCredentials(scopes), user
     scopes = ["unauthenticated"]
     return AuthCredentials(scopes), UnauthenticatedUser()
예제 #6
0
 async def authenticate(self, request):
     from models import Token, User
     token = request.headers.get("Authorization")
     check = await Token.check_token(token)
     if check is None:
         return AuthCredentials(), CustomUnauthenticatedUser()
     user = await User.get(check.user_id)
     return AuthCredentials(["authenticated"]), user
예제 #7
0
    async def authenticate(self, request):
        user = self.get_user(request)

        if user and user.is_authenticated:
            scopes = ["authenticated"] + sorted([str(s) for s in user.scopes])
            return AuthCredentials(scopes), user

        scopes = ["unauthenticated"]
        return AuthCredentials(scopes), UnauthenticatedUser()
예제 #8
0
 async def authenticate(
     self, conn: HTTPConnection
 ) -> typing.Optional[typing.Tuple[AuthCredentials, BaseUser]]:
     secret = conn.headers.get("secret")
     if secret in _SCOPE_MAP:
         scopes = _SCOPE_MAP[secret]
         return AuthCredentials(scopes), SimpleUser("smith")
     else:
         return AuthCredentials(), UnauthenticatedUser()
예제 #9
0
 async def authenticate(self, conn: HTTPConnection):
     user = await self.get_user(conn)
     if user and user["is_active"]:
         used = await db.get_user_scopes(user["id"])
         return (
             AuthCredentials(["authenticated"] +
                             sorted([s["code"] for s in used])),
             ModelUser(user),
         )
     return AuthCredentials(["unauthenticated"]), UnauthenticatedUser()
예제 #10
0
    async def authenticate(self, request):
        session_id = request.cookies.get("session_id")
        if not session_id:
            return AuthCredentials(["unauthenticated"]), UnauthenticatedUser()

        user = User.get_by_session_id(session_id)
        if not user:
            return AuthCredentials(["unauthenticated"]), UnauthenticatedUser()

        return AuthCredentials(["authenticated"]), user
예제 #11
0
 async def authenticate(self, request: Request) -> Tuple[AuthCredentials, BaseUser]:
     try:
         identity = self.get_identity(request, type="access")
         log.info(f"Authenticating with {identity}")
         # We could check that we actually have a valid user here, but this doesn't
         # seem to be what other libraries tend to do.
         user = SimpleUser(identity)
         return (AuthCredentials(("admin",)), user)
     except AuthenticationError as err:
         return (AuthCredentials(("public",)), UnauthenticatedUser())
예제 #12
0
    async def authenticate(self, request):
        if self.headers.lower() not in request.headers:
            return AuthCredentials(), UnauthenticatedUser()

        auth = request.headers[self.headers]
        scheme, token = get_authorization_scheme_param(auth)
        if scheme.lower() != self.auth_type:
            return AuthCredentials(), UnauthenticatedUser()

        return self.verify_token(token)
예제 #13
0
    async def authenticate(self, request: Request):
        if request['method'] == 'GET' and \
                any((x.match(request.url.path) for x in self.allowed_patterns)):
            return AuthCredentials(['unauthenticated']), UnauthenticatedUser()

        host = request.headers.get('host')
        if 'local' in host or 'internal' in host or \
                '.' not in host:
            return AuthCredentials(['unauthenticated']), UnauthenticatedUser()

        elif self.id is None:
            # local dev
            username = '******'
            return AuthCredentials(['authenticated'
                                    ]), SimpleUser(username=username)

        elif request.url.path == '/oauth_callback/google':
            # handle redirect
            # print('sess', request.session)
            query = request.query_params
            state = query.get('state')
            code = query.get('code')

            gc = GoogleClient(client_id=self.id, client_secret=self.secret)
            host = get_hostname(request)
            if request.url.port:
                host += f':{request.url.port}'
            otoken, other = await gc.get_access_token(
                code, redirect_uri=f'{host}/oauth_callback/google')

            idt = other['id_token']
            id_token = jwt.decode(idt, verify=False)

            email = id_token.get('email')
            if not (id_token.get('hd') == self.org == email.split('@')[1]):
                return AuthenticationError('Bad user')

            timestamp = time.time()
            request.session['ts'] = timestamp
            request.session['user'] = email
            request.state.redirect_url = state
            raise RedirectAuthError('need to redirect')

        elif request.session and request.session.get('user'):
            # make sure cookie is still valid
            timestamp = request.session.get('ts')
            now = time.time()
            if now - timestamp > 86520:
                raise StartAuthError

            user = request.session.get('user')
            return AuthCredentials(['authenticated'
                                    ]), SimpleUser(username=user)
        else:
            raise StartAuthError('Not logged in')
예제 #14
0
 async def authenticate(self, r: HTTPConnection):
     session_id: Optional[str] = r.cookies.get('q_c0')
     if not session_id:
         return AuthCredentials(), User(id=0)
     credential = await credential_ctl.get_access_credential(session_id)
     if not credential or credential.is_expired:
         return AuthCredentials(), User(id=0)
     if credential.is_stale:
         await credential_ctl.refresh_access_credential(credential)
     return AuthCredentials(['login']), User(id=credential.member_id,
                                             access_token=session_id)
예제 #15
0
    async def authenticate(self, request):
        from helpdesk.models.user import User
        logger.debug('request.session: %s, user: %s', request.session, request.session.get('user'))
        userinfo = request.session.get('user')
        if not userinfo:
            return AuthCredentials([]), UnauthenticatedUser()

        try:
            user = User.from_json(userinfo)
            return user.auth_credentials, user
        except Exception:
            return AuthCredentials([]), UnauthenticatedUser()
예제 #16
0
    async def authenticate(self, conn: HTTPConnection):
        unauthenticated = (None, AnonymousUser())
        sid = conn.cookies.get("AURSID")
        if not sid:
            return unauthenticated

        timeout = aurweb.config.getint("options", "login_timeout")
        remembered = ("AURREMEMBER" in conn.cookies
                      and bool(conn.cookies.get("AURREMEMBER")))
        if remembered:
            timeout = aurweb.config.getint("options",
                                           "persistent_cookie_timeout")

        # If no session with sid and a LastUpdateTS now or later exists.
        now_ts = time.utcnow()
        record = db.query(Session).filter(Session.SessionID == sid).first()
        if not record:
            return unauthenticated
        elif record.LastUpdateTS < (now_ts - timeout):
            with db.begin():
                db.delete_all([record])
            return unauthenticated

        # At this point, we cannot have an invalid user if the record
        # exists, due to ForeignKey constraints in the schema upheld
        # by mysqlclient.
        with db.begin():
            user = db.query(User).filter(User.ID == record.UsersID).first()
        user.nonce = util.make_nonce()
        user.authenticated = True

        return (AuthCredentials(["authenticated"]), user)
예제 #17
0
    async def authenticate(self, request: HTTPConnection):
        if "discord_id" not in request.session:
            request.session.pop("user", None)
            return

        user = request.session.get("user")
        if not user:
            db_user = await DBUser.get(request.session["discord_id"])
            log.info("First time adding user info for %s, user: %s",
                     request.session["discord_id"], db_user)

            if db_user is None:
                log.info("User %s was not in the database, rejecting",
                         request.session["discord_id"])
                request.session.pop("discord_id", None)
                return
            user = {
                "discord_id": db_user.discord_id,
                "is_admin": db_user.is_admin,
                "username": db_user.username,
            }
            request.session["user"] = user

        username, discord_id, is_admin = (
            user["username"],
            user["discord_id"],
            user["is_admin"],
        )

        creds = ["authenticated"]
        if is_admin:
            creds.append("admin")

        return AuthCredentials(creds), User(username, discord_id, is_admin)
예제 #18
0
    async def authenticate(self, conn: HTTPConnection):
        payload = getattr(conn.state, "payload", None)
        if not payload:
            return

        username = payload.get("username")
        if not username:
            return

        try:
            session = conn.state.session
        except AttributeError:
            raise RuntimeError(
                "Missing session: try adding SessionMiddleware.")

        if self.user_cls:
            user = await run_in_threadpool(self.user_cls.get_by_username,
                                           session, username)
            if not user:
                logger.warning("User not found: %s", username)
                return
        else:
            user = SimpleUser(username=username)

        scopes = await self.scopes(payload)
        return AuthCredentials(scopes), user
예제 #19
0
    async def authenticate(
            self,
            conn: HTTPConnection) -> Optional[Tuple[AuthCredentials, User]]:
        if 'token' in conn.cookies:
            token = json.loads(conn.cookies.get('token'))
            user = json.loads(conn.cookies.get('user'))

            expires_at = datetime.utcfromtimestamp(token['expires_at'])
            refresh_token = token['refresh_token']
            now = datetime.now()

            # Check token expiration
            if expires_at > now:
                token, user = await self._refresh_access_token(refresh_token)
                self._update_auth_cookies(conn, token, user)
            self._add_data_to_session(conn, token, user)

            # Check user in database
            user_model = await self._check_user_in_db(user)

            # Store token and user in global context
            conn.scope['user'] = user
            conn.scope['token'] = token

            return AuthCredentials(['authenticated']), user_model
        return
예제 #20
0
    async def authenticate(self, request):
        if 'Authorization' not in request.headers:
            return

        auth = request.headers['Authorization']
        try:
            scheme, credentials = auth.split()
            if scheme.lower() != 'basic':
                return
            decoded = base64.b64decode(credentials).decode("ascii")
        except (ValueError, UnicodeDecodeError, binascii.Error):
            raise AuthenticationError('Invalid basic auth credentials')

        pseudo, _, password = decoded.partition(':')
        db = get_session(DATABASE_URL)
        user = db.query(User).filter(User.pseudo == pseudo).one_or_none()
        if user is None or not user.check_password(password):
            db.close()
            raise AuthenticationError(f'pseudo or password incorrect')

        user.is_authenticated = True
        scopes = ['authenticated']
        for group in user.groups:
            scopes.extend([permission.name for permission in group.permissions])
        db.close()
        return AuthCredentials(scopes), user
예제 #21
0
    async def authenticate(self, request: HTTPConnection):
        if "discord_id" not in request.session:
            request.session.pop("user", None)
            return

        user = request.session.get("user")
        if not user:
            uid = request.session["discord_id"]

            if uid not in settings.LADS:
                return
            user = {
                "discord_id": uid,
                "username": request.session["discord_username"],
            }
            request.session["user"] = user

        username, discord_id = (
            user["username"],
            user["discord_id"],
        )

        creds = ["authenticated"]

        return AuthCredentials(creds), User(username, discord_id)
예제 #22
0
파일: auth.py 프로젝트: rednap/apitoolbox
    async def authenticate(
        self, conn: HTTPConnection
    ) -> Optional[Tuple["AuthCredentials", "BaseUser"]]:
        try:
            payload = conn.state.payload
        except AttributeError:
            raise RuntimeError(
                "Missing 'request.state.payload': "
                "try adding 'middleware.UpstreamPayloadMiddleware'")

        username = payload.get("username")
        if not username:
            return

        if self.user_cls:
            try:
                session = conn.state.session
            except AttributeError:
                raise RuntimeError("Missing 'request.state.session': "
                                   "try adding 'middleware.SessionMiddleware'")

            user = await run_in_threadpool(self.user_cls.get_by_username,
                                           session, username)
            if not user:
                logger.warning("User not found: %s", username)
                return
        else:
            user = SimpleUser(username=username)

        scopes = await self.scopes(payload)
        return AuthCredentials(scopes), user
예제 #23
0
 async def authenticate(
         self, request: HTTPConnection
 ) -> tuple[AuthCredentials, SimpleUser] | None:
     """Authenticate a Starlette request with HTTP Basic auth."""
     if "Authorization" not in request.headers:
         return None
     try:
         auth = request.headers["Authorization"]
         basic_auth_username = os.getenv("BASIC_AUTH_USERNAME")
         basic_auth_password = os.getenv("BASIC_AUTH_PASSWORD")
         if not (basic_auth_username and basic_auth_password):
             raise AuthenticationError(
                 "Server HTTP Basic auth credentials not set")
         scheme, credentials = auth.split()
         decoded = base64.b64decode(credentials).decode("ascii")
         username, _, password = decoded.partition(":")
         correct_username = secrets.compare_digest(username,
                                                   basic_auth_username)
         correct_password = secrets.compare_digest(password,
                                                   basic_auth_password)
         if not (correct_username and correct_password):
             raise AuthenticationError(
                 "HTTP Basic auth credentials not correct")
         return AuthCredentials(["authenticated"]), SimpleUser(username)
     except Exception:
         raise
예제 #24
0
    async def authenticate(self, request):
        if request.url.path != "/pretix-webhook":
            raise ValueError("PretixAuthBackend used outside pretix-webhook")

        if "Authorization" not in request.headers:
            return

        auth = request.headers["Authorization"]
        try:
            scheme, credentials = auth.split()
            if scheme.lower() != "basic":
                return
            decoded = base64.b64decode(credentials).decode("ascii")
        except (ValueError, UnicodeDecodeError, binascii.Error) as exc:
            raise AuthenticationError(
                "Invalid basic auth credentials") from exc

        username, _, password = decoded.partition(":")
        if username != "pretix":
            raise AuthenticationError("Invalid auth")

        if password != str(PRETIX_WEBHOOK_SECRET):
            raise AuthenticationError("Invalid auth")

        return AuthCredentials(["authenticated",
                                "pretix"]), SimpleUser("pretix")
예제 #25
0
 async def authenticate(
     self, request: HTTPConnection
 ) -> typing.Optional[typing.Tuple[AuthCredentials, BaseUser]]:
     resource_protector = OurResourceProtector(
         [BearerTokenValidator(self.now, request.app.state.jwt_config)])
     try:
         token_wrap = resource_protector.validate_request(
             HttpRequest(request))
         user = await async_(
             session.query(User).join(
                 Client, User.pool_id == Client.pool_id).filter(
                     Client.oauth2_client_id == token_wrap.get_client_id(),
                     User.key == token_wrap.get_subject(),
                 ).one)()
         return (
             AuthCredentials(list(set(token_wrap.get_scope().split(None)))),
             StarletteUserWrapper(user),
         )
     except (
             ExpiredTokenError,
             InvalidTokenError,
             MissingAuthorizationError,
             UnsupportedTokenTypeError,
             orm_exc.NoResultFound,
     ) as e:
         logger.debug(str(e), exc_info=True)
         return None
예제 #26
0
    async def authenticate(self, request):

        if "Authorization" not in request.headers:
            return None

        authorization = request.headers["Authorization"]
        token = self.get_token_from_header(authorization=authorization,
                                           prefix=self.prefix)

        try:
            jwt_payload = jwt.decode(token,
                                     key=str(self.secret_key),
                                     algorithms=self.algorithm)
        except jwt.InvalidTokenError:
            if DEBUG:
                sprint_f(f"Invalid JWT token", "red")
            raise AuthenticationError("Invalid JWT token")
        except jwt.ExpiredSignatureError:
            if DEBUG:
                sprint_f(f"Expired JWT token", "red")
            raise AuthenticationError("Expired JWT token")

        if DEBUG:
            sprint_f(f"Decoded JWT payload: {jwt_payload}",
                     "green")  # debug part, do not forget to remove it

        return (
            AuthCredentials(["authenticated"]),
            JWTUser(username=jwt_payload["username"],
                    user_id=jwt_payload["user_id"],
                    email=jwt_payload["email"],
                    token=token),
        )
예제 #27
0
    async def authenticate(
            self, request: HTTPConnection
    ) -> Optional[Tuple[AuthCredentials, BaseUser]]:
        """Authenticate the user."""
        if "Authorization" not in request.headers:
            return

        authorization_header = request.headers["Authorization"]
        if not authorization_header.startswith("Bearer "):
            logger.info(msg=f"Invalid Authorization header sent by user")
            raise AuthenticationError(
                "Invalid Authorization header value. The header "
                "value must have the format Bearer <token>.")

        user_token = request.headers["Authorization"][
            7:]  # length of "Bearer " is 7
        try:
            payload = parse_token(user_token)
        except Exception:
            logger.exception(msg=f"Invalid or expired authentication token.")
            raise AuthenticationError(
                "Invalid or expired authentication token.")

        user = await user_repository.find_user_by_id(int(payload.user_id))

        if not user:
            logger.error(msg=f"No user found for id {payload.user_id}.")
            raise AuthenticationError("No user found for user id.")

        return AuthCredentials(["authenticated"]), AuthenticatedUser(user)
예제 #28
0
    async def authenticate(self, request):
        """
        Hàm dùng cho việc xác thực Http Request từ client

        :param request: HTTP request từ client
        :return: authenticated và JWTUser
        """

        if 'Authorization' not in request.headers:
            return None

        auth = request.headers['Authorization']
        token = self.get_token_from_header(authorization=auth,
                                           prefix=self.prefix)

        try:
            payload = self.decode_token(token)
        except jwt.InvalidTokenError:
            raise AuthenticationError('error: Token không hợp lệ!')
        else:
            # Kiểm tra xem Token có nằm trong danh sách blacklist Token hay không
            # ** blacklist Token là file chứa danh sách các token đã logout hoặc đã bị vô hiệu hóa
            with open('security.txt', 'r') as reader:
                modify_token_for_check = token + '\n'
                if modify_token_for_check in reader.readlines():
                    raise AuthenticationError(
                        'error: Token đã bị vô hiệu hoá!')
                else:
                    return AuthCredentials(
                        ['authenticated']), JWTUser(user_id=payload['userId'])
예제 #29
0
    async def authenticate(
        self, conn: HTTPConnection
    ) -> Tuple[AuthCredentials, BaseUser]:
        """ Perform authentication using a shared token or oauth """
        roles: List[str] = []

        # See if there is a logged in user and what roles they have
        await validate_refresh_token(conn)
        roles.extend(parse_scopes(conn))
        username = conn.session.get("user", {}).get("username")

        # See if the correct token has been passed as a query param
        if (
            self.token is None
            or conn.query_params.get("token") == self.token.get_secret_value()
        ):
            if not username:
                username = "******"
            roles.append("backend")

        credentials = AuthCredentials(roles)
        if username:
            return credentials, SimpleUser(username)

        return credentials, UnauthenticatedUser()
예제 #30
0
    async def authenticate(
            self, request: Request) -> Tuple[AuthCredentials, SimpleUser]:
        if 'Authorization' not in request.headers:
            raise AuthenticationError('Please, authenticate')

        auth = request.headers['Authorization']
        try:
            scheme, credentials = auth.split()
        except ValueError:
            raise AuthenticationError('Invalid basic auth credentials')

        if scheme.lower() != 'basic':
            raise AuthenticationError('Please, use basic authentication')

        try:
            decoded = base64.b64decode(credentials).decode('ascii')
        except (binascii.Error, UnicodeDecodeError, ValueError):
            raise AuthenticationError('Invalid basic auth credentials')

        username, _, token = decoded.partition(':')
        if username != '__token__':
            raise AuthenticationError(
                'Incorrect username. Only token are allowed. Please, set username to __token__'
            )

        token_response: AccessSecretVersionResponse = await sync_to_async(
            self.client.access_secret_version)(request={
                'name': TOKEN_NAME
            })
        token_response_data: str = token_response.payload.data.decode()
        auth_tokens: Set[str] = set(token_response_data.split())

        if token not in auth_tokens:
            raise AuthenticationError('Incorrect token')
        return AuthCredentials(['authenticated']), SimpleUser(username)