Ejemplo n.º 1
0
async def create_story(
        story: schemas.StoryCreate,
        request: Request,
        db: Session = Depends(get_db),
):
    token_data = await main.get_token_if_present(request)

    user = main.get_user_from_token(db, token_data)
    story_to_update = main.get_existing_story(user, token_data, db)

    if story_to_update:
        db_story = crud.update_story(db, story_to_update, story)
    else:
        db_story = crud.create_story(db=db, story=story, user=user)

    jsonStory = jsonable_encoder(schemas.Story.from_orm(db_story))

    # prepare response
    response = JSONResponse(jsonStory, status_code=200)
    if not token_data:
        access_token = main.create_access_token(data={"story_id": db_story.id})
        response.set_cookie(
            "Authorization",
            value=f"Bearer {access_token}",
            httponly=True,
        )
    return response
Ejemplo n.º 2
0
async def check_in(commander_check_in: CommanderCheckIn):
    """
    Post your name to receive key to control room
    """
    name = unidecode(commander_check_in.name)
    if name not in [c.name for c in commanders]:
        commander = Commander(name)
        commanders.append(commander)
        reactors.append(ReactorCore(commander.uuid))
        content = {
            "message":
            f"Take the key to your control room. "
            f"Keep it safe. use it as resource path to check on your RMBK-100 reactor! "
            "Use following: /{key}/control_room to gain knowledge how to operate reactor. "
            "You may see if the core is intact here: /{key}/reactor_core . "
            "If anything goes wrong push AZ-5 safety button to put all control rods in place!"
            "Good luck Commander.",
            "key":
            f"{commander.uuid}"
        }
        response = JSONResponse(status_code=status.HTTP_201_CREATED,
                                content=content)
        response.set_cookie(
            "secret_documentation",
            "Reactor will blow up if it is poisoned, overpowered and you press AZ5"
            f"${{flag_keeper_of_secrets_{commander.name}}}")
        return response
    else:

        return JSONResponse(
            status_code=422,
            content={
                "message":
                "A spy?! That Power Plant Tech Commander has already checked in!"
            })
Ejemplo n.º 3
0
async def login_for_access_token(
        request: Request,
        form_data: OAuth2PasswordRequestForm = Depends(),
        db: Session = Depends(get_db),
):
    token_data = await main.get_token_if_present(request)
    user = crud.authenticate_user(form_data.username, form_data.password,
                                  token_data, db)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect email or password",
            headers={"WWW-Authenticate": "Bearer"},
        )

    access_token = main.create_access_token(data={"email": user.email})
    response = JSONResponse({}, status_code=200)
    response.set_cookie(
        "Authorization",
        value=f"Bearer {access_token}",
        httponly=True,
        # max_age=os.environ["COOKIE_EXPIRATION_SECONDS"],
        # expires=os.environ["COOKIE_EXPIRATION_SECONDS"],
    )
    return response
Ejemplo n.º 4
0
async def bookmark(request: Request):
    if not request.session.get("user"):
        raise HTTPException(404)

    resource_id = request.path_params.get("resource_id")
    user = request.session["user"]
    bookmarks = user.get("bookmarks") or []

    if request.method == "DELETE":

        if resource_id not in bookmarks:
            return JSONResponse({"error": "Materialet var ikke bogmærket"})

        # update db
        # bookmark = {"user_id": user["openid"], "resource_id": resource_id}
        # await queries.delete_bookmark(bookmark)

        # update session
        bookmarks.remove(resource_id)
        user["bookmarks"] = bookmarks

        # generate response
        response = JSONResponse({"msg": "Bogmærke fjernet"})
        response.set_cookie("user", user)
        return response
Ejemplo n.º 5
0
async def login(
	response: JSONResponse,
	internal_user: str = Depends(auth_token_scheme)
) -> JSONResponse:
	""" Login endpoint for authenticating a user after he has received
		an authentication token. If the token is valid it generates
		an access token and inserts it in a HTTPOnly cookie.

		Args:
			internal_auth_token: Internal authentication token

		Returns:
			response: A JSON response with the status of the user's session
	"""
	async with exception_handling():
		access_token = await auth_util.create_internal_access_token(
			InternalAccessTokenData(
				sub=internal_user.internal_sub_id,
			)
		)

		response = JSONResponse(
			content=jsonable_encoder({
				"userLoggedIn": True,
				"userName": internal_user.username,
			}),
		)

		# Make this a secure cookie for production use
		response.set_cookie(key="access_token", value=f"Bearer {access_token}", httponly=True)

		return response
Ejemplo n.º 6
0
async def searches(request: Request):
    if not request.session.get("user"):
        raise HTTPException(404)

    user = request.session["user"]
    searches = user.get("searches", [])

    if request.method == "GET":
        context = {"request": request, "user": user}
        # searches = await queries.get_searches(user["openid"])
        if searches:
            context["searches"] = searches
        return render("users/searches.html", context)

    if request.method == "POST":
        search = await request.json()
        url = search.get("url")
        if not url:
            return JSONResponse({"error": "Manglende søgestreng"})

        if url in searches:
            return JSONResponse({"error": "Søgningen var allerede gemt"})

        # update db
        # search = {"user_id": user["openid"], "url": url, "description": search.get("description")}
        # await queries.insert_search(search)

        # update session
        user["searches"] = searches.extend(url)

        # generate response
        response = JSONResponse({"msg": "Søgning gemt"})
        response.set_cookie("user", user)
        return response
Ejemplo n.º 7
0
async def authenticate(form_data: OAuth2PasswordRequestForm = Depends()):
    """Verify login details and issue JWT in httpOnly cookie.

    Raises:
        HTTPException: 401 error if username or password are not recognised.
    """
    user = _USER_DB.get(form_data.username)
    if user["password"] != form_data.password:
        raise HTTPException(status_code=401,
                            detail="Incorrect email or password")
    data = {
        "user": form_data.username,
        "user_id": user["user_id"],
        "scopes": user["scopes"],
    }
    issued_at = datetime.utcnow()
    expire = issued_at + timedelta(minutes=15)
    data.update({"exp": expire, "iat": issued_at, "sub": "jwt-cookies-test"})
    encoded_jwt = jwt.encode(data, "i am a secret",
                             algorithm="HS256").decode("utf-8")
    response = JSONResponse({"status": "authenticated"})
    # NOTE: we should also set secure=True to mark this as a `secure` cookie
    # https://tools.ietf.org/html/rfc6265#section-4.1.2.5
    response.set_cookie(oauth2_scheme.token_name, encoded_jwt, httponly=True)
    return response
Ejemplo n.º 8
0
async def google_login_auth(request):
    token = await oauth.google.authorize_access_token(request)
    user = await oauth.google.parse_id_token(request, token)

    if not user["email_verified"]:
        return JSONResponse({"error": "Email not verified"}, status_code=400)

    email = user["email"]
    user = await services.social_login(
        SocialLoginInput(
            email=email,
            social_account=SocialAccount(
                social_id=user["sub"],
                fullname=user["name"],
                first_name=user["given_name"],
                last_name=user["family_name"],
            ),
        ),
        users_repository=request.state.users_repository,
    )

    # response = RedirectResponse(url="/")
    # Temporary
    response = JSONResponse({"ok": True})
    response.set_cookie(
        SOCIAL_LOGIN_JWT_COOKIE_NAME, json.dumps({"jwt": user.generate_token()})
    )
    return response
Ejemplo n.º 9
0
async def login_for_access_token(login_data: LoginParam,
                                 db: Session = Depends(deps.get_db)):
    user = crud.user.authenticate_user(db, login_data.login,
                                       login_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )

    access_token = crud.user.create_access_token(data={
        "sub": user.login,
    })

    response = JSONResponse(content={"details": "ok"})
    response.set_cookie(settings.access_token_cookie_name,
                        access_token,
                        max_age=settings.token_expire_minutes * 60,
                        secure=settings.secure_cookie,
                        httponly=True,
                        samesite="strict")

    csrf_token = secrets.token_hex(12)
    response.set_cookie(settings.csrf_token_cookie_name,
                        csrf_token,
                        max_age=settings.token_expire_minutes * 60,
                        secure=settings.secure_cookie,
                        httponly=False,
                        samesite="strict")
    return response
Ejemplo n.º 10
0
    def format_response(self,
                        user: User,
                        token: str,
                        status_code: int = HTTP_200_OK):
        schema = UserSchema()

        user_data = schema.dump(user)

        response = JSONResponse(
            {
                "success": True,
                "result": user_data,
                "token": token
            },
            status_code=status_code,
        )
        response.set_cookie(
            AUTH_COOKIE_NAME,
            token,
            expires=settings.AUTH_EXPIRES,
            path=settings.COOKIE_PATH,
            domain=settings.APP_DOMAIN,
            secure=not settings.DEBUG,
            httponly=True,
        )

        return response
Ejemplo n.º 11
0
def create_new_user(token: str, database: Session):
    new_user_id = "".join(
        random.choices(string.ascii_letters + string.digits, k=32))
    crud.create_user(
        database, schemas.UserCreate(access_token=token, user_id=new_user_id))
    content = {"message": "OK"}
    response = JSONResponse(content=content)
    response.set_cookie(key="user_id", value=new_user_id)
    return response
Ejemplo n.º 12
0
async def signin(request):
    if request.method == "GET":
        return home(request)
    if request.method == "POST":
        data = await request.json()
        message, status, session_id = await Auth.LoginUser.execute(data)
        response = JSONResponse(message, status)
        response.set_cookie('session_id', session_id)
        return response
async def route_login_and_set_cookie(api_key: APIKey = Depends(get_api_key)):
    response = JSONResponse({"you are authenticated": "yes you are"})
    response.set_cookie(
        API_KEY_NAME,
        value=api_key,
        domain=COOKIE_DOMAIN,
        httponly=True,
        max_age=1800,
        expires=1800,
    )
    return response
Ejemplo n.º 14
0
async def login_check(req):
    data = await req.json()
    username = data.get("username")
    password = data.get("password")

    if not username:
        return JSONResponse({"retcode": 1, "stderr": "用户名不能为空"})
    if not password:
        return JSONResponse({"retcode": 1, "stderr": "密码不能为空"})

    username = username.strip()
    password = password.strip()

    if username == config_info("username") and password == config_info(
            "password"):

        # 审计记录
        await audit_record(event=f"{username}登陆",
                           event_type="login",
                           level=1,
                           timestamp=time.strftime("%Y-%m-%d %H:%M:%S"))

        # session: key=hash(username), value=hash(user-agent, 客户端的浏览器环境)
        user_agent = "user-agent-default"
        headers = req.scope.get("headers")
        if isinstance(headers, (list, )):
            for k, v in headers:
                if k == "user-agent":
                    user_agent = v

        username_hash = hmac_salt(SALT, username)
        SESSION.setex(key=username_hash,
                      value=hmac_salt(SALT, user_agent),
                      ttl=EXPIRE)

        resp = JSONResponse({"retcode": 0, "stdout": "/"})

        # cookies: key=uid, value=hash(username)
        resp.set_cookie(
            key="uid",
            value=username_hash,
            max_age=EXPIRE,
            expires=EXPIRE,
            path="/",
            domain=None,
            # 只允许在https访问
            secure=False,
            # 防止xss
            httponly=True,
        )
        return resp
    return JSONResponse({"retcode": 1, "stderr": "用户信息校验失败"})
Ejemplo n.º 15
0
async def get_login(api_key: APIKey = Depends(get_api_key)):
    content = {"message": "Logged In Successfully!"}
    response = JSONResponse(content=content)

    response.set_cookie(
        API_KEY_NAME,
        value=api_key,
        domain=COOKIE_DOMAIN,
        httponly=True,
        max_age=1800,
        expires=1800,
    )
    return response
Ejemplo n.º 16
0
async def login(request: Request = None, db: Session = Depends(get_db)):
    token = await create_access_token(request, db)
    response = JSONResponse({"access_token": token, "token_type": "bearer"})

    response.set_cookie(
        key=COOKIE_AUTHORIZATION_NAME,
        value=f"Bearer {token}",
        domain=COOKIE_DOMAIN,
        httponly=True,
        max_age=1800,
        expires=1800,
    )
    return response
Ejemplo n.º 17
0
async def csrf(request):  # pylint: disable=unused-argument
    """CSRF route.
    Set the CSRF cookie and return a `JSONResponse with the token`.

    We need this REST endpoint to protect against CSRF because all GraphQL queries use POST method,
    so they are not safe to transmit the token.
    """
    token = get_new_token()
    response = JSONResponse({"csrftoken": token})
    response.set_cookie(
        settings.CSRF_COOKIE_NAME,
        token,
        httponly=settings.CSRF_COOKIE_HTTPONLY,
        secure=settings.CSRF_COOKIE_SECURE,
    )
    return response
Ejemplo n.º 18
0
async def check_user_and_make_token(request: Request,
                                    db: Session = Depends(get_db)):
    formdata = await request.form()
    print(request)
    print(formdata)
    print("the scopes are .......")
    #print(formdata.scopes)
    print(formdata["username"], formdata["password"])
    authenticated_user = authenticate_user(db, formdata["username"],
                                           formdata["password"])
    print(authenticated_user)
    if authenticated_user is None:
        raise HTTPException(status_code=401,
                            detail="Invalid username or password")

    access_token_expires = timedelta(hours=ACCESS_TOKEN_EXPIRE_HOURS)
    log_info(logging, authenticated_user.email)

    user_scope = authenticated_user.position  # if isinstance(authenticated_user.position, list) else [authenticated_user.position]
    print("the user scope is........")
    print(user_scope)
    access_token = create_access_token(data={
        "sub": authenticated_user.email,
        "scopes": user_scope
    },
                                       expires_delta=access_token_expires)

    #################### SUCCESSFULLY LOGED IN USING CUSTOM DETAILS ######################
    #crud.logged_in(authenticated_user.id,"custom",request)

    token = jsonable_encoder(access_token)
    print("token is----------------------")
    print(token)
    response = JSONResponse({"access_token": token, "token_type": "bearer"})

    response.set_cookie(
        key=COOKIE_AUTHORIZATION_NAME,
        value=f"Bearer {token}",
        domain=COOKIE_DOMAIN,
        httponly=True,
        max_age=10800,  # 3 hours
        expires=10800,  # 3 hours
    )
    print(response.__dict__)
    return response
Ejemplo n.º 19
0
def login(user_registration: UserRegistration):
    user = User(user_registration.username, user_registration.password)
    cookie = None
    if user in USERS:
        content = {"message": f"Welcome, {user.username}, in the Primer!"}
        status_code = status.HTTP_202_ACCEPTED
        cookie = {
            "key": "session",
            "value": "${{flag_{user.uuid}_may_the_4th_b_with_u}}"
        }
    else:
        content = {
            "message": f"Failed to login. Wrong username or password.",
            "flag": "${flag_naughty_aint_ya}"
        }
        status_code = status.HTTP_401_UNAUTHORIZED
    response = JSONResponse(content=content, status_code=status_code)
    if cookie:
        response.set_cookie(**cookie)
    return response
Ejemplo n.º 20
0
    async def on_post(self,
                      session: models.Session,
                      username: str,
                      password: str,
                      location: str = None,
                      **kwargs) -> Union[HTMLResponse, JSONResponse]:
        """ Handle POST requests """
        user_data = await self.authenticate(session,
                                            username=username,
                                            password=password,
                                            **kwargs)
        if not user_data:
            # ref: OWASP
            error = "Login failed; Invalid userID or password"
            html = await run_in_threadpool(self.render,
                                           username=username,
                                           error=error)
            return HTMLResponse(content=html,
                                status_code=self.error_status_code)

        result = await self.payload(user_data)

        expiry = tz.utcnow() + tz.timedelta(seconds=self.token_expiry)

        # jwt_encode will convert this to an epoch inside the token
        result["exp"] = expiry

        token = await self.jwt_encode(result)
        result["token"] = token
        result["exp"] = expiry.isoformat()

        headers = {"location": location or self.location}
        response = JSONResponse(content=result,
                                status_code=303,
                                headers=headers)
        response.set_cookie(self.cookie_name,
                            token,
                            path="/",
                            expires=int(expiry.timestamp()),
                            secure=self.secure)
        return response
Ejemplo n.º 21
0
async def external_login(
        request: Request,
        form_data: OAuth2PasswordRequestForm = Depends(),
        db: Session = Depends(get_db),
):
    user = crud.get_user_by_email(db, email=form_data.username)

    if not user:
        new_user = schemas.UserCreate(email=form_data.username, password="")
        user = crud.create_user(db=db, user=new_user)

    access_token = main.create_access_token(data={"email": user.email})
    response = JSONResponse({}, status_code=200)
    response.set_cookie(
        "Authorization",
        value=f"Bearer {access_token}",
        httponly=True,
        # max_age=os.environ["COOKIE_EXPIRATION_SECONDS"],
        # expires=os.environ["COOKIE_EXPIRATION_SECONDS"],
    )
    return response
Ejemplo n.º 22
0
def create_cookie(user):
    # session flag
    is_found = False

    # create session value for login user
    session_str = user['username'] + user['search_engine']
    hashed_session = pbkdf2_sha256.hash(session_str)

    data = {'username': user['username'], 'session': hashed_session}

    # check if session is created for the user
    with open('session.txt', 'r') as session_file:
        sessions = session_file.readlines()

        for session in sessions:
            # convert str to json obj
            session_obj = json.loads(session)
            if (user['username'] in session_obj['username']):
                is_found = True
                break

    # write session info to a text file if not found
    if not is_found:
        with open('session.txt', 'a') as session_file:
            json.dump(data, session_file)
            session_file.write('\n')

    content = {'detail': 'Login success'}

    response = JSONResponse(content=content, status_code=200)

    # session cookie settings
    response.set_cookie(
        key=user['username'],
        value=hashed_session,
        secure=True,
        max_age=1800,
        expires=1800,
    )
    return response
Ejemplo n.º 23
0
async def login(request: Request) -> JSONResponse:
    """Login user and save him into a session.

    :return: {"success": bool}.
    :rtype: JSONResponse
    """
    try:
        params = await request.json()
        auth = Authenticator(MONGO)
        try:
            user_info = auth.login_user(params["login"], params["password"])
            if user_info["success"]:
                response = JSONResponse(user_info)
                response.set_cookie("user_token", str(user_info["token"]))
                response.set_cookie("user_id", str(user_info["id"]))
                response.set_cookie("username", str(user_info["username"]))
                return response
            return JSONResponse({
                "success": False,
                "username": user_info["username"],
                "userID": user_info["id"],
            })
        except ValueError as err:
            logger.exception(err)
    except JSONDecodeError as err:
        logger.exception(err)
Ejemplo n.º 24
0
async def login_user(request):
    # TODO: oauth2-jwt: https://fastapi.tiangolo.com/tutorial/security/oauth2-jwt/
    #                   Is data signed?
    try:
        session = Session()
        token = session.query(Tokens).filter_by(
            idUser=request.user.id).one_or_none()
        session.commit()
    except exc.SQLAlchemyError:
        return JSONResponse({
            "message": "Database failure",
            "code": "1"
        },
                            status_code=404)

    if not token:
        try:
            session = Session()
            token = Tokens(idUser=request.user.id, )
            session.add(token)
            session.commit()
        except exc.SQLAlchemyError:
            return JSONResponse(
                {
                    "message": "Failed to generate token",
                    "code": "1"
                },
                status_code=409)

    response = JSONResponse({"message": "success"}, status_code=201)
    response.set_cookie(
        key="token",
        value=token.token,
        max_age=300,
        path="/",
        secure=True,  # assert it's only valid through SSL/HTTPS
        samesite="strict",
    )
    return response
Ejemplo n.º 25
0
async def bookmarks(request: Request):
    user = request.session["user"]
    if not user:
        raise HTTPException(404)

    bookmarks = user.get("bookmarks") or []

    if request.method == "GET":
        context = {"request": request, "user": user}
        if bookmarks:
            context["bookmarks"] = bookmarks
            # fetch full records
            # context["bookmarks"] = await api.get_records(id_list=bookmarks)
        return render("users/bookmarks.html", context)

    if request.method == "POST":
        bookmark = await request.json()
        resource_id = bookmark.get("resource_id")

        if not resource_id:
            return JSONResponse({"error": "Manglende materialeID"})

        if resource_id in bookmarks:
            return JSONResponse({"error": "Materialet var allerede bogmærket"})

        # update db
        # bookmark = {"user_id": user["openid"], "resource_id": resource_id}
        # await queries.insert_bookmark(bookmark)

        # update session
        user["bookmarks"] = bookmarks.extend(resource_id)

        # generate response
        response = JSONResponse({"msg": "Bogmærke tilføjet"})
        response.set_cookie("user", user)
        return response
Ejemplo n.º 26
0
async def post_auth(request: Request,
                    watchdog_auth: str = Cookie(''),
                    redirect: str = '/'):
    # two scene for set new password, update new password if has password, else return the html
    # 1. not set watchdog_auth; 2. already authenticated
    password = loads(await request.body())['password']
    auth_not_set = not Config.watchdog_auth
    already_authed = watchdog_auth and watchdog_auth == Config.watchdog_auth
    need_new_pwd = auth_not_set or already_authed
    if password:
        if need_new_pwd:
            old_password = Config.password
            Config.password = password
            await refresh_token()
            resp = JSONResponse({'ok': True, 'redirect': redirect})
            resp.set_cookie('watchdog_auth',
                            Config.watchdog_auth,
                            max_age=Config.cookie_max_age,
                            httponly=True)
            logger.warning(
                f'password changed {old_password}->{Config.password}.')
            return resp
        elif (await md5_checker(password, Config.watchdog_auth, freq=True)):
            resp = JSONResponse({'ok': True, 'redirect': redirect})
            resp.set_cookie('watchdog_auth',
                            Config.watchdog_auth,
                            max_age=Config.cookie_max_age,
                            httponly=True)
            logger.info('correct password, login success.')
            return resp
    # invalid password, clear cookie
    resp = JSONResponse({'ok': False})
    # resp.set_cookie('watchdog_auth', '')
    resp.delete_cookie('watchdog_auth')
    logger.info(f'invalid password: {password}')
    return resp
Ejemplo n.º 27
0
async def encrypted_message(
        credentials: HTTPBasicCredentials = Depends(security)):
    if has_credentials(credentials):
        user = User(credentials.username, credentials.password)
        if not MESSAGES.get(user.uuid):
            flag = f"${{flag_agency_decryptor_{user.uuid}}}"
            flag = to_base64(flag)
            flag = to_base64(flag)
            flag = rot13(flag)
            flag = to_base64(flag)
            flag = to_base64(flag)
            flag = to_base64(flag)
            flag = rot13(flag)
            flag = to_base64(flag)
            MESSAGES[user.uuid] = {}
            MESSAGES[user.uuid]["flag"] = flag
            message_for_hq = f"We serve the People's Internet Network Deciphering Agency"
            message_for_hq = to_base64(message_for_hq)
            message_for_hq = rot13(message_for_hq)
            message_for_hq = to_base64(message_for_hq)
            message_for_hq = to_base64(message_for_hq)
            message_for_hq = to_base64(message_for_hq)
            message_for_hq = rot13(message_for_hq)
            message_for_hq = rot13(message_for_hq)
            message_for_hq = rot13(message_for_hq)
            message_for_hq = to_base64(message_for_hq)
            message_for_hq = to_base64(message_for_hq)
            message_for_hq = to_base64(message_for_hq)
            MESSAGES[user.uuid]["secret"] = message_for_hq

            response = JSONResponse(
                content={
                    "message":
                    MESSAGES.get(user.uuid).get("flag"),
                    "securityInformation":
                    f"Codename {user.uuid}! You will see this message only once!",
                    "secret":
                    "POST /{unique identification number}/headquarters with a decoded secret, "
                    f"but first GET the secret from the /box"
                })
            response.set_cookie("message", "UBURUBUBUBURUBUB")
            response.set_cookie("secret", "UBUBUBURURURUBUBUBURUB")
            return response
        else:
            response = JSONResponse(
                status_code=status.HTTP_404_NOT_FOUND,
                content={"message": "I told you. ONLY ONCE!"})
            response.set_cookie("flag", "${flag_there_can_be_only_one}")
            return response
Ejemplo n.º 28
0
    async def post(self, request: Request) -> Response:
        # Some middleware (for example CSRF) has already awaited the request
        # body, and adds it to the request.
        body = request.scope.get("form")

        if not body:
            try:
                body = await request.json()
            except JSONDecodeError:
                body = await request.form()

        username = body.get("username", None)
        password = body.get("password", None)
        return_html = body.get("format") == "html"

        if (not username) or (not password):
            error_message = "Missing username or password"
            if return_html:
                return self._render_template(
                    request,
                    template_context={"error": error_message},
                )
            else:
                raise HTTPException(status_code=422, detail=error_message)

        # Run pre_login hooks
        if self._hooks and self._hooks.pre_login:
            hooks_response = await self._hooks.run_pre_login(username=username)
            if isinstance(hooks_response, str):
                return self._get_error_response(
                    request=request,
                    error=hooks_response,
                    response_format="html" if return_html else "plain",
                )

        # Check CAPTCHA
        if self._captcha:
            token = body.get(self._captcha.token_field, None)
            validate_response = await self._captcha.validate(token=token)
            if isinstance(validate_response, str):
                if return_html:
                    return self._render_template(
                        request,
                        template_context={"error": validate_response},
                    )
                else:
                    raise HTTPException(status_code=401,
                                        detail=validate_response)

        # Attempt login
        user_id = await self._auth_table.login(username=username,
                                               password=password)

        if user_id:
            # Run login_success hooks
            if self._hooks and self._hooks.login_success:
                hooks_response = await self._hooks.run_login_success(
                    username=username, user_id=user_id)
                if isinstance(hooks_response, str):
                    return self._get_error_response(
                        request=request,
                        error=hooks_response,
                        response_format="html" if return_html else "plain",
                    )
        else:
            # Run login_failure hooks
            if self._hooks and self._hooks.login_failure:
                hooks_response = await self._hooks.run_login_failure(
                    username=username)
                if isinstance(hooks_response, str):
                    return self._get_error_response(
                        request=request,
                        error=hooks_response,
                        response_format="html" if return_html else "plain",
                    )

            if return_html:
                return self._render_template(
                    request,
                    template_context={
                        "error": "The username or password is incorrect."
                    },
                )
            else:
                raise HTTPException(status_code=401, detail="Login failed")

        now = datetime.now()
        expiry_date = now + self._session_expiry
        max_expiry_date = now + self._max_session_expiry

        session: SessionsBase = await self._session_table.create_session(
            user_id=user_id,
            expiry_date=expiry_date,
            max_expiry_date=max_expiry_date,
        )

        if self._redirect_to is not None:
            response: Response = RedirectResponse(
                url=self._redirect_to, status_code=HTTP_303_SEE_OTHER)
        else:
            response = JSONResponse(content={"message": "logged in"},
                                    status_code=200)

        if not self._production:
            message = (
                "If running sessions in production, make sure 'production' "
                "is set to True, and serve under HTTPS.")
            warnings.warn(message)

        cookie_value = t.cast(str, session.token)

        response.set_cookie(
            key=self._cookie_name,
            value=cookie_value,
            httponly=True,
            secure=self._production,
            max_age=int(self._max_session_expiry.total_seconds()),
            samesite="lax",
        )
        return response
Ejemplo n.º 29
0
    async def post(self, request: Request) -> Response:
        # Some middleware (for example CSRF) has already awaited the request
        # body, and adds it to the request.
        body = request.scope.get("form")

        if not body:
            try:
                body = await request.json()
            except JSONDecodeError:
                body = await request.form()

        username = body.get("username", None)
        password = body.get("password", None)

        if (not username) or (not password):
            raise HTTPException(
                status_code=401, detail="Missing username or password"
            )

        user_id = await self._auth_table.login(
            username=username, password=password
        )

        if not user_id:
            if body.get("format") == "html":
                return self.render_template(
                    request,
                    template_context={
                        "error": "The username or password is incorrect."
                    },
                )
            else:
                raise HTTPException(status_code=401, detail="Login failed")

        now = datetime.now()
        expiry_date = now + self._session_expiry
        max_expiry_date = now + self._max_session_expiry

        session: SessionsBase = await self._session_table.create_session(
            user_id=user_id,
            expiry_date=expiry_date,
            max_expiry_date=max_expiry_date,
        )

        if self._redirect_to is not None:
            response: Response = RedirectResponse(
                url=self._redirect_to, status_code=HTTP_303_SEE_OTHER
            )
        else:
            response = JSONResponse(
                content={"message": "logged in"}, status_code=200
            )

        if not self._production:
            message = (
                "If running sessions in production, make sure 'production' "
                "is set to True, and serve under HTTPS."
            )
            warnings.warn(message)

        cookie_value = t.cast(str, session.token)

        response.set_cookie(
            key=self._cookie_name,
            value=cookie_value,
            httponly=True,
            secure=self._production,
            max_age=int(self._max_session_expiry.total_seconds()),
            samesite="lax",
        )
        return response
Ejemplo n.º 30
0
async def set_cookie():
    """ Set api key into cookies """
    response = JSONResponse(f'API key has been set into cookie as {API_KEY_NAME}')
    response.set_cookie(key=API_KEY_NAME, value=API_KEY_VALUE)
    return response