Esempio n. 1
0
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()
Esempio n. 2
0
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)
Esempio n. 3
0
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)})
Esempio n. 4
0
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)})