def _login_jwt_user(self, web_request: WebRequest, create: bool = False) -> Dict[str, Any]: username: str = web_request.get_str('username') password: str = web_request.get_str('password') user_info: Dict[str, Any] if username in RESERVED_USERS: raise self.server.error(f"Invalid Request for user {username}") if create: if username in self.users: raise self.server.error(f"User {username} already exists") salt = secrets.token_bytes(32) hashed_pass = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, HASH_ITER).hex() user_info = { 'username': username, 'password': hashed_pass, 'salt': salt.hex(), 'created_on': time.time() } self.users[username] = user_info action = "user_created" else: if username not in self.users: raise self.server.error(f"Unregistered User: {username}") user_info = self.users[username] salt = bytes.fromhex(user_info['salt']) hashed_pass = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, HASH_ITER).hex() action = "user_logged_in" if hashed_pass != user_info['password']: raise self.server.error("Invalid Password") jwt_secret_hex: Optional[str] = user_info.get('jwt_secret', None) if jwt_secret_hex is None: private_key = Signer() jwk_id = base64url_encode(secrets.token_bytes()).decode() user_info['jwt_secret'] = private_key.hex_seed().decode() user_info['jwk_id'] = jwk_id self.users[username] = user_info self.public_jwks[jwk_id] = self._generate_public_jwk(private_key) else: private_key = self._load_private_key(jwt_secret_hex) jwk_id = user_info['jwk_id'] token = self._generate_jwt(username, jwk_id, private_key) refresh_token = self._generate_jwt( username, jwk_id, private_key, token_type="refresh", exp_time=datetime.timedelta(days=self.login_timeout)) if create: IOLoop.current().call_later(.005, self.server.send_event, "authorization:user_created", {'username': username}) return { 'username': username, 'token': token, 'refresh_token': refresh_token, 'action': action }
async def _login_jwt_user(self, web_request: WebRequest, create: bool = False) -> Dict[str, Any]: username: str = web_request.get_str('username') password: str = web_request.get_str('password') source: str = web_request.get_str('source', self.default_source).lower() if source not in AUTH_SOURCES: raise self.server.error(f"Invalid 'source': {source}") user_info: Dict[str, Any] if username in RESERVED_USERS: raise self.server.error(f"Invalid Request for user {username}") if source == "ldap": if create: raise self.server.error("Cannot Create LDAP User") if self.ldap is None: raise self.server.error("LDAP authentication not available", 401) await self.ldap.authenticate_ldap_user(username, password) if username not in self.users: create = True if create: if username in self.users: raise self.server.error(f"User {username} already exists") salt = secrets.token_bytes(32) hashed_pass = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, HASH_ITER).hex() user_info = { 'username': username, 'password': hashed_pass, 'salt': salt.hex(), 'source': source, 'created_on': time.time() } self.users[username] = user_info self._sync_user(username) action = "user_created" if source == "ldap": # Dont notify user created action = "user_logged_in" create = False else: if username not in self.users: raise self.server.error(f"Unregistered User: {username}") user_info = self.users[username] auth_src = user_info.get("source", "moonraker") if auth_src != source: raise self.server.error( f"Moonraker cannot authenticate user '{username}', must " f"specify source '{auth_src}'", 401) salt = bytes.fromhex(user_info['salt']) hashed_pass = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, HASH_ITER).hex() action = "user_logged_in" if hashed_pass != user_info['password']: raise self.server.error("Invalid Password") jwt_secret_hex: Optional[str] = user_info.get('jwt_secret', None) if jwt_secret_hex is None: private_key = Signer() jwk_id = base64url_encode(secrets.token_bytes()).decode() user_info['jwt_secret'] = private_key.hex_seed().decode() user_info['jwk_id'] = jwk_id self.users[username] = user_info self._sync_user(username) self.public_jwks[jwk_id] = self._generate_public_jwk(private_key) else: private_key = self._load_private_key(jwt_secret_hex) jwk_id = user_info['jwk_id'] token = self._generate_jwt(username, jwk_id, private_key) refresh_token = self._generate_jwt( username, jwk_id, private_key, token_type="refresh", exp_time=datetime.timedelta(days=self.login_timeout)) if create: event_loop = self.server.get_event_loop() event_loop.delay_callback(.005, self.server.send_event, "authorization:user_created", {'username': username}) return { 'username': username, 'token': token, 'source': user_info.get("source", "moonraker"), 'refresh_token': refresh_token, 'action': action }