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
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
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
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)
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
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
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
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")
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")