def __create_user_management(self): from cmdb.user_management.models.user import UserModel from cmdb.user_management.managers.user_manager import UserManager from cmdb.user_management.managers.group_manager import GroupManager from cmdb.user_management import __FIXED_GROUPS__ from cmdb.security.security import SecurityManager scm = SecurityManager(self.setup_database_manager) group_manager = GroupManager(self.setup_database_manager) user_manager = UserManager(self.setup_database_manager) for group in __FIXED_GROUPS__: group_manager.insert(group) # setting the initial user to admin/admin as default admin_name = 'admin' admin_pass = '******' import datetime admin_user = UserModel( public_id=1, user_name=admin_name, active=True, group_id=__FIXED_GROUPS__[0].get_public_id(), registration_time=datetime.datetime.now(), password=scm.generate_hmac(admin_pass), ) user_manager.insert(admin_user) return True
def get_group(public_id: int): """ HTTP `GET`/`HEAD` route for a single group resource. Args: public_id (int): Public ID of the group. Raises: ManagerGetError: When the selected group does not exists. Notes: Calling the route over HTTP HEAD method will result in an empty body. Returns: GetSingleResponse: Which includes the json data of a UserGroupModel. """ group_manager: GroupManager = GroupManager(database_manager=current_app.database_manager, right_manager=RightManager(rights)) try: group = group_manager.get(public_id) except ManagerGetError as err: return abort(404, err.message) api_response = GetSingleResponse(UserGroupModel.to_dict(group), url=request.url, model=UserGroupModel.MODEL, body=request.method == 'HEAD') return api_response.make_response()
def get_groups(params: CollectionParameters): """ HTTP `GET`/`HEAD` route for getting a iterable collection of resources. Args: params (CollectionParameters): Passed parameters over the http query string Returns: GetMultiResponse: Which includes a IterationResult of the UserGroupModel. Notes: Calling the route over HTTP HEAD method will result in an empty body. Raises: ManagerIterationError: If the collection could not be iterated. ManagerGetError: If the collection/resources could not be found. """ group_manager: GroupManager = GroupManager(database_manager=current_app.database_manager, right_manager=RightManager(rights)) try: iteration_result: IterationResult[UserGroupModel] = group_manager.iterate( filter=params.filter, limit=params.limit, skip=params.skip, sort=params.sort, order=params.order) groups = [UserGroupModel.to_dict(group) for group in iteration_result.results] api_response = GetMultiResponse(groups, total=iteration_result.total, params=params, url=request.url, model=UserGroupModel.MODEL, body=request.method == 'HEAD') except FrameworkIterationError as err: return abort(400, err.message) except ManagerGetError as err: return abort(404, err.message) return api_response.make_response()
def update_group(public_id: int, data: dict): """ HTTP `PUT`/`PATCH` route for update a single group resource. Args: public_id (int): Public ID of the updatable group. data (UserGroupModel.SCHEMA): New group data to update. Raises: ManagerGetError: When the group with the `public_id` was not found. ManagerUpdateError: When something went wrong during the update. Returns: UpdateSingleResponse: With update result of the new updated group. """ group_manager: GroupManager = GroupManager(database_manager=current_app.database_manager, right_manager=RightManager(rights)) try: group = UserGroupModel.from_data(data=data, rights=RightManager(rights).rights) group_dict = UserGroupModel.to_dict(group) group_dict['rights'] = [right.get('name') for right in group_dict.get('rights', [])] group_manager.update(public_id=PublicID(public_id), group=group_dict) api_response = UpdateSingleResponse(result=group_dict, url=request.url, model=UserGroupModel.MODEL) except ManagerGetError as err: return abort(404, err.message) except ManagerUpdateError as err: return abort(400, err.message) return api_response.make_response()
def insert_group(data: dict): """ HTTP `POST` route for insert a single group resource. Args: data (UserGroupModel.SCHEMA): Insert data of a new group. Raises: ManagerGetError: If the inserted group could not be found after inserting. ManagerInsertError: If something went wrong during insertion. Returns: InsertSingleResponse: Insert response with the new group and its public_id. """ group_manager: GroupManager = GroupManager(database_manager=current_app.database_manager, right_manager=RightManager(rights)) try: result_id: PublicID = group_manager.insert(data) group = group_manager.get(public_id=result_id) except ManagerGetError as err: return abort(404, err.message) except ManagerInsertError as err: return abort(400, err.message) api_response = InsertSingleResponse(result_id=result_id, raw=UserGroupModel.to_dict(group), url=request.url, model=UserGroupModel.MODEL) return api_response.make_response(prefix='groups')
def right_required(required_right: str, excepted: dict = None): """wraps function for routes which requires a special user right requires: insert_request_user """ with current_app.app_context(): group_manager = GroupManager(current_app.database_manager, RightManager(rights)) def _page_right(func): @functools.wraps(func) def _decorate(*args, **kwargs): try: current_user: UserModel = kwargs['request_user'] except KeyError: return abort(400, 'No request user was provided') try: group: UserGroupModel = group_manager.get( current_user.group_id) has_right = group.has_right(required_right) except ManagerGetError: return abort(404, 'Group or right not exists') if not has_right and not group.has_extended_right(required_right): return abort( 403, 'Request user does not have the right for this action') return func(*args, **kwargs) return _decorate return _page_right
def delete_group(public_id: int, params: GroupDeletionParameters): """ HTTP `DELETE` route for delete a single group resource. Args: public_id (int): Public ID of the user. params (GroupDeletionParameters): Optional action parameters for handling users when the group \ is going to be deleted. Notes: Based on the params attribute. Users can be moved or deleted. Raises: ManagerGetError: When the group with the `public_id` was not found. ManagerDeleteError: When something went wrong during the deletion. Returns: DeleteSingleResponse: Delete result with the deleted group as data. """ group_manager: GroupManager = GroupManager(database_manager=current_app.database_manager, right_manager=RightManager(rights)) user_manager: UserManager = UserManager(database_manager=current_app.database_manager) # Check of action is set if params.action: users_in_group: List[UserModel] = user_manager.get_many(Query({'group_id': public_id})) if len(users_in_group) > 0: if params.action == GroupDeleteMode.MOVE.value: if params.group_id: for user in users_in_group: user.group_id = int(params.group_id) try: user_manager.update(user.public_id, user) except ManagerUpdateError as err: return abort(400, f'Could not move user: {user.public_id} to group: {params.group_id} | ' f'Error: {err.message}') if params.action == GroupDeleteMode.DELETE.value: for user in users_in_group: try: user_manager.delete(user.public_id) except ManagerDeleteError as err: return abort(400, f'Could not delete user: {user.public_id} | Error: {err.message}') try: deleted_group = group_manager.delete(public_id=PublicID(public_id)) api_response = DeleteSingleResponse(raw=UserGroupModel.to_dict(deleted_group), model=UserGroupModel.MODEL) except ManagerGetError as err: return abort(404, err.message) except ManagerDeleteError as err: return abort(404, err.message) return api_response.make_response()
def user_has_right(required_right: str) -> bool: """Check if a user has a specific right""" from flask import request, current_app with current_app.app_context(): user_manager = UserManager(current_app.database_manager) group_manager = GroupManager(current_app.database_manager, RightManager(rights)) token = parse_authorization_header(request.headers['Authorization']) try: decrypted_token = TokenValidator(database_manager=current_app.database_manager).decode_token(token) except ValidationError as err: return abort(401) try: user_id = decrypted_token['DATAGERRY']['value']['user']['public_id'] user = user_manager.get(user_id) group = group_manager.get(user.group_id) right_status = group.has_right(right_name=required_right) if not right_status: right_status = group.has_extended_right(right_name=required_right) return right_status except ManagerGetError: return False
def preset_database(database_manager, database_name): from cmdb.database.errors.database_errors import DatabaseNotExists from cmdb.security.key.generator import KeyGenerator from cmdb.security.security import SecurityManager from cmdb.user_management.managers.group_manager import GroupManager from cmdb.user_management.managers.user_manager import UserManager try: database_manager.drop_database(database_name) except DatabaseNotExists: pass from cmdb.user_management import __FIXED_GROUPS__ from datetime import datetime kg = KeyGenerator(database_manager=database_manager) kg.generate_rsa_keypair() kg.generate_symmetric_aes_key() group_manager = GroupManager(database_manager=database_manager) user_manager = UserManager(database_manager=database_manager) security_manager = SecurityManager(database_manager=database_manager) for group in __FIXED_GROUPS__: group_manager.insert(group) admin_name = 'admin' admin_pass = '******' from cmdb.user_management import UserModel admin_user = UserModel( public_id=1, user_name=admin_name, active=True, group_id=__FIXED_GROUPS__[0].public_id, registration_time=datetime.now(), password=security_manager.generate_hmac(admin_pass), ) user_manager.insert(admin_user)
def post_login(): user_manager: UserManager = UserManager(current_app.database_manager) group_manager: GroupManager = GroupManager( current_app.database_manager, right_manager=RightManager(rights)) security_manager: SecurityManager = SecurityManager( current_app.database_manager) login_data = request.json if not request.json: return abort(400, 'No valid JSON data was provided') request_user_name = login_data['user_name'] request_password = login_data['password'] auth_module = AuthModule( system_settings_reader.get_all_values_from_section( 'auth', default=AuthModule.__DEFAULT_SETTINGS__), user_manager=user_manager, group_manager=group_manager, security_manager=security_manager) user_instance = None try: user_instance = auth_module.login(request_user_name, request_password) except (AuthenticationProviderNotExistsError, AuthenticationProviderNotActivated) as err: return abort(503, err.message) except Exception as e: return abort(401) finally: # If login success generate user instance with token if user_instance: tg = TokenGenerator() token: bytes = tg.generate_token( payload={'user': { 'public_id': user_instance.get_public_id() }}) token_issued_at = int(datetime.now().timestamp()) token_expire = int(tg.get_expire_time().timestamp()) login_response = LoginResponse(user_instance, token, token_issued_at, token_expire) return login_response.make_response() # Login not success else: return abort(401, 'Could not login')
def parse_authorization_header(header): """ Parses the HTTP Auth Header to a JWT Token Args: header: Authorization header of the HTTP Request Examples: request.headers['Authorization'] or something same Returns: Valid JWT token """ if not header: return None value = wsgi_to_bytes(header) try: auth_type, auth_info = value.split(None, 1) auth_type = auth_type.lower() except ValueError: # Fallback for old versions auth_type = b"bearer" auth_info = value if auth_type == b"basic": try: username, password = base64.b64decode(auth_info).split(b":", 1) with current_app.app_context(): username = to_unicode(username, "utf-8") password = to_unicode(password, "utf-8") user_manager: UserManager = UserManager(current_app.database_manager) group_manager: GroupManager = GroupManager(current_app.database_manager, right_manager=RightManager(rights)) security_manager: SecurityManager = SecurityManager(current_app.database_manager) auth_settings = SystemSettingsReader(current_app.database_manager).get_all_values_from_section( 'auth', default=AuthModule.__DEFAULT_SETTINGS__) auth_module = AuthModule(auth_settings, user_manager=user_manager, group_manager=group_manager, security_manager=security_manager) try: user_instance = auth_module.login(username, password) except Exception as e: return None if user_instance: tg = TokenGenerator(current_app.database_manager) return tg.generate_token(payload={'user': { 'public_id': user_instance.get_public_id() }}) else: return None except Exception: return None if auth_type == b"bearer": try: with current_app.app_context(): tv = TokenValidator(current_app.database_manager) decoded_token = tv.decode_token(auth_info) tv.validate_token(decoded_token) return auth_info except Exception: return None return None