async def refresh_token(email: str = '*****@*****.**'): """ Endpoint that creates a new web token. As the funciton "updates" creating a new token, it has the PUT method. Need to be logged in to use. """ if not email: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect password", headers={"WWW-Authenticate": "Bearer"}, ) try: with db_session: username: str = db.get( "select username from DB_User where email=$email") access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) access_token = create_access_token( data={ "email": email, "username": username }, expires_delta=access_token_expires, ) return {"access_token": access_token, "token_type": "bearer"} except: raise HTTPException(status_code=405, detail="Something went wrong")
def access_token_for_user(user: "******", is_long_term=False) -> str: """Returns an access token for the given user""" if is_long_term: access_token_expires = timedelta( days=settings.access_token_remember_me_days) else: access_token_expires = timedelta(minutes=settings.access_token_expiry) return create_access_token( data={"sub": user.badge}, expires_delta=access_token_expires, )
def create_user_token( session: db.Session, user: Optional["models.User"] = None ) -> Tuple[models.User, str]: """Returns a new user, and their associated bearer token""" if not user: user, _ = create_user_password(session) token = create_access_token( data={"sub": user.badge}, expires_delta=timedelta(minutes=15), ) return user, token
def test_edit_snapshot_others_snapshot(client: TestClient, user1, snapshot2): """Permissions error when attempting to edit other people's decks""" token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) response = client.patch( f"/v2/decks/snapshots/{snapshot2.id}", headers={"Authorization": f"Bearer {token}"}, json={"title": "New title"}, ) assert response.status_code == status.HTTP_403_FORBIDDEN
def test_edit_snaphot_not_snapshot(client: TestClient, user1, deck1): """Generic error when trying to edit something that is not a snapshot""" token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) response = client.patch( f"/v2/decks/snapshots/{deck1.id}", headers={"Authorization": f"Bearer {token}"}, json={"title": "New title"}, ) assert response.status_code == status.HTTP_400_BAD_REQUEST
def test_get_deck_no_record(client: TestClient, session: db.Session, user1): """Trying to fetch an ID that no longer exists must fail correctly""" deck = create_deck_for_user(session, user1) deleted_id = deck.id session.delete(deck) session.commit() token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) response = client.get( f"/v2/decks/{deleted_id}", headers={"Authorization": f"Bearer {token}"} ) assert response.status_code == status.HTTP_404_NOT_FOUND
def test_list_snapshots(client: TestClient, user1, private_snapshot1): """Users can view both private and public snapshots for decks they own""" token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) response = client.get( f"/v2/decks/{private_snapshot1.source_id}/snapshots", headers={"Authorization": f"Bearer {token}"}, ) assert response.status_code == status.HTTP_200_OK data = response.json() assert data["count"] == 2 assert len(data["results"]) == 2
def test_list_snapshots_public_only(client: TestClient, user1, private_snapshot1): """Users can view listings that include only public snapshots""" token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) response = client.get( f"/v2/decks/{private_snapshot1.source_id}/snapshots", params={"show_public_only": True}, headers={"Authorization": f"Bearer {token}"}, ) assert response.status_code == status.HTTP_200_OK data = response.json() assert data["count"] == 1 assert len(data["results"]) == 1
def test_get_deck_saved(client: TestClient, deck1, user1): """Showing saved decks must work for the owner""" token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) response = client.get( f"/v2/decks/{deck1.id}", params={"show_saved": True}, headers={"Authorization": f"Bearer {token}"}, ) assert response.status_code == status.HTTP_200_OK data = response.json() assert data["deck"]["id"] == deck1.id assert data["deck"]["is_saved"] == True
def test_get_deck_private_snapshot_owned( client: TestClient, session: db.Session, user1 ): """Private snapshots must be returned if requested by the owner""" deck = create_deck_for_user(session, user1) snapshot = create_snapshot_for_deck(session, user1, deck) token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) response = client.get( f"/v2/decks/{snapshot.id}", headers={"Authorization": f"Bearer {token}"} ) assert response.status_code == status.HTTP_200_OK assert response.json()["deck"]["id"] == snapshot.id
def test_get_mine(client: TestClient, user1, deck1, private_deck1): """Listing private decks returns the current user's decks""" # This endpoint is functionally identical to the generic deck filter, aside from returning saved # decks, so no need to test all the filters token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) response = client.get( f"/v2/decks/mine", headers={"Authorization": f"Bearer {token}"} ) assert response.status_code == status.HTTP_200_OK data = response.json() assert data["count"] == 2 assert data["results"][0]["id"] == private_deck1.id assert data["results"][1]["id"] == deck1.id
def test_edit_snapshot_bad_id(client: TestClient, session: db.Session, user1, deck1): """Not found error thrown when viewing non-existent ID""" snapshot = create_snapshot_for_deck(session, user1, deck1) deleted_id = snapshot.id session.delete(snapshot) session.commit() token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) response = client.patch( f"/v2/decks/snapshots/{deleted_id}", headers={"Authorization": f"Bearer {token}"}, json={"title": "New title"}, ) assert response.status_code == status.HTTP_404_NOT_FOUND, response.json()
async def login(form: OAuth2PasswordRequestForm = Depends()): try: user = authenticate_user(form.username, form.password) except UsernameNotFound: return {"Username not found"} except IncorrectPassword: return {"Incorrect Password"} ACCESS_TOKEN_EXPIRES = timedelta(minutes=30) access_token = create_access_token( data={ "email": user["email"], "username": user["username"] }, expires_delta=ACCESS_TOKEN_EXPIRES, ) return {"access_token": access_token, "token_type": "bearer"}
def test_edit_snapshot(client: TestClient, session: db.Session, user1, snapshot1): """Users can edit their own snapshots""" token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) new_title = "New title" new_description = "New description" response = client.patch( f"/v2/decks/snapshots/{snapshot1.id}", headers={"Authorization": f"Bearer {token}"}, json={"title": new_title, "description": new_description}, ) assert response.status_code == status.HTTP_200_OK session.refresh(snapshot1) assert snapshot1.title == new_title assert snapshot1.description == new_description
def test_get_deck_deleted(client: TestClient, session: db.Session, user1): """Deleted decks must not provide access""" deck = create_deck_for_user(session, user1) deck.is_deleted = True session.commit() token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) # Invisible to the owning user response = client.get( f"/v2/decks/{deck.id}", headers={"Authorization": f"Bearer {token}"} ) assert response.status_code == status.HTTP_404_NOT_FOUND # Invisible to unauthenticated, too response = client.get(f"/v2/decks/{deck.id}") assert response.status_code == status.HTTP_404_NOT_FOUND
def test_edit_snapshot_clear_description( client: TestClient, session: db.Session, user1, snapshot1 ): """Users can pass empty strings to clear descriptions""" token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) old_title = snapshot1.title new_description = "" response = client.patch( f"/v2/decks/snapshots/{snapshot1.id}", headers={"Authorization": f"Bearer {token}"}, json={"description": new_description}, ) assert response.status_code == status.HTTP_200_OK session.refresh(snapshot1) assert snapshot1.title == old_title assert snapshot1.description is None
def test_get_deck_deleted_public_snapshot( client: TestClient, session: db.Session, user1 ): """Decks with a deleted public snapshot must throw an error""" deck = create_deck_for_user(session, user1) snapshot = create_snapshot_for_deck(session, user1, deck, is_public=True) snapshot.is_deleted = True session.commit() token = create_access_token( data={"sub": user1.badge}, expires_delta=timedelta(minutes=15), ) # Invisible to the owning user response = client.get( f"/v2/decks/{deck.id}", headers={"Authorization": f"Bearer {token}"} ) assert response.status_code == status.HTTP_404_NOT_FOUND # Invisible to unauthenticated, too response = client.get(f"/v2/decks/{deck.id}") assert response.status_code == status.HTTP_404_NOT_FOUND
async def login(form_data: OAuth2PasswordRequestForm = Depends()): """ LogIn endpoint, first, authenticates the user checking that the email and the password submitted by the user are correct. Then it creates a valid token for the user. """ user = authenticate_user(form_data.username, form_data.password) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect password", headers={"WWW-Authenticate": "Bearer"}, ) access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) access_token = create_access_token( data={ "email": user["email"], "username": user["username"] }, expires_delta=access_token_expires, ) return {"access_token": access_token, "token_type": "bearer"}