def test_hash_and_verify_password(initial_password, updated_password): # Create the hashes of each password initial_hash = hash_password(initial_password) updated_hash = hash_password(updated_password) # Make sure the two hashes are not the same assert initial_hash != updated_hash # Make sure both passwords validate against their hash assert verify_password(initial_password, initial_hash) is True assert verify_password(updated_password, updated_hash) is True
def create_user( user: UserCreate, request: Request, response: Response, db: Session = Depends(get_db), ): # Create the new user using the data from the request new_user = User(**user.dict()) # Get the alert queue from the database to associate with the new user new_user.default_alert_queue = crud.read_by_value(user.default_alert_queue, db_table=AlertQueue, db=db) # Get the user roles from the database to associate with the new user new_user.roles = crud.read_by_values(user.roles, db_table=UserRole, db=db) # Securely hash and salt the password. Bcrypt_256 is used to get around the Bcrypt limitations # of silently truncating passwords longer than 72 characters as well as not handling NULL bytes. new_user.password = hash_password(new_user.password) # Save the new user to the database db.add(new_user) crud.commit(db) response.headers["Content-Location"] = request.url_for("get_user", uuid=new_user.uuid)
async def user_post(new_user: UserPost): values = new_user.dict() values["hashed_password"] = hash_password(new_user.password) del values["password"] try: values["id"] = await db.execute(user.insert(), values=values) del values["hashed_password"] return JSONResponse(status_code=status.HTTP_201_CREATED, content=values) except asyncpg.exceptions.UniqueViolationError: raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail="Username or email already used", )
def update_user( uuid: UUID, user: UserUpdate, request: Request, response: Response, db: Session = Depends(get_db), ): # Read the current user from the database db_user: User = crud.read(uuid=uuid, db_table=User, db=db) # Get the data that was given in the request and use it to update the database object update_data = user.dict(exclude_unset=True) if "default_alert_queue" in update_data: db_user.default_alert_queue = crud.read_by_value( value=update_data["default_alert_queue"], db_table=AlertQueue, db=db) if "display_name" in update_data: db_user.display_name = update_data["display_name"] if "email" in update_data: db_user.email = update_data["email"] if "enabled" in update_data: db_user.enabled = update_data["enabled"] if "password" in update_data: db_user.password = hash_password(update_data["password"]) if "roles" in update_data: db_user.roles = crud.read_by_values(values=update_data["roles"], db_table=UserRole, db=db) if "timezone" in update_data: db_user.timezone = update_data["timezone"] if "username" in update_data: db_user.username = update_data["username"] crud.commit(db) response.headers["Content-Location"] = request.url_for("get_user", uuid=uuid)
async def login_user( response: Response, login_user: UserLogin, status_code=200, redis=Depends(get_redis()), ): query = str( select([user.c.id ]).where(user.c.username == bindparam("username")).where( user.c.hashed_password == bindparam("hashed_password"))) result = await db.fetch_one( query, values={ "username": login_user.username, "hashed_password": hash_password(login_user.password), }, ) if result is None: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="wrong username or password", ) user_id, *_ = result.values() token = secrets.token_urlsafe(128)[:64] await redis.set(token, user_id, expire=60 * 60 * 6) response.set_cookie( key="access_token", value=token, secure=True, samesite="Lax", httponly=True, ) return {"message": "ok"}