def get(self, args) -> Response: try: token = oauth.auth.authorize_access_token(**args) id_token = oauth.auth.parse_id_token(token) subject = id_token.get("sub") if not subject: raise OAuthError(description="No user details provided") except OAuthError as e: return make_api_response(400, e.description) user: User = User.get(id=subject) preferred_username = id_token.get("preferred_username") if not user and preferred_username: valid = get_long_validation(preferred_username) if not valid.valid: token_body = make_linking_token(subject, preferred_username, valid.reason) linking_token = create_access_token(token_body) return make_api_response(400, valid.reason, content={"token": linking_token}) # make the user an admin if they are claimed to be an admin user = create_user(subject, preferred_username, admin=id_token.get("admin", False)) if user: tokens = get_sign_in_body(user) return make_api_response(200, content=tokens) return make_api_response(400, "Unable to login using OpenID")
def get(self, page: int, query: str, limit: int, user: Optional[str]) -> Response: if user: user = User.get(username=user) elif current_user: user = current_user return get_songs_response(self, page, query, limit, user)
def user_exists(username: str) -> bool: """Check if username is taken :param str username: username to check :return: True if username is taken, else False :rtype: bool """ return User.exists(username=username)
def validate_linking_token(args: Dict[str, UUID]) -> bool: try: decoded = decode_token(args["token"]) if "id" in decoded["identity"] and "link" in decoded["identity"]: if User.get(id=decoded["identity"]["id"]): raise ValidationError("User is already linked") return True except (PyJWTError, JWTExtendedException): pass raise ValidationError("Token is invalid")
def post(self, username: str, password: str) -> Response: validator = valid_username(username) if not validator.valid: return make_api_response(400, validator.reason) # if no users registered, make first one admin make_admin = User.select().count() == 0 new_user = register(username, password, admin=make_admin) if new_user: return make_api_response( 200, f'User "{username}" successfully registered') return make_api_response(500, "Failed to register user")
def sign_in(username: str, password: str) -> Optional[Dict]: """Authenticate user details, returning authorization tokens and user metadata :param str username: username to authenticate :param str password: password to authenticate :return: dict containing auth tokens and user metadata if valid else None :rtype: dict """ user: User = User.get(username=username) # openid users do not have a hash if user and user.hash: if bcrypt.checkpw(password.encode("utf-8"), user.hash.encode("utf8")): return get_sign_in_body(user) return None
def register(username: str, password: str, admin: bool = False) -> bool: """Register a user given a valid username and password :param str username: username to register :param str password: password to register :param bool admin: if the user should be an admin, defaults to False :return: True if user was successfully registered, else False :rtype: bool """ validator = valid_username(username) if not validator.valid: return False hashed = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()) new_user = User(username=username, hash=hashed.decode("utf-8"), admin=admin) # save user to db commit() return new_user is not None
def user_loader_callback(identity: str): user = User.get(id=identity) return user or None
class FavouriteSchema(SongQuerySchema): user = fields.Str( required=True, validate=lambda arg: User.exists(username=arg), error_messages={"validator_failed": "User does not exist"}, )
from pony.orm import commit, db_session from radio.common.users import register, user_exists, valid_username from radio.database import User parser = argparse.ArgumentParser() parser.add_argument("username", type=str) parser.add_argument("-p", "--password", type=str) parser.add_argument("--admin", action="store_true") args = parser.parse_args() with db_session: if user_exists(args.username): if args.admin: print(f'User "{args.username}" exists. Making them an admin.') user = User.get(username=args.username) user.admin = True commit() else: print(f'User "{args.username}" already exists.') else: validator = valid_username(args.username) if validator.valid: if args.password: success = register(args.username, args.password, admin=args.admin) if success: print(f'User "{args.username}" successfully created.') else: print("No password specified.")
def create_user(subject, preferred_username, admin=False) -> User: make_admin = admin or User.select().count() == 0 user = User(id=subject, username=preferred_username, admin=make_admin) commit() return user