Пример #1
0
 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
     }
Пример #2
0
 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
     }