def register_user_with_group(user_name, group_name, email, password, db_session): # type: (Str, Str, Str, Str, Session) -> None """ Registers the user if missing and associate him to a group specified by name, also created if missing. :param user_name: name of the user to create (if missing) and to make part of the group (if specified) :param group_name: name of the group to create (if missing and specified) and to make the user join (if not already) :param email: email of the user to be created (if missing) :param password: password of the user to be created (if missing) :param db_session: database connexion to apply changes .. warning:: Should be employed only for **special** users/groups in this module as other expected API behaviour and operations will not be applied (ex: create additional permissions or user-group references). """ if not GroupService.by_group_name(group_name, db_session=db_session): # noinspection PyArgumentList new_group = models.Group(group_name=group_name) db_session.add(new_group) registered_group = GroupService.by_group_name(group_name=group_name, db_session=db_session) registered_user = UserService.by_user_name(user_name, db_session=db_session) if not registered_user: # noinspection PyArgumentList new_user = models.User(user_name=user_name, email=email) UserService.set_password(new_user, password) UserService.regenerate_security_code(new_user) db_session.add(new_user) if group_name is not None: registered_user = UserService.by_user_name(user_name, db_session=db_session) else: print_log("User '{}' already exist".format(user_name), level=logging.DEBUG) # noinspection PyBroadException try: # ensure the reference between user/group exists (user joined the group) user_group_refs = BaseService.all(models.UserGroup, db_session=db_session) user_group_refs_tup = [(ref.group_id, ref.user_id) for ref in user_group_refs] if (registered_group.id, registered_user.id) not in user_group_refs_tup: # noinspection PyArgumentList group_entry = models.UserGroup(group_id=registered_group.id, user_id=registered_user.id) db_session.add(group_entry) except Exception: # in case reference already exists, avoid duplicate error db_session.rollback()
def downgrade_migrate(old_group, old_user, new_group, old_name, db_session): """ Migrates a standard group back to the original user and corresponding personal user-group. Reassigns the user references to link to the old personal group. """ if old_group is None: # create missing group # noinspection PyArgumentList old_group = models.Group(group_name=old_name) db_session.add(old_group) if old_group is not None and new_group is not None: # transfer user-group references all_usr_grp = db_session.query(models.UserGroup) for usr_grp in all_usr_grp: if usr_grp.group_id == new_group.id: # if user_id/group_id combination already exists, delete duplicate that would be generated by transfer match_old_grp = [ ug for ug in all_usr_grp if ug.group_id == old_group.id ] if len(match_old_grp) > 0: db_session.delete(usr_grp) # otherwise transfer back reference to old group else: usr_grp.group_id = old_group.id if new_group is not None: db_session.delete(new_group) if old_user is None: # noinspection PyArgumentList old_user = models.User(user_name=old_name, email='{}@mail.com'.format(old_name)) db_session.add(old_user) old_user = models.User.by_user_name(old_name, db_session) # noinspection PyArgumentList usr_grp = models.UserGroup(group_id=old_group.id, user_id=old_user.id) db_session.add(usr_grp)
def create_user(user_name, password, email, group_name, db_session): # type: (Str, Optional[Str], Str, Str, Session) -> HTTPException """ Creates a user if it is permitted and not conflicting. Password must be set to `None` if using external identity. Created user will be part of group matching ``group_name`` (can be ``MAGPIE_ANONYMOUS_GROUP`` for minimal access). Furthermore, the user will also *always* be associated with ``MAGPIE_ANONYMOUS_GROUP`` (if not already explicitly requested with ``group_name``) to allow access to resources with public permission. The ``group_name`` **must** be an existing group. :returns: valid HTTP response on successful operation. """ def _get_group(grp_name): # type: (Str) -> models.Group grp = ax.evaluate_call( lambda: GroupService.by_group_name(grp_name, db_session=db_session ), httpError=HTTPForbidden, msgOnFail=s.UserGroup_GET_ForbiddenResponseSchema.description) ax.verify_param( grp, notNone=True, httpError=HTTPBadRequest, msgOnFail=s.UserGroup_Check_BadRequestResponseSchema.description) return grp # Check that group already exists group_checked = _get_group(group_name) # Check if user already exists user_checked = ax.evaluate_call( lambda: UserService.by_user_name(user_name=user_name, db_session=db_session), httpError=HTTPForbidden, msgOnFail=s.User_Check_ForbiddenResponseSchema.description) ax.verify_param(user_checked, isNone=True, httpError=HTTPConflict, msgOnFail=s.User_Check_ConflictResponseSchema.description) # Create user with specified name and group to assign # noinspection PyArgumentList new_user = models.User(user_name=user_name, email=email) if password: UserService.set_password(new_user, password) UserService.regenerate_security_code(new_user) ax.evaluate_call( lambda: db_session.add(new_user), fallback=lambda: db_session.rollback(), httpError=HTTPForbidden, msgOnFail=s.Users_POST_ForbiddenResponseSchema.description) # Fetch user to update fields new_user = ax.evaluate_call( lambda: UserService.by_user_name(user_name, db_session=db_session), httpError=HTTPForbidden, msgOnFail=s.UserNew_POST_ForbiddenResponseSchema.description) def _add_to_group(usr, grp): # type: (models.User, models.Group) -> None # noinspection PyArgumentList group_entry = models.UserGroup(group_id=grp.id, user_id=usr.id) ax.evaluate_call( lambda: db_session.add(group_entry), fallback=lambda: db_session.rollback(), httpError=HTTPForbidden, msgOnFail=s.UserGroup_GET_ForbiddenResponseSchema.description) # Assign user to group new_user_groups = [group_name] _add_to_group(new_user, group_checked) # Also add user to anonymous group if not already done anonym_grp_name = get_constant("MAGPIE_ANONYMOUS_GROUP") if group_checked.group_name != anonym_grp_name: _add_to_group(new_user, _get_group(anonym_grp_name)) new_user_groups.append(anonym_grp_name) return ax.valid_http( httpSuccess=HTTPCreated, detail=s.Users_POST_CreatedResponseSchema.description, content={u"user": uf.format_user(new_user, new_user_groups)})
def create_user(user_name, password, email, group_name, db_session): # type: (Str, Optional[Str], Str, Optional[Str], Session) -> HTTPException """ Creates a user if it is permitted and not conflicting. Password must be set to ``None`` if using external identity. Created user will immediately assigned membership to the group matching :paramref:`group_name` (can be :py:data:`MAGPIE_ANONYMOUS_GROUP` for minimal access). If no group is provided, this anonymous group will be applied by default, creating a user effectively without any permissions other than ones set directly for him. Furthermore, the user will also *always* be associated with :py:data:`MAGPIE_ANONYMOUS_GROUP` (if not already explicitly or implicitly requested with :paramref:`group_name`) to allow access to resources with public permission. Argument :paramref:`group_name` **MUST** be an existing group if provided. :returns: valid HTTP response on successful operation. """ def _get_group(grp_name): # type: (Str) -> models.Group ax.verify_param(grp_name, not_none=True, not_empty=True, matches=True, param_compare=ax.PARAM_REGEX, param_name="group_name", http_error=HTTPBadRequest, msg_on_fail=s.UserGroup_Check_BadRequestResponseSchema.description) grp = ax.evaluate_call(lambda: GroupService.by_group_name(grp_name, db_session=db_session), http_error=HTTPForbidden, msg_on_fail=s.UserGroup_GET_ForbiddenResponseSchema.description) ax.verify_param(grp, not_none=True, http_error=HTTPNotFound, with_param=False, msg_on_fail=s.UserGroup_Check_NotFoundResponseSchema.description) return grp # Check that group already exists if group_name is None: group_name = get_constant("MAGPIE_ANONYMOUS_GROUP") is_internal = password is not None check_user_info(user_name, email, password, group_name, check_password=is_internal) group_checked = _get_group(group_name) # Check if user already exists user_checked = ax.evaluate_call(lambda: UserService.by_user_name(user_name=user_name, db_session=db_session), http_error=HTTPForbidden, msg_on_fail=s.User_Check_ForbiddenResponseSchema.description) ax.verify_param(user_checked, is_none=True, with_param=False, http_error=HTTPConflict, msg_on_fail=s.User_Check_ConflictResponseSchema.description) # Create user with specified name and group to assign new_user = models.User(user_name=user_name, email=email) # noqa if is_internal: UserService.set_password(new_user, password) UserService.regenerate_security_code(new_user) ax.evaluate_call(lambda: db_session.add(new_user), fallback=lambda: db_session.rollback(), http_error=HTTPForbidden, msg_on_fail=s.Users_POST_ForbiddenResponseSchema.description) # Fetch user to update fields new_user = ax.evaluate_call(lambda: UserService.by_user_name(user_name, db_session=db_session), http_error=HTTPForbidden, msg_on_fail=s.UserNew_POST_ForbiddenResponseSchema.description) def _add_to_group(usr, grp): # type: (models.User, models.Group) -> None group_entry = models.UserGroup(group_id=grp.id, user_id=usr.id) # noqa ax.evaluate_call(lambda: db_session.add(group_entry), fallback=lambda: db_session.rollback(), http_error=HTTPForbidden, msg_on_fail=s.UserGroup_GET_ForbiddenResponseSchema.description) # Assign user to group new_user_groups = [group_name] _add_to_group(new_user, group_checked) # Also add user to anonymous group if not already done anonym_grp_name = get_constant("MAGPIE_ANONYMOUS_GROUP") if group_checked.group_name != anonym_grp_name: _add_to_group(new_user, _get_group(anonym_grp_name)) new_user_groups.append(anonym_grp_name) return ax.valid_http(http_success=HTTPCreated, detail=s.Users_POST_CreatedResponseSchema.description, content={"user": uf.format_user(new_user, new_user_groups)})