Пример #1
0
    def register(self, user: UserModel) -> UserModel:
        """
        Registers a new user.

        If the user cannot register, because the login or the the ameil are already in use,
        a `ConstraintViolation` exception is raised.

        The student role is added automaticall to the new user.

        :param UserModel user: The userdate for the new user.
        """
        data = user.json()
        url = self.url_for("/user/register/")
        result = self.requests.post(url, data=data)

        # Status 201: Ressource created
        if result.status_code == 201:
            response_data = result.json()
            user = UserModel.raw(response_data["user"])
            bearer_token_data = BearerTokenData.parse_obj(response_data["bearer_token_data"])

            # Not get the student role
            student_role = self.client.role_service.get_by_name_or_none(
                bearer_token_data.bearer_token, "student"
            )
            if student_role:
                self.add_role(bearer_token_data.bearer_token, user, student_role)
            return (
                user,
                bearer_token_data,
            )

        raise DigiCubeError(f"Something went wrong. Status {result.status_code}")
Пример #2
0
    def get(self, token, user_id: int, fields: XFieldList = None) -> Optional[UserModel]:
        """
        Get a single user with the given id.

        :param str token: The authentification token.
        :param int user_id: The id of the requested user.
        :param XFieldList fields: The fields of the user, that should be returned.
        :return: The requested user.
        :rtype: :class:`UserModel`
        :raises InsufficientRights: If the requesting user has not the permission.
        :raises DoesNotExist: if no user exists with the provided login.
        :raises TokenExpired: is the token has expired.
        :raises ServerError: if an unpredicted exception occurred.
        """
        # user = self.cache.get_user(user_id)
        # if user is not None:
        #    logger.info("Cache hit for user %s", user.login)
        #    return user  # Cache hit

        # Cache miss
        headers = self.create_default_header(token, fields=fields)
        url = self.url_for(f"/user/{user_id}")
        response = self.requests.get(url, headers=headers)

        self.check_response_status(response, expected_status=200)
        user = UserModel.parse_obj(response.json())
        # self.cache.set_user(user)  # Cache the fetched user.
        return user
Пример #3
0
def get_all():
    """The user list route."""
    user_list = digicubes.user.all(digicubes.token)
    if requested_html():
        return render_template("admin/users.jinja", users=user_list, token=digicubes.token)

    return UserModel.list_model(user_list).json()
Пример #4
0
    def update(self, token, user: UserModelUpsert) -> UserModel:
        """
        Update an existing user.
        If successfull, a new user model is returned with the latest version of the
        user data.
        """
        response = self.requests.put(
            self.url_for(f"/user/{user.id}"),
            data=user.json(),
            headers=self.create_default_header(token),
        )

        if response.status_code == 404:
            raise DoesNotExist(response.text)

        if response.status_code == 500:
            raise ServerError(response.text)

        if response.status_code != 200:
            raise ServerError(f"Wrong status. Expected 200. Got {response.status_code}")

        user = UserModel.parse_obj(response.json())

        # Add or update the cached user
        # self.cache.set_user(user)
        return user  # TODO Check other status_codes
Пример #5
0
    def create(self, token: str, user: UserModelUpsert, fields: XFieldList = None) -> UserModel:
        """
        Creates a new user
        """
        headers = self.create_default_header(token, fields=fields)
        data = user.json()
        url = self.url_for("/users/")
        result = self.requests.post(url, data=data, headers=headers)

        if result.status_code == 201:
            # User created successfully. We cannot create the user directly
            # with the password, so we have to set the password in a second step.
            #
            # TODO: Why not able to set the password directly in the
            # REST call? Check is and change it, if possible.
            user_model = UserModel.parse_obj(result.json())
            if not user.password:
                logger.debug("Created user without password.")
            else:
                self.set_password(token=token, user_id=user_model.id, new_password=user.password)

            return user_model

        if result.status_code == 409:
            raise ConstraintViolation(result.text)

        if result.status_code == 500:
            raise ServerError(result.text)

        raise ServerError(f"Unknown error. [{result.status_code}] {result.text}")
Пример #6
0
 def get_school_teacher(self, token: str,
                        school_id: int) -> List[UserModel]:
     headers = self.create_default_header(token)
     url = self.url_for(f"/school/{school_id}/teacher/")
     response = self.requests.get(url, headers=headers)
     self.check_response_status(response, expected_status=200)
     return [UserModel.parse_obj(user) for user in response.json()]
Пример #7
0
def update(user_id: int):
    """
    Route to update an existing user.
    """
    service: srv.UserService = digicubes.user
    token = digicubes.token
    form = UserForm()
    user_model: UserModel = None

    if form.is_submitted():
        if form.validate({"login": [UserLoginAvailable(user_id=user_id)]}):
            user_model = UserModel.parse_obj(form.data)
            user_model.id = user_id
            digicubes.user.update(token, user_model)
            return redirect(url_for("user.get", user_id=user_id))
        else:
            user_model: UserModel = service.get(token, user_id)
    else:
        user_model: UserModel = service.get(token, user_id)
        form.process(obj=user_model)

    return render_template(
        "admin/update_user.jinja",
        form=form,
        user=user_model,
        action=url_for("user.update", user_id=user_id),
    )
Пример #8
0
def get_my_schools():
    """
    Gets alls schools related to this user. The user must be
    a headmaster. If no schools are associated with this user,
    a info message will be displayed.
    """
    school_service: SchoolService = digicubes.school

    schools = school_service.get_headmaster_schools(digicubes.token, UserModel(id=current_user.id))
    return render_template("headmaster/schools.jinja", schools=schools)
Пример #9
0
    def rfc_user_toggle_role(data: DataType) -> RfcResponse:
        user_id = data.get("user_id", None)
        role_id = data.get("role_id", None)
        operation = data.get("operation", "toggle")

        assert user_id is not None, "No user id provided"
        assert role_id is not None, "No role id provided"

        if operation == "add":
            server.user.add_role(
                server.token, UserModel(id=user_id), RoleModel(id=role_id, name="xxx")
            )
            return RfcResponse(data={"user_id": user_id, "role_id": role_id, "has_role": True})

        if operation == "remove":
            server.user.remove_role(
                server.token, UserModel(id=user_id), RoleModel(id=role_id, name="xxx")
            )
            return RfcResponse(data={"user_id": user_id, "role_id": role_id, "has_role": False})

        raise ValueError(f"Unknown or unsupported operation '{operation}'")
Пример #10
0
def school_remove_teacher(school_id: int, teacher_id: int):
    try:
        success = server.school.remove_teacher(server.token,
                                               SchoolModel(id=school_id),
                                               UserModel(id=teacher_id))
        if success:
            flash("Teacher removed")
        else:
            flash("Could not remove teacher.")

        return redirect(url_for("school.get", school_id=school_id))
    except Exception:
        logger.exception("Could not remove teacher from school")
        return redirect(url_for("school.get", school_id=school_id))
Пример #11
0
    def delete(self, token, user_id: int) -> Optional[UserModel]:
        """
        Deletes a user from the database
        """
        # TODO: Clear from cache (or wait for expiration of the key)
        headers = self.create_default_header(token)
        url = self.url_for(f"/user/{user_id}")
        result = self.requests.delete(url, headers=headers)

        if result.status_code == 404:
            raise DoesNotExist(f"User with user id {user_id} not found.")

        if result.status_code != 200:
            raise ServerError(f"Wrong status. Expected 200. Got {result.status_code}")

        return UserModel.parse_obj(result.json())
Пример #12
0
    def get_by_login(self, token: str, login: str) -> UserModel:
        """
        Get a single user by his login, if existent.

        :Route: ``/user/bylogin/{login}``
        :param str token: The authentification token
        :param str login: The login of the user to be looked up.
        :return: The found user
        :rtype: UserModel
        :raises InsufficientRights: If the requesting user has not the permission.
        :raises DoesNotExist: if no user exists with the provided login.
        :raises TokenExpired: is the token has expired.
        :raises ServerError: if an unpredicted exception occurred.
        """
        headers = self.create_default_header(token)
        url = self.url_for(f"/user/bylogin/{login}")
        response = self.requests.get(url, headers=headers)
        self.check_response_status(response, expected_status=200)
        return UserModel.parse_obj(response.json())
Пример #13
0
    def rfc_user_set_active_state(data: DataType) -> RfcResponse:
        user_id = data.get("user_id", None)
        mode = data.get("mode", "toggle")

        user = server.user.get(server.token, user_id, fields=["is_active"])
        new_state = user.is_active

        if mode == "toggle":
            new_state = not new_state
        elif mode == "on":
            new_state = True
        elif mode == "off":
            new_state = False
        else:
            raise ValueError("Unknown mode")

        if new_state != user.is_active:
            server.user.update(server.token, UserModel(id=user_id, is_active=new_state))

        return RfcResponse(data={"user_id": user_id, "state": new_state})
Пример #14
0
    def me(self, token, fields: XFieldList = None) -> Optional[UserModel]:
        """
        Get a single user
        """
        headers = self.create_default_header(token)
        if fields is not None:
            headers[self.X_FILTER_FIELDS] = ",".join(fields)

        url = self.url_for("/me/")
        result = self.requests.get(url, headers=headers)

        if result.status_code == 401:
            raise TokenExpired("Could not read user details. Token expired.")

        if result.status_code == 404:
            return None

        if result.status_code == 200:
            return UserModel.parse_obj(result.json())

        return None
Пример #15
0
    def verify_user(self, token: str):
        """
        Verifies the user, that is connected to this token. If the token is
        valid and nor expired, the user, that belongs to this token, will be
        verified.

        :Route: /verify/user/{token}
        :Method: PUT
        :param str token: The verification token returned by ``get_verification_token``
        :return: The verified user.
        :rtype: :class:`UserModel`
        :raises InsufficientRights: If the requesting user has not the permission.
        :raises DoesNotExist: if the user connected to the token does not exist.
        :raises TokenExpired: is the token has expired.
        :raises ServerError: if an unpredicted exception occurred.
        """
        url = self.url_for(f"/verify/user/{token}")
        response = self.requests.put(url)
        data = response.json()

        return UserModel.parse_obj(data["user"]), data["token"]
Пример #16
0
def register():
    """
    Register a new user.
    """

    # You cannot register, if you are already logged in
    if account_manager.authenticated:
        return account_manager.successful_logged_in()

    form = RegisterForm()
    if form.validate_on_submit():

        try:
            new_user = UserModel.parse_obj(form.data)
            new_user.is_active = True
            new_user.id = None  # Just du be shure, we don't have an id in the form accidently
            # and do an update instead of an creation
            new_user.is_verified = account_manager.auto_verify

            # Create a new user in behalf of root
            result = account_manager.user.register(new_user)
            new_user, btd = result
            current_user.set_data(btd)
            # Also setting the password in behalf of root
            account_manager.user.set_password(current_user.token, new_user.id,
                                              form.password.data)

            # If the user has been auto verified, we can directly proceed to the login page.
            # Otherwise we have to show an information to check his email inbox
            # TODO: Pay respect to both situations.
            account_manager.logout()
            return redirect(url_for("account.index"))

        except DigiCubeError as e:
            logger.exception("Could not create new account.", exc_info=e)
            abort(500)

    return render_template("account/register.jinja", form=form)
Пример #17
0
    def rfc_user_set_verified_state(data: DataType) -> RfcResponse:
        user_id = data.get("user_id", None)
        assert user_id is not None, "No user id provided"

        mode = data.get("mode", "toggle")

        user = server.user.get(server.token, user_id, fields=["is_verified"])
        new_state = user.is_verified

        if mode == "toggle":
            new_state = not new_state
        elif mode == "on":
            new_state = True
        elif mode == "off":
            new_state = False
        else:
            raise ValueError("Unknown mode")

        if new_state != user.is_verified:
            u = UserModel(id=user_id, is_verified=new_state)
            u = server.user.update(server.token, u)

        return RfcResponse(data={"user_id": user_id, "state": new_state})
Пример #18
0
 def get_user_rights(self, user_id: int) -> Optional[List[str]]:
     raw_data = self.redis.get(f"USER:{user_id}:RIGHTS")
     return None if raw_data is None else UserModel.parse_obj(raw_data)
Пример #19
0
def remove_user_role(user_id: int, role_id: int):
    server.user.remove_role(server.token, UserModel(id=user_id),
                            RoleModel(id=role_id, name=""))
    return redirect(url_for("user.update", user_id=user_id))
Пример #20
0
 def set_user(self, user: UserModel):
     key = f"USER:{user.id}"
     self.redis.set(key, user.json(), ex=self.max_age)