async def destroy( user_id: int, user_repo: UserRepo = Depends(UserRepo()), token: TokenPayload = Depends( ScopedTo("user:create", "super", satisfy="one")), user: User = Depends(current_user), ): if user_id == user.id: abort(403, msg="Cannot deactivate self") remaining_supers = len( user_repo.filter( user_repo.label("is_superuser") == True, user_repo.label("is_active") == True, user_repo.label("id") != user_id, ).all().results()) if remaining_supers < 1: abort( 403, msg="Cannot deactivate user. No other active super users available." ) user_repo.clear() messages = [{"text": "Deactivation Succesful", "type": "success"}] if not user_repo.exists(id=user_id): return BaseResponse(messages=messages) user_repo.deactivate(user_id) return BaseResponse(messages=messages)
async def update( user_id: int, form: UserEditForm, user_repo: UserRepo = Depends(UserRepo()), token: TokenPayload = Depends( ScopedTo("user:update", "super", satisfy="one")), ): email = getattr(form, "email", None) if email: for u in user_repo.new().all().results(): print("USER:"******"Invalid Email Address", code=422, field="email") data = only(form, ["email", "is_active", "is_superuser"]) if getattr(form, "password", None): data["hashed_password"] = hash_password(form.password) item = user_repo.new().get_or_fail(user_id).update(data).data() return UserResponse(user=item)
async def show( user_repo: UserRepo = Depends(UserRepo()), token: TokenPayload = Depends(ScopedTo("profile")), user: User = Depends(current_user), ): logger.critical("Loading user") item = user_repo.set_results(user).data() return UserResponse(user=item)
async def index( sort_qs: SortQS = Depends(SortQS), pagination: PaginationQS = Depends(PaginationQS), user_repo: UserRepo = Depends(UserRepo()), token: TokenPayload = Depends(ScopedTo("user:list")), ): pg, items = user_repo.sort(sort_qs).paginate(pagination).data() return UsersResponse(pagination=pg, users=items)
async def activate( user_id: int, user_repo: UserRepo = Depends(UserRepo()), token: TokenPayload = Depends(ScopedTo("user:create", "super")), ): user = user_repo.get_or_fail(user_id).update({"is_active": True}).data() return UserResponse(user=user)
async def show( user_id: int, user_repo: UserRepo = Depends(UserRepo()), token: TokenPayload = Depends(ScopedTo("user:show", "super")), includes: List[str] = Query(None), ): includes = only(includes, [], values=True) item = user_repo.loads(includes).get_or_fail(user_id).includes( includes).data() return UserResponse(user=item)
async def broadcast_auth(websocket: WebSocket): try: await websocket.accept() except Exception as e: logger.critical( f"[email protected] - Accept Error: {str(type(e))}") logger.critical( f"[email protected] - Accept Trace: {str(e)}") return 1 params = parse_qs(urlparse(str(websocket.url)).query) token = verify_jwt_token(params["ws_access_token"][0]) if not token_has_required_scopes(token, []): # TODO: check scopes later raise HTTPException(403, detail="Forbidden") user_repo = UserRepo(session()) user = await current_user(token, user_repo) subscriber, channel = await make_subscriber("auth") try: while await channel.wait_message(): logger.info("[email protected] - Waiting for message") msg = await channel.get(encoding="utf-8") logger.info("[email protected] - Received message: " + str(msg)) data = json.loads(msg) logger.info("[email protected] - Sending message: " + str(data)) await websocket.send_json(data) except Exception as e: logger.critical( f"[email protected] - Receieve/Send: Error: {str(type(e))}" ) logger.critical( f"[email protected] - Receieve/Send: Trace:{str(e)}") logger.critical( f"[email protected] - Receieve/Send: Not closing or unsubscribing" ) return 1 logger.info(f"[email protected] - Attempting to unsuscribe") await subscriber.unsubscribe("channel:auth") logger.info( f"[email protected]: Websocket - Attempting to close socket" ) await websocket.close()
async def broadcast_authed_index(websocket: WebSocket): await websocket.accept() params = parse_qs(urlparse(str(websocket.url)).query) token = verify_jwt_token(params["ws_access_token"][0]) if not token_has_required_scopes(token, []): # TODO: check scopes later raise HTTPException(403, detail="Forbidden") user_repo = UserRepo(session()) user = current_user(token, user_repo) subscriber, channel = await make_subscriber("auth") while await channel.wait_message(): msg = await channel.get(encoding="utf-8") print("broadcasting message", msg) data = json.loads(msg) await websocket.send_json(data) await subscriber.unsubscribe("channel:auth") await websocket.close()
async def store( form: UserCreateForm, user_repo: UserRepo = Depends(UserRepo()), token: TokenPayload = Depends( ScopedTo("user:create", "super", satisfy="one")), ): if user_repo.exists(email=form.email): abort_for_input("email", "Email has already been taken.") user_repo.clear() # TODO: data validation against current db & perm checks data = { "email": form.email, "hashed_password": hash_password(form.password), "is_active": getattr(form, "is_superuser", True), "is_superuser": getattr(form, "is_superuser", False), } item = user_repo.create(data).data() return UserResponse(user=item)
def seed_from_env(self): from bountydns.core.user import UserRepo from bountydns.core.zone import ZoneRepo from bountydns.core.dns_server import DnsServerRepo from bountydns.db.session import _scoped_session session = _scoped_session for i in range(9): i = str(i) user_data = {} email_key = f"SEED_USER_{i}_EMAIL" email = environ.get(email_key, None) password_key = f"SEED_USER_{i}_PASSWORD" password = environ.get(password_key, None) superuser_key = f"SEED_USER_{i}_SUPERUSER" is_superuser = int(environ.get(superuser_key, 0)) if email and password: email = email.lower() hashed_password = hash_password(password) repo = UserRepo(db=session) if not repo.exists(email=email): logger.info(f"seeding user {email}") user = factory("UserFactory", session=session).create( email=email, hashed_password=hashed_password, is_superuser=is_superuser, ) else: logger.info(f"seeded user {email} already exists") for i in range(9): i = str(i) name_key = f"SEED_DNS_SERVER_{i}_NAME" name = environ.get(name_key, None) if name: repo = DnsServerRepo(db=session) if not repo.exists(name=name): logger.info(f"seeding domain {name}") domain = factory("DnsServerFactory", session=session).create(name=name) for i in range(9): i = str(i) ip_key = f"SEED_ZONE_{i}_IP" domain_key = f"SEED_ZONE_{i}_DOMAIN" dns_server_name_key = f"SEED_ZONE_{i}_DNS_SERVER_NAME" ip = environ.get(ip_key, None) domain = environ.get(domain_key, None) if domain: domain = domain.lower() dns_server_name = environ.get(dns_server_name_key, None) if ip and domain: if dns_server_name: dns_server_repo = DnsServerRepo(db=session) if dns_server_repo.exists(name=dns_server_name): dns_server = dns_server_repo.results() else: logger.info( f"seeding dns server as zone dependency: {name}") dns_server = factory( "DnsServerFactory", session=session).create(name=dns_server_name) factory("ZoneFactory", session=session).create(ip=ip, domain=domain, dns_server=dns_server) else: repo = ZoneRepo(db=session) if not repo.exists(ip=ip, domain=domain): logger.info( f"seeding zone without dns server: {ip}, {domain}") factory("GlobalZoneFactory", session=session).create(ip=ip, domain=domain)
async def current_user(token: TokenPayload = Depends(ScopedTo()), user_repo: UserRepo = Depends(UserRepo())) -> User: user = user_repo.get_by_sub(token.sub) if not user: raise HTTPException(404, detail="Not Found") return user