예제 #1
0
def validate_and_continue(obj, data):
    """
    Method to validate data against an object
    """
    try:
        validate = obj.load(data)
    except ValidationError as e:
        raise InvalidUsage(error=f"Bad data format: {e}")
    err = ""
    if validate is None:
        raise InvalidUsage(error=f"Bad data format: {err}")
    return validate
예제 #2
0
    def log_in(self, **kwargs):
        """
        This method is in charge of performing the log in of the user

        :param kwargs: keyword arguments passed for the login, these can be username, password or a token
        :return: the response of the login or it raises an error. The correct response is a dict
        with the newly issued token and the user id, and a status code of 200
        :rtype: dict
        """
        auth_type = current_app.config["AUTH_TYPE"]

        if auth_type == AUTH_DB:
            user = self.auth_db_authenticate(**kwargs)
        elif auth_type == AUTH_LDAP:
            user = self.auth_ldap_authenticate(**kwargs)
        elif auth_type == AUTH_OID:
            user = self.auth_oid_authenticate(**kwargs)
        else:
            raise ConfigurationError()

        try:
            token = self.auth_class.generate_token(user.id)
        except Exception as e:
            raise InvalidUsage(f"Error in generating user token: {str(e)}",
                               400)

        return {"token": token, "id": user.id}, 200
예제 #3
0
    def post(self, name, description, minimize=1):
        """

        :param str name:
        :param str description:
        :param int minimize:
        :return: a tuple with the created instance and a integer with the status code
        :rtype: Tuple(:class:`InstanceModel`, 201)
        """
        if "file" not in request.files:
            raise InvalidUsage(error="No file was provided")
        file = request.files["file"]
        filename = secure_filename(file.filename)
        if not (file and allowed_file(filename)):
            raise InvalidUsage(
                error=
                f"Could not open file to upload. Check the extension matches {ALLOWED_EXTENSIONS}"
            )
        file.save(filename)
        sense = 1 if minimize else -1
        try:
            _vars, problem = pulp.LpProblem.fromMPS(filename, sense=sense)
        except:
            raise InvalidUsage(error="There was an error reading the file")
        try:
            os.remove(filename)
        except:
            pass

        pb_data = dict(
            data=problem.toDict(),
            name=name,
            description=description,
            user_id=self.get_user_id(),
        )

        try:
            data = InstanceSchema().load(pb_data)
        except ValidationError as val_err:
            raise InvalidUsage(error=val_err.normalized_messages())

        item = InstanceModel(data)
        item.schema = "solve_model_dag"
        item.save()
        log.info(
            f"User {self.get_user()} creates instance {item.id} from mps file")
        return item, 201
예제 #4
0
    def get(self, user_id):
        """

        :param int user_id: User id.
        :return:
        :rtype: Tuple(dict, integer)
        """
        if self.get_user_id() != user_id and not self.is_admin():
            raise InvalidUsage(
                error="You have no permission to access given user",
                status_code=400)

        return self.get_detail(idx=user_id)
예제 #5
0
    def get_user(self):
        """
        Method to get the user from the request or from the application context

        :return: the user object
        :rtype: :class:`UserBaseModel`
        """
        if self.user is None:
            try:
                self.user = g.user
            except AttributeError:
                self.user = self.auth_class.get_user_from_header(
                    request.headers)
            if self.user is None:
                raise InvalidUsage("Error authenticating the user")
        return self.user
예제 #6
0
    def sign_up(self, **kwargs):
        """
        The method in charge of performing the sign up of users

        :param kwargs: the keyword arguments needed to perform the sign up
        :return: a dictionary with the newly issued token and the user id, and a status code
        """
        auth_type = current_app.config["AUTH_TYPE"]
        if auth_type == AUTH_LDAP:
            raise EndpointNotImplemented(
                "The user has to sign up on the active directory")
        elif auth_type == AUTH_OID:
            raise EndpointNotImplemented(
                "The user has to sign up with the OpenID protocol")

        user = self.data_model(kwargs)

        if user.check_username_in_use():
            raise InvalidCredentials(
                error="Username already in use, please supply another username"
            )

        if user.check_email_in_use():
            raise InvalidCredentials(
                error=
                "Email already in use, please supply another email address")

        user.save()

        user_role = self.user_role_association({
            "user_id":
            user.id,
            "role_id":
            current_app.config["DEFAULT_ROLE"]
        })

        user_role.save()

        try:
            token = self.auth_class.generate_token(user.id)
        except Exception as e:
            raise InvalidUsage(error="Error in generating user token: " +
                               str(e),
                               status_code=400)

        return {"token": token, "id": user.id}, 201
예제 #7
0
    def get_user_from_header(self, headers: Headers = None) -> UserBaseModel:
        """
        Gets the user represented by the token that has to be in the request headers.

        :param headers: the request headers
        :type headers: `Headers`
        :return: the user object
        :rtype: `UserBaseModel`
        """
        if headers is None:
            raise InvalidUsage(
                "Headers are missing from the request. Authentication was not possible to perform"
            )
        token = self.get_token_from_header(headers)
        data = self.decode_token(token)
        user_id = data["user_id"]
        user = self.user_model.get_one_user(user_id)
        if user is None:
            raise ObjectDoesNotExist("User does not exist, invalid token")
        return user
예제 #8
0
    def decode_token(token: str = None) -> dict:
        """
        Decodes a given JSON Web token and extracts the sub from it to give it back.

        :param str token: the given JSON Web Token
        :return: the sub field of the token as the user_id
        :rtype: dict
        """
        if token is None:
            raise InvalidUsage("The provided token is not valid")
        try:
            payload = decode(token,
                             current_app.config["SECRET_KEY"],
                             algorithms="HS256")
            return {"user_id": payload["sub"]}
        except ExpiredSignatureError:
            raise InvalidCredentials(
                "The token has expired, please login again")
        except InvalidTokenError:
            raise InvalidCredentials(
                "Invalid token, please try again with a new token")
예제 #9
0
    def generate_token(user_id: int = None) -> str:
        """
        Generates a token given a user_id with a duration of one day

        :param int user_id: user code to be encoded in the token to identify the user afterwards
        :return: the generated token
        :rtype: str
        """
        if user_id is None:
            raise InvalidUsage(
                "The user id passed to generate the token is not valid.")

        payload = {
            "exp": datetime.utcnow() + timedelta(days=1),
            "iat": datetime.utcnow(),
            "sub": user_id,
        }

        return encode(payload,
                      current_app.config["SECRET_KEY"],
                      algorithm="HS256")