def setNewPassword(self, session): """ Set a new password for a user, request should have keys "user_email" and "password" """ requestDict = RequestDictionary(self.request) if (not (requestDict.exists("user_email") and requestDict.exists("password"))): # Don't have the keys we need in request exc = ResponseException( "Set password route requires keys user_email and password", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) if (not self.checkPassword(requestDict.getValue("password"))): exc = ResponseException("Invalid Password", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) # Get user from email user = self.interfaces.userDb.getUserByEmail( requestDict.getValue("user_email")) # Set new password self.interfaces.userDb.setPassword(user, requestDict.getValue("password"), self.bcrypt) # Invalidate token self.interfaces.userDb.deleteToken(session["token"]) session["reset"] = None # Return success message return JsonResponse.create( StatusCode.OK, {"message": "Password successfully changed"})
def changeStatus(self, system_email): """ Changes status for specified user. Associated request body should have keys 'uid' and 'new_status' arguments: system_email -- (string) the emaily to send emails from return the reponse object with a success message """ requestDict = RequestDictionary(self.request) if (not (requestDict.exists("uid") and requestDict.exists("new_status"))): # Missing a required field, return 400 exc = ResponseException( "Request body must include uid and new_status", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) # Find user that matches specified uid user = self.interfaces.userDb.getUserByUID( int(requestDict.getValue("uid"))) if (user.email == None): return JsonResponse.error( ResponseException("User does not have a defined email", StatusCode.INTERNAL_ERROR), StatusCode.INTERNAL_ERROR) #check if the user is waiting if (self.interfaces.userDb.checkStatus(user, "awaiting_approval")): if (requestDict.getValue("new_status") == "approved"): # Grant agency_user permission to newly approved users self.interfaces.userDb.grantPermission(user, "agency_user") link = AccountHandler.FRONT_END emailTemplate = {'[URL]': link, '[EMAIL]': system_email} newEmail = sesEmail(user.email, system_email, templateType="account_approved", parameters=emailTemplate, database=self.interfaces.userDb) newEmail.send() elif (requestDict.getValue("new_status") == "denied"): emailTemplate = {} newEmail = sesEmail(user.email, system_email, templateType="account_rejected", parameters=emailTemplate, database=self.interfaces.userDb) newEmail.send() # Change user's status self.interfaces.userDb.changeStatus(user, requestDict.getValue("new_status")) return JsonResponse.create(StatusCode.OK, {"message": "Status change successful"})
def getRequestParamsForGenerate(self): """ Pull information out of request object and return it Returns: tuple of submission ID and file type """ requestDict = RequestDictionary(self.request) if not (requestDict.exists("submission_id") and requestDict.exists("file_type")): raise ResponseException("Generate file route requires submission_id and file_type", StatusCode.CLIENT_ERROR) submission_id = requestDict.getValue("submission_id") file_type = requestDict.getValue("file_type") return submission_id, file_type
def setSkipGuide(self, session): """ Set current user's skip guide parameter """ uid = session["name"] userDb = self.interfaces.userDb user = userDb.getUserByUID(uid) requestDict = RequestDictionary(self.request) if not requestDict.exists("skip_guide"): exc = ResponseException("Must include skip_guide parameter", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) skipGuide = requestDict.getValue("skip_guide") if type(skipGuide) == type(True): # param is a bool user.skip_guide = skipGuide elif type(skipGuide) == type("string"): # param is a string, allow "true" or "false" if skipGuide.lower() == "true": user.skip_guide = True elif skipGuide.lower() == "false": user.skip_guide = False else: exc = ResponseException("skip_guide must be true or false", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) else: exc = ResponseException("skip_guide must be a boolean", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) userDb.session.commit() return JsonResponse.create(StatusCode.OK,{"message":"skip_guide set successfully","skip_guide":skipGuide})
def resetPassword(self,system_email,session): """ Remove old password and email user a token to set a new password. Request should have key "email" arguments: system_email -- (string) email used to send messages session -- (Session) object from flask """ requestDict = RequestDictionary(self.request) if(not (requestDict.exists("email"))): # Don't have the keys we need in request exc = ResponseException("Reset password route requires key 'email'",StatusCode.CLIENT_ERROR) return JsonResponse.error(exc,exc.status) # Get user object try: user = self.interfaces.userDb.getUserByEmail(requestDict.getValue("email")) except Exception as e: exc = ResponseException("Unknown Error",StatusCode.CLIENT_ERROR,ValueError) return JsonResponse.error(exc,exc.status) email = requestDict.getValue("email") LoginSession.logout(session) self.sendResetPasswordEmail(user, system_email, email) # Return success message return JsonResponse.create(StatusCode.OK,{"message":"Password reset"})
def listUsersWithStatus(self): """ List all users with the specified status. Associated request body must have key 'status' """ requestDict = RequestDictionary(self.request) if(not (requestDict.exists("status"))): # Missing a required field, return 400 exc = ResponseException("Request body must include status", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc,exc.status) current_user = self.interfaces.userDb.getUserByUID(flaskSession["name"]) try: if self.interfaces.userDb.hasPermission(current_user, "agency_admin"): users = self.interfaces.userDb.getUsersByStatus(requestDict.getValue("status"), current_user.cgac_code) else: users = self.interfaces.userDb.getUsersByStatus(requestDict.getValue("status")) except ValueError as e: # Client provided a bad status exc = ResponseException(str(e),StatusCode.CLIENT_ERROR,ValueError) return JsonResponse.error(exc,exc.status) userInfo = [] for user in users: agency_name = self.interfaces.validationDb.getAgencyName(user.cgac_code) thisInfo = {"name":user.name, "title":user.title, "agency_name":agency_name, "cgac_code":user.cgac_code, "email":user.email, "id":user.user_id } userInfo.append(thisInfo) return JsonResponse.create(StatusCode.OK,{"users":userInfo})
def validate_job(self, request): """ Gets file for job, validates each row, and sends valid rows to a staging table Args: request -- HTTP request containing the jobId Returns: Http response object """ # Create connection to job tracker database sess = GlobalDB.db().session requestDict = RequestDictionary(request) if requestDict.exists('job_id'): job_id = requestDict.getValue('job_id') else: # Request does not have a job ID, can't validate validation_error_type = ValidationError.jobError raise ResponseException('No job ID specified in request', StatusCode.CLIENT_ERROR, None, validation_error_type) # Get the job job = sess.query(Job).filter_by(job_id=job_id).one_or_none() if job is None: validation_error_type = ValidationError.jobError writeFileError(job_id, None, validation_error_type) raise ResponseException( 'Job ID {} not found in database'.format(job_id), StatusCode.CLIENT_ERROR, None, validation_error_type) # Make sure job's prerequisites are complete if not run_job_checks(job_id): validation_error_type = ValidationError.jobError writeFileError(job_id, None, validation_error_type) raise ResponseException( 'Prerequisites for Job ID {} are not complete'.format(job_id), StatusCode.CLIENT_ERROR, None, validation_error_type) # Make sure this is a validation job if job.job_type.name in ('csv_record_validation', 'validation'): job_type_name = job.job_type.name else: validation_error_type = ValidationError.jobError writeFileError(job_id, None, validation_error_type) raise ResponseException( 'Job ID {} is not a validation job (job type is {})'.format( job_id, job.job_type.name), StatusCode.CLIENT_ERROR, None, validation_error_type) # set job status to running and do validations mark_job_status(job_id, "running") if job_type_name == 'csv_record_validation': self.runValidation(job) elif job_type_name == 'validation': self.runCrossValidation(job) else: raise ResponseException("Bad job type for validator", StatusCode.INTERNAL_ERROR) return JsonResponse.create(StatusCode.OK, {"message": "Validation complete"})
def checkPasswordToken(self, session): """ Checks the password token if its valid arguments: session -- (Session) object from flask return the reponse object with a error code and a message """ requestFields = RequestDictionary(self.request) if (not requestFields.exists("token")): exc = ResponseException("Request body must include token", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) token = requestFields.getValue("token") success, message, errorCode = sesEmail.checkToken( token, self.interfaces.userDb, "password_reset") if (success): #mark session that password can be filled out LoginSession.resetPassword(session) return JsonResponse.create(StatusCode.OK, { "email": message, "errorCode": errorCode, "message": "success" }) else: #failure but alert UI of issue return JsonResponse.create(StatusCode.OK, { "errorCode": errorCode, "message": message })
def checkEmailConfirmationToken(self,session): """ Creates user record and email arguments: session -- (Session) object from flask return the reponse object with a error code and a message """ requestFields = RequestDictionary(self.request) if(not requestFields.exists("token")): exc = ResponseException("Request body must include token", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc,exc.status) token = requestFields.getValue("token") success,message,errorCode = sesEmail.checkToken(token,self.interfaces.userDb,"validate_email") if(success): #mark session that email can be filled out LoginSession.register(session) #remove token so it cant be used again # The following line is commented out for issues with registration email links bouncing users back # to the original email input page instead of the registration page #self.interfaces.userDb.deleteToken(token) #set the status only if current status is awaiting confirmation user = self.interfaces.userDb.getUserByEmail(message) if self.interfaces.userDb.checkStatus(user,"awaiting_confirmation"): self.interfaces.userDb.changeStatus(user,"email_confirmed") return JsonResponse.create(StatusCode.OK,{"email":message,"errorCode":errorCode,"message":"success"}) else: #failure but alert UI of issue return JsonResponse.create(StatusCode.OK,{"errorCode":errorCode,"message":message})
def setSkipGuide(self, session): """ Set current user's skip guide parameter """ uid = session["name"] userDb = self.interfaces.userDb user = userDb.getUserByUID(uid) requestDict = RequestDictionary(self.request) if not requestDict.exists("skip_guide"): exc = ResponseException("Must include skip_guide parameter", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) skipGuide = requestDict.getValue("skip_guide") if type(skipGuide) == type(True): # param is a bool user.skip_guide = skipGuide elif type(skipGuide) == type("string"): # param is a string, allow "true" or "false" if skipGuide.lower() == "true": user.skip_guide = True elif skipGuide.lower() == "false": user.skip_guide = False else: exc = ResponseException("skip_guide must be true or false", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) else: exc = ResponseException("skip_guide must be a boolean", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) userDb.session.commit() return JsonResponse.create(StatusCode.OK, { "message": "skip_guide set successfully", "skip_guide": skipGuide })
def resetPassword(self,system_email,session): """ Remove old password and email user a token to set a new password. Request should have key "email" arguments: system_email -- (string) email used to send messages session -- (Session) object from flask """ requestDict = RequestDictionary(self.request) if(not (requestDict.exists("email"))): # Don't have the keys we need in request exc = ResponseException("Reset password route requires key 'email'",StatusCode.CLIENT_ERROR) return JsonResponse.error(exc,exc.status) # Get user object try: user = self.interfaces.userDb.getUserByEmail(requestDict.getValue("email")) except Exception as e: exc = ResponseException("Unknown Error",StatusCode.CLIENT_ERROR,ValueError) return JsonResponse.error(exc,exc.status) LoginSession.logout(session) self.interfaces.userDb.session.commit() email = requestDict.getValue("email") # Send email with token emailToken = sesEmail.createToken(email,self.interfaces.userDb,"password_reset") link= "".join([ AccountHandler.FRONT_END,'#/forgotpassword/',emailToken]) emailTemplate = { '[URL]':link} newEmail = sesEmail(user.email, system_email,templateType="reset_password",parameters=emailTemplate,database=self.interfaces.userDb) newEmail.send() # Return success message return JsonResponse.create(StatusCode.OK,{"message":"Password reset"})
def createEmailConfirmation(self,system_email,session): """ Creates user record and email arguments: system_email -- (string) email used to send messages session -- (Session) object from flask """ requestFields = RequestDictionary(self.request) if(not requestFields.exists("email")): exc = ResponseException("Request body must include email", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc,exc.status) email = requestFields.getValue("email") if( not re.match("[^@]+@[^@]+\.[^@]+",email)) : return JsonResponse.error(ValueError("Invalid Email Format"),StatusCode.CLIENT_ERROR) try : user = self.interfaces.userDb.getUserByEmail(requestFields.getValue("email")) except ResponseException as e: self.interfaces.userDb.addUnconfirmedEmail(email) else: if(not (user.user_status_id == self.interfaces.userDb.getUserStatusId("awaiting_confirmation") or user.user_status_id == self.interfaces.userDb.getUserStatusId("email_confirmed"))): exc = ResponseException("User already registered", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc,exc.status) emailToken = sesEmail.createToken(email,self.interfaces.userDb,"validate_email") link= "".join([AccountHandler.FRONT_END,'#/registration/',emailToken]) emailTemplate = {'[USER]': email, '[URL]':link} newEmail = sesEmail(email, system_email,templateType="validate_email",parameters=emailTemplate,database=self.interfaces.userDb) newEmail.send() return JsonResponse.create(StatusCode.OK,{"message":"Email Sent"})
def listUsersWithStatus(self): """ List all users with the specified status. Associated request body must have key 'status' """ requestDict = RequestDictionary(self.request) if (not (requestDict.exists("status"))): # Missing a required field, return 400 exc = ResponseException("Request body must include status", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) try: users = self.interfaces.userDb.getUsersByStatus( requestDict.getValue("status")) except ValueError as e: # Client provided a bad status exc = ResponseException(str(e), StatusCode.CLIENT_ERROR, ValueError) return JsonResponse.error(exc, exc.status) userInfo = [] for user in users: thisInfo = { "name": user.name, "title": user.title, "agency": user.agency, "email": user.email, "id": user.user_id } userInfo.append(thisInfo) return JsonResponse.create(StatusCode.OK, {"users": userInfo})
def checkPasswordToken(self,session): """ Checks the password token if its valid arguments: session -- (Session) object from flask return the reponse object with a error code and a message """ requestFields = RequestDictionary(self.request) if(not requestFields.exists("token")): exc = ResponseException("Request body must include token", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc,exc.status) token = requestFields.getValue("token") success,message,errorCode = sesEmail.checkToken(token,self.interfaces.userDb,"password_reset") if(success): #mark session that password can be filled out LoginSession.resetPassword(session) return JsonResponse.create(StatusCode.OK,{"email":message,"errorCode":errorCode,"message":"success"}) else: #failure but alert UI of issue return JsonResponse.create(StatusCode.OK,{"errorCode":errorCode,"message":message})
def resetPassword(self, system_email, session): """ Remove old password and email user a token to set a new password. Request should have key "email" arguments: system_email -- (string) email used to send messages session -- (Session) object from flask """ requestDict = RequestDictionary(self.request) if (not (requestDict.exists("email"))): # Don't have the keys we need in request exc = ResponseException( "Reset password route requires key 'email'", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) # Get user object try: user = self.interfaces.userDb.getUserByEmail( requestDict.getValue("email")) except Exception as e: exc = ResponseException("Unknown Error", StatusCode.CLIENT_ERROR, ValueError) return JsonResponse.error(exc, exc.status) email = requestDict.getValue("email") LoginSession.logout(session) self.sendResetPasswordEmail(user, system_email, email) # Return success message return JsonResponse.create(StatusCode.OK, {"message": "Password reset"})
def emailUsers(self, system_email, session): """ Send email notification to list of users """ requestDict = RequestDictionary(self.request) if not (requestDict.exists("users") and requestDict.exists("submission_id") and requestDict.exists("email_template")): exc = ResponseException( "Email users route requires users, email_template, and submission_id", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) uid = session["name"] current_user = self.interfaces.userDb.getUserByUID(uid) user_ids = requestDict.getValue("users") submission_id = requestDict.getValue("submission_id") # Check if submission id is valid self.jobManager.getSubmissionById(submission_id) template_type = requestDict.getValue("email_template") # Check if email template type is valid self.userManager.getEmailTemplate(template_type) users = [] link = "".join( [AccountHandler.FRONT_END, '#/reviewData/', str(submission_id)]) emailTemplate = { '[REV_USER_NAME]': current_user.name, '[REV_URL]': link } for user_id in user_ids: # Check if user id is valid, if so add User object to array users.append(self.userManager.getUserByUID(user_id)) for user in users: newEmail = sesEmail(user.email, system_email, templateType=template_type, parameters=emailTemplate, database=UserHandler()) newEmail.send() return JsonResponse.create(StatusCode.OK, {"message": "Emails successfully sent"})
def setNewPassword(self): """ Set a new password for a user, request should have keys "user_email" and "password" """ requestDict = RequestDictionary(self.request) if(not (requestDict.exists("user_email") and requestDict.exists("password"))): # Don't have the keys we need in request exc = ResponseException("Set password route requires keys user_email and password",StatusCode.CLIENT_ERROR) return JsonResponse.error(exc,exc.status) if(not self.checkPassword(requestDict.getValue("password"))): exc = ResponseException("Invalid Password", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc,exc.status) # Get user from email user = self.interfaces.userDb.getUserByEmail(requestDict.getValue("user_email")) # Set new password self.interfaces.userDb.setPassword(user,requestDict.getValue("password"),self.bcrypt) # Return success message return JsonResponse.create(StatusCode.OK,{"message":"Password successfully changed"})
def deleteUser(self): """ Deletes user specified by 'email' in request """ requestDict = RequestDictionary(self.request) if not requestDict.exists("email"): # missing required fields, return 400 exc = ResponseException( "Request body must include email of user to be deleted", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) email = requestDict.getValue("email") self.interfaces.userDb.deleteUser(email) return JsonResponse.create(StatusCode.OK, {"message": "success"})
def changeStatus(self,system_email): """ Changes status for specified user. Associated request body should have keys 'uid' and 'new_status' arguments: system_email -- (string) the emaily to send emails from return the reponse object with a success message """ requestDict = RequestDictionary(self.request) if(not (requestDict.exists("uid") and requestDict.exists("new_status"))): # Missing a required field, return 400 exc = ResponseException("Request body must include uid and new_status", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc,exc.status) # Find user that matches specified uid user = self.interfaces.userDb.getUserByUID(int(requestDict.getValue("uid"))) if(user.email == None): return JsonResponse.error(ResponseException("User does not have a defined email",StatusCode.INTERNAL_ERROR),StatusCode.INTERNAL_ERROR) #check if the user is waiting if(self.interfaces.userDb.checkStatus(user,"awaiting_approval")): if(requestDict.getValue("new_status") == "approved"): # Grant agency_user permission to newly approved users self.interfaces.userDb.grantPermission(user,"agency_user") link= AccountHandler.FRONT_END emailTemplate = { '[URL]':link,'[EMAIL]':system_email} newEmail = sesEmail(user.email, system_email,templateType="account_approved",parameters=emailTemplate,database=self.interfaces.userDb) newEmail.send() elif (requestDict.getValue("new_status") == "denied"): emailTemplate = {} newEmail = sesEmail(user.email, system_email,templateType="account_rejected",parameters=emailTemplate,database=self.interfaces.userDb) newEmail.send() # Change user's status self.interfaces.userDb.changeStatus(user,requestDict.getValue("new_status")) return JsonResponse.create(StatusCode.OK,{"message":"Status change successful"})
def getJobID(request): """ Pull job ID out of request Args: request: HTTP request containing the job ID Returns: job ID, or raises exception if job ID not found in request """ requestDict = RequestDictionary(request) if(requestDict.exists("job_id")): jobId = requestDict.getValue("job_id") return jobId else: # Request does not have a job ID, can't validate raise ResponseException("No job ID specified in request",StatusCode.CLIENT_ERROR)
def getJobID(request): """ Pull job ID out of request Args: request: HTTP request containing the job ID Returns: job ID, or raises exception if job ID not found in request """ requestDict = RequestDictionary(request) if (requestDict.exists("job_id")): jobId = requestDict.getValue("job_id") return jobId else: # Request does not have a job ID, can't validate raise ResponseException("No job ID specified in request", StatusCode.CLIENT_ERROR)
def listUsers(self): """ List all users ordered by status. Associated request body must have key 'filter_by' """ requestDict = RequestDictionary(self.request, optionalRequest=True) user_status = requestDict.getValue("status") if requestDict.exists( "status") else "all" user = self.interfaces.userDb.getUserByUID( LoginSession.getName(flaskSession)) isAgencyAdmin = self.userManager.hasPermission( user, "agency_admin") and not self.userManager.hasPermission( user, "website_admin") try: if isAgencyAdmin: users = self.interfaces.userDb.getUsers( cgac_code=user.cgac_code, status=user_status) else: users = self.interfaces.userDb.getUsers(status=user_status) except ValueError as e: # Client provided a bad status exc = ResponseException(str(e), StatusCode.CLIENT_ERROR, ValueError) return JsonResponse.error(exc, exc.status) userInfo = [] for user in users: agency_name = self.interfaces.validationDb.getAgencyName( user.cgac_code) thisInfo = { "name": user.name, "title": user.title, "agency_name": agency_name, "cgac_code": user.cgac_code, "email": user.email, "id": user.user_id, "is_active": user.is_active, "permissions": ",".join(self.interfaces.userDb.getUserPermissions(user)), "status": user.user_status.name } userInfo.append(thisInfo) return JsonResponse.create(StatusCode.OK, {"users": userInfo})
def checkEmailConfirmationToken(self, session): """ Creates user record and email arguments: session -- (Session) object from flask return the reponse object with a error code and a message """ requestFields = RequestDictionary(self.request) if (not requestFields.exists("token")): exc = ResponseException("Request body must include token", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) token = requestFields.getValue("token") session["token"] = token success, message, errorCode = sesEmail.checkToken( token, self.interfaces.userDb, "validate_email") if (success): #mark session that email can be filled out LoginSession.register(session) #remove token so it cant be used again # The following line is commented out for issues with registration email links bouncing users back # to the original email input page instead of the registration page #self.interfaces.userDb.deleteToken(token) #set the status only if current status is awaiting confirmation user = self.interfaces.userDb.getUserByEmail(message) if self.interfaces.userDb.checkStatus(user, "awaiting_confirmation"): self.interfaces.userDb.changeStatus(user, "email_confirmed") return JsonResponse.create(StatusCode.OK, { "email": message, "errorCode": errorCode, "message": "success" }) else: #failure but alert UI of issue return JsonResponse.create(StatusCode.OK, { "errorCode": errorCode, "message": message })
def resetPassword(self, system_email, session): """ Remove old password and email user a token to set a new password. Request should have key "email" arguments: system_email -- (string) email used to send messages session -- (Session) object from flask """ requestDict = RequestDictionary(self.request) if (not (requestDict.exists("email"))): # Don't have the keys we need in request exc = ResponseException( "Reset password route requires key 'email'", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) # Get user object try: user = self.interfaces.userDb.getUserByEmail( requestDict.getValue("email")) except Exception as e: exc = ResponseException("Unknown Error", StatusCode.CLIENT_ERROR, ValueError) return JsonResponse.error(exc, exc.status) LoginSession.logout(session) self.interfaces.userDb.session.commit() email = requestDict.getValue("email") # Send email with token emailToken = sesEmail.createToken(email, self.interfaces.userDb, "password_reset") link = "".join( [AccountHandler.FRONT_END, '#/forgotpassword/', emailToken]) emailTemplate = {'[URL]': link} newEmail = sesEmail(user.email, system_email, templateType="reset_password", parameters=emailTemplate, database=self.interfaces.userDb) newEmail.send() # Return success message return JsonResponse.create(StatusCode.OK, {"message": "Password reset"})
def createEmailConfirmation(self, system_email, session): """ Creates user record and email arguments: system_email -- (string) email used to send messages session -- (Session) object from flask """ requestFields = RequestDictionary(self.request) if (not requestFields.exists("email")): exc = ResponseException("Request body must include email", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) email = requestFields.getValue("email") if (not re.match("[^@]+@[^@]+\.[^@]+", email)): return JsonResponse.error(ValueError("Invalid Email Format"), StatusCode.CLIENT_ERROR) try: user = self.interfaces.userDb.getUserByEmail( requestFields.getValue("email")) except ResponseException as e: self.interfaces.userDb.addUnconfirmedEmail(email) else: if (not (user.user_status_id == self.interfaces.userDb. getUserStatusId("awaiting_confirmation") or user.user_status_id == self.interfaces.userDb. getUserStatusId("email_confirmed"))): exc = ResponseException("User already registered", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) emailToken = sesEmail.createToken(email, self.interfaces.userDb, "validate_email") link = "".join( [AccountHandler.FRONT_END, '#/registration/', emailToken]) emailTemplate = {'[USER]': email, '[URL]': link} newEmail = sesEmail(email, system_email, templateType="validate_email", parameters=emailTemplate, database=self.interfaces.userDb) newEmail.send() return JsonResponse.create(StatusCode.OK, {"message": "Email Sent"})
def listUsersWithStatus(self): """ List all users with the specified status. Associated request body must have key 'status' """ requestDict = RequestDictionary(self.request) if(not (requestDict.exists("status"))): # Missing a required field, return 400 exc = ResponseException("Request body must include status", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc,exc.status) try: users = self.interfaces.userDb.getUsersByStatus(requestDict.getValue("status")) except ValueError as e: # Client provided a bad status exc = ResponseException(str(e),StatusCode.CLIENT_ERROR,ValueError) return JsonResponse.error(exc,exc.status) userInfo = [] for user in users: thisInfo = {"name":user.name, "title":user.title, "agency":user.agency, "email":user.email, "id":user.user_id } userInfo.append(thisInfo) return JsonResponse.create(StatusCode.OK,{"users":userInfo})
def completeGeneration(self, generationId): """ For files D1 and D2, the API uses this route as a callback to load the generated file. Requires an 'href' key in the request that specifies the URL of the file to be downloaded Args: generationId - Unique key stored in file_generation_task table, used in callback to identify which submission this file is for. """ if generationId is None: return JsonResponse.error(ResponseException("Must include a generation ID",StatusCode.CLIENT_ERROR), StatusCode.CLIENT_ERROR) self.smx_log_file_name = "smx_request.log" # Pull url from request safeDictionary = RequestDictionary(self.request) CloudLogger.log("DEBUG: Request content => " + safeDictionary.to_string(), log_type="debug", file_name=self.smx_log_file_name) if not safeDictionary.exists("href"): return JsonResponse.error(ResponseException("Request must include href key with URL of D file", StatusCode.CLIENT_ERROR), StatusCode.CLIENT_ERROR) url = safeDictionary.getValue("href") CloudLogger.log("DEBUG: Download URL => " + url, log_type="debug", file_name=self.smx_log_file_name) #Pull information based on task key try: CloudLogger.log("DEBUG: Pulling information based on task key...", log_type="debug", file_name=self.smx_log_file_name) task = self.interfaces.jobDb.session.query(FileGenerationTask).options(joinedload(FileGenerationTask.file_type)).filter(FileGenerationTask.generation_task_key == generationId).one() job = self.interfaces.jobDb.getJobById(task.job_id) CloudLogger.log("DEBUG: Loading D file...", log_type="debug", file_name=self.smx_log_file_name) result = self.load_d_file(url,job.filename,job.original_filename,job.job_id,self.isLocal) CloudLogger.log("DEBUG: Load D file result => " + str(result), log_type="debug", file_name=self.smx_log_file_name) return JsonResponse.create(StatusCode.OK,{"message":"File loaded successfully"}) except ResponseException as e: return JsonResponse.error(e, e.status) except NoResultFound as e: # Did not find file generation task return JsonResponse.error(ResponseException("Generation task key not found", StatusCode.CLIENT_ERROR), StatusCode.CLIENT_ERROR)
def listUsersWithStatus(self): """ List all users with the specified status. Associated request body must have key 'status' """ requestDict = RequestDictionary(self.request) if (not (requestDict.exists("status"))): # Missing a required field, return 400 exc = ResponseException("Request body must include status", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) current_user = self.interfaces.userDb.getUserByUID( flaskSession["name"]) try: if self.interfaces.userDb.hasPermission(current_user, "agency_admin"): users = self.interfaces.userDb.getUsersByStatus( requestDict.getValue("status"), current_user.cgac_code) else: users = self.interfaces.userDb.getUsersByStatus( requestDict.getValue("status")) except ValueError as e: # Client provided a bad status exc = ResponseException(str(e), StatusCode.CLIENT_ERROR, ValueError) return JsonResponse.error(exc, exc.status) userInfo = [] for user in users: agency_name = self.interfaces.validationDb.getAgencyName( user.cgac_code) thisInfo = { "name": user.name, "title": user.title, "agency_name": agency_name, "cgac_code": user.cgac_code, "email": user.email, "id": user.user_id } userInfo.append(thisInfo) return JsonResponse.create(StatusCode.OK, {"users": userInfo})
def submit(self,name,CreateCredentials): """ Builds S3 URLs for a set of files and adds all related jobs to job tracker database Flask request should include keys from FILE_TYPES class variable above Arguments: name -- User ID from the session handler Returns: Flask response returned will have key_url and key_id for each key in the request key_url is the S3 URL for uploading key_id is the job id to be passed to the finalize_submission route """ try: responseDict= {} fileNameMap = [] safeDictionary = RequestDictionary(self.request) submissionId = self.jobManager.createSubmission(name, safeDictionary) existingSubmission = False if safeDictionary.exists("existing_submission_id"): existingSubmission = True # Check if user has permission to specified submission self.checkSubmissionPermission(self.jobManager.getSubmissionById(submissionId)) for fileType in FileHandler.FILE_TYPES : # If filetype not included in request, and this is an update to an existing submission, skip it if not safeDictionary.exists(fileType): if existingSubmission: continue else: # This is a new submission, all files are required raise ResponseException("Must include all files for new submission",StatusCode.CLIENT_ERROR) filename = safeDictionary.getValue(fileType) if( safeDictionary.exists(fileType)) : if(not self.isLocal): uploadName = str(name)+"/"+s3UrlHandler.getTimestampedFilename(filename) else: uploadName = filename responseDict[fileType+"_key"] = uploadName fileNameMap.append((fileType,uploadName,filename)) fileJobDict = self.jobManager.createJobs(fileNameMap,submissionId,existingSubmission) for fileType in fileJobDict.keys(): if (not "submission_id" in fileType) : responseDict[fileType+"_id"] = fileJobDict[fileType] if(CreateCredentials and not self.isLocal) : self.s3manager = s3UrlHandler(CONFIG_BROKER["aws_bucket"]) responseDict["credentials"] = self.s3manager.getTemporaryCredentials(name) else : responseDict["credentials"] ={"AccessKeyId" : "local","SecretAccessKey" :"local","SessionToken":"local" ,"Expiration" :"local"} responseDict["submission_id"] = fileJobDict["submission_id"] if self.isLocal: responseDict["bucket_name"] = CONFIG_BROKER["broker_files"] else: responseDict["bucket_name"] = CONFIG_BROKER["aws_bucket"] return JsonResponse.create(StatusCode.OK,responseDict) except (ValueError , TypeError, NotImplementedError) as e: return JsonResponse.error(e,StatusCode.CLIENT_ERROR) except Exception as e: # Unexpected exception, this is a 500 server error return JsonResponse.error(e,StatusCode.INTERNAL_ERROR) except: return JsonResponse.error(Exception("Failed to catch exception"),StatusCode.INTERNAL_ERROR)
def register(self, system_email, session): """ Save user's information into user database. Associated request body should have keys 'email', 'name', 'cgac_code', and 'title' arguments: system_email -- (string) email used to send messages session -- (Session) object from flask Returns message that registration is successful or error message that fields are not valid """ def ThreadedFunction(from_email="", username="", title="", cgac_code="", userEmail="", link=""): """ This inner function sends emails in a new thread as there could be lots of admins from_email -- (string) the from email address username -- (string) the name of the user title -- (string) the title of the user agency -- (string) the agency of the user userEmail -- (string) the email of the user link -- (string) the broker email link """ threadedDatabase = UserHandler() try: agency_name = self.interfaces.validationDb.getAgencyName( cgac_code) agency_name = "Unknown" if agency_name is None else agency_name for user in threadedDatabase.getUsersByType("website_admin"): emailTemplate = { '[REG_NAME]': username, '[REG_TITLE]': title, '[REG_AGENCY_NAME]': agency_name, '[REG_CGAC_CODE]': cgac_code, '[REG_EMAIL]': userEmail, '[URL]': link } newEmail = sesEmail(user.email, system_email, templateType="account_creation", parameters=emailTemplate, database=threadedDatabase) newEmail.send() for user in threadedDatabase.getUsersByType("agency_admin"): if user.cgac_code == cgac_code: emailTemplate = { '[REG_NAME]': username, '[REG_TITLE]': title, '[REG_AGENCY_NAME]': agency_name, '[REG_CGAC_CODE]': cgac_code, '[REG_EMAIL]': userEmail, '[URL]': link } newEmail = sesEmail(user.email, system_email, templateType="account_creation", parameters=emailTemplate, database=threadedDatabase) newEmail.send() finally: threadedDatabase.close() requestFields = RequestDictionary(self.request) if (not (requestFields.exists("email") and requestFields.exists("name") and requestFields.exists("cgac_code") and requestFields.exists("title") and requestFields.exists("password"))): # Missing a required field, return 400 exc = ResponseException( "Request body must include email, name, cgac_code, title, and password", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) if (not self.checkPassword(requestFields.getValue("password"))): exc = ResponseException("Invalid Password", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) # Find user that matches specified email user = self.interfaces.userDb.getUserByEmail( requestFields.getValue("email")) # Check that user's status is before submission of registration if not (self.interfaces.userDb.checkStatus(user, "awaiting_confirmation") or self.interfaces.userDb.checkStatus(user, "email_confirmed")): # Do not allow duplicate registrations exc = ResponseException("User already registered", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) # Add user info to database self.interfaces.userDb.addUserInfo(user, requestFields.getValue("name"), requestFields.getValue("cgac_code"), requestFields.getValue("title")) self.interfaces.userDb.setPassword(user, requestFields.getValue("password"), self.bcrypt) userLink = "".join( [AccountHandler.FRONT_END, '#/login?redirect=/admin']) # Send email to approver list emailThread = Thread(target=ThreadedFunction, kwargs=dict(from_email=system_email, username=user.name, title=user.title, cgac_code=user.cgac_code, userEmail=user.email, link=userLink)) emailThread.start() #email user link = AccountHandler.FRONT_END emailTemplate = {'[EMAIL]': system_email} newEmail = sesEmail(user.email, system_email, templateType="account_creation_user", parameters=emailTemplate, database=self.interfaces.userDb) newEmail.send() # Logout and delete token LoginSession.logout(session) self.interfaces.userDb.deleteToken(session["token"]) # Mark user as awaiting approval self.interfaces.userDb.changeStatus(user, "awaiting_approval") return JsonResponse.create(StatusCode.OK, {"message": "Registration successful"})
def updateUser(self, system_email): """ Update editable fields for specified user. Editable fields for a user: * is_active * user_status_id * permissions Args: None: Request body should contain the following keys: * uid (integer) * status (string) * permissions (comma separated string) * is_active (boolean) Returns: JSON response object with either an exception or success message """ requestDict = RequestDictionary(self.request) # throw an exception if nothing is provided in the request if not requestDict.exists("uid") or not ( requestDict.exists("status") or requestDict.exists("permissions") or requestDict.exists("is_active")): # missing required fields, return 400 exc = ResponseException( "Request body must include uid and at least one of the following: status, permissions, is_active", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) # Find user that matches specified uid user = self.interfaces.userDb.getUserByUID( int(requestDict.getValue("uid"))) if requestDict.exists("status"): #check if the user is waiting if (self.interfaces.userDb.checkStatus(user, "awaiting_approval")): if (requestDict.getValue("status") == "approved"): # Grant agency_user permission to newly approved users self.interfaces.userDb.grantPermission(user, "agency_user") link = AccountHandler.FRONT_END emailTemplate = {'[URL]': link, '[EMAIL]': system_email} newEmail = sesEmail(user.email, system_email, templateType="account_approved", parameters=emailTemplate, database=self.interfaces.userDb) newEmail.send() elif (requestDict.getValue("status") == "denied"): emailTemplate = {} newEmail = sesEmail(user.email, system_email, templateType="account_rejected", parameters=emailTemplate, database=self.interfaces.userDb) newEmail.send() # Change user's status self.interfaces.userDb.changeStatus(user, requestDict.getValue("status")) if requestDict.exists("permissions"): permissions_list = requestDict.getValue("permissions").split(',') # Remove all existing permissions for user user_permissions = self.interfaces.userDb.getUserPermissions(user) for permission in user_permissions: self.interfaces.userDb.removePermission(user, permission) # Grant specified permissions for permission in permissions_list: self.interfaces.userDb.grantPermission(user, permission) # Activate/deactivate user if requestDict.exists("is_active"): is_active = bool(requestDict.getValue("is_active")) if not self.isUserActive(user) and is_active: # Reset password count to 0 self.resetPasswordCount(user) # Reset last login date so the account isn't expired self.interfaces.userDb.updateLastLogin(user, unlock_user=True) self.sendResetPasswordEmail(user, system_email, unlock_user=True) self.interfaces.userDb.setUserActive(user, is_active) return JsonResponse.create(StatusCode.OK, {"message": "User successfully updated"})
def updateUser(self, system_email): """ Update editable fields for specified user. Editable fields for a user: * is_active * user_status_id * permissions Args: None: Request body should contain the following keys: * uid (integer) * status (string) * permissions (comma separated string) * is_active (boolean) Returns: JSON response object with either an exception or success message """ requestDict = RequestDictionary(self.request) # throw an exception if nothing is provided in the request if not requestDict.exists("uid") or not (requestDict.exists("status") or requestDict.exists("permissions") or requestDict.exists("is_active")): # missing required fields, return 400 exc = ResponseException("Request body must include uid and at least one of the following: status, permissions, is_active", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc, exc.status) # Find user that matches specified uid user = self.interfaces.userDb.getUserByUID(int(requestDict.getValue("uid"))) if requestDict.exists("status"): #check if the user is waiting if(self.interfaces.userDb.checkStatus(user,"awaiting_approval")): if(requestDict.getValue("status") == "approved"): # Grant agency_user permission to newly approved users self.interfaces.userDb.grantPermission(user,"agency_user") link= AccountHandler.FRONT_END emailTemplate = { '[URL]':link,'[EMAIL]':system_email} newEmail = sesEmail(user.email, system_email,templateType="account_approved",parameters=emailTemplate,database=self.interfaces.userDb) newEmail.send() elif (requestDict.getValue("status") == "denied"): emailTemplate = {} newEmail = sesEmail(user.email, system_email,templateType="account_rejected",parameters=emailTemplate,database=self.interfaces.userDb) newEmail.send() # Change user's status self.interfaces.userDb.changeStatus(user,requestDict.getValue("status")) if requestDict.exists("permissions"): permissions_list = requestDict.getValue("permissions").split(',') # Remove all existing permissions for user user_permissions = self.interfaces.userDb.getUserPermissions(user) for permission in user_permissions: self.interfaces.userDb.removePermission(user, permission) # Grant specified permissions for permission in permissions_list: self.interfaces.userDb.grantPermission(user, permission) # Activate/deactivate user if requestDict.exists("is_active"): is_active = bool(requestDict.getValue("is_active")) if not self.isUserActive(user) and is_active: # Reset password count to 0 self.resetPasswordCount(user) # Reset last login date so the account isn't expired self.interfaces.userDb.updateLastLogin(user, unlock_user=True) self.sendResetPasswordEmail(user, system_email, unlock_user=True) self.interfaces.userDb.setUserActive(user, is_active) return JsonResponse.create(StatusCode.OK, {"message": "User successfully updated"})
def validateJob(self, request, interfaces): """ Gets file for job, validates each row, and sends valid rows to staging database Args: request -- HTTP request containing the jobId interfaces -- InterfaceHolder object to the databases Returns: Http response object """ # Create connection to job tracker database self.filename = None tableName = "" jobId = None jobTracker = None try: jobTracker = interfaces.jobDb requestDict = RequestDictionary(request) tableName = "" if (requestDict.exists("job_id")): jobId = requestDict.getValue("job_id") else: # Request does not have a job ID, can't validate raise ResponseException("No job ID specified in request", StatusCode.CLIENT_ERROR) # Check that job exists and is ready if (not (jobTracker.runChecks(jobId))): raise ResponseException("Checks failed on Job ID", StatusCode.CLIENT_ERROR) tableName = interfaces.stagingDb.getTableName(jobId) jobType = interfaces.jobDb.checkJobType(jobId) except ResponseException as e: CloudLogger.logError(str(e), e, traceback.extract_tb(sys.exc_info()[2])) if (e.errorType == None): # Error occurred while trying to get and check job ID e.errorType = ValidationError.jobError interfaces.errorDb.writeFileError(jobId, self.filename, e.errorType, e.extraInfo) return JsonResponse.error(e, e.status, table=tableName) except Exception as e: exc = ResponseException(str(e), StatusCode.INTERNAL_ERROR, type(e)) CloudLogger.logError(str(e), e, traceback.extract_tb(sys.exc_info()[2])) self.markJob(jobId, jobTracker, "failed", interfaces.errorDb, self.filename, ValidationError.unknownError) return JsonResponse.error(exc, exc.status, table=tableName) try: jobTracker.markJobStatus(jobId, "running") if jobType == interfaces.jobDb.getJobTypeId( "csv_record_validation"): self.runValidation(jobId, interfaces) elif jobType == interfaces.jobDb.getJobTypeId("validation"): self.runCrossValidation(jobId, interfaces) else: raise ResponseException("Bad job type for validator", StatusCode.INTERNAL_ERROR) interfaces.errorDb.markFileComplete(jobId, self.filename) return JsonResponse.create(StatusCode.OK, {"table": tableName}) except ResponseException as e: CloudLogger.logError(str(e), e, traceback.extract_tb(sys.exc_info()[2])) self.markJob(jobId, jobTracker, "invalid", interfaces.errorDb, self.filename, e.errorType, e.extraInfo) return JsonResponse.error(e, e.status, table=tableName) except ValueError as e: CloudLogger.logError(str(e), e, traceback.extract_tb(sys.exc_info()[2])) # Problem with CSV headers exc = ResponseException( str(e), StatusCode.CLIENT_ERROR, type(e), ValidationError.unknownError) #"Internal value error" self.markJob(jobId, jobTracker, "invalid", interfaces.errorDb, self.filename, ValidationError.unknownError) return JsonResponse.error(exc, exc.status, table=tableName) except Error as e: CloudLogger.logError(str(e), e, traceback.extract_tb(sys.exc_info()[2])) # CSV file not properly formatted (usually too much in one field) exc = ResponseException("Internal error", StatusCode.CLIENT_ERROR, type(e), ValidationError.unknownError) self.markJob(jobId, jobTracker, "invalid", interfaces.errorDb, self.filename, ValidationError.unknownError) return JsonResponse.error(exc, exc.status, table=tableName) except Exception as e: CloudLogger.logError(str(e), e, traceback.extract_tb(sys.exc_info()[2])) exc = ResponseException(str(e), StatusCode.INTERNAL_ERROR, type(e), ValidationError.unknownError) self.markJob(jobId, jobTracker, "failed", interfaces.errorDb, self.filename, ValidationError.unknownError) return JsonResponse.error(exc, exc.status, table=tableName)
def register(self,system_email,session): """ Save user's information into user database. Associated request body should have keys 'email', 'name', 'agency', and 'title' arguments: system_email -- (string) email used to send messages session -- (Session) object from flask Returns message that registration is successful or error message that fields are not valid """ def ThreadedFunction (from_email="",username="",title="",agency="",userEmail="" ,link="") : """ This inner function sends emails in a new thread as there could be lots of admins from_email -- (string) the from email address username -- (string) the name of the user title -- (string) the title of the user agency -- (string) the agency of the user userEmail -- (string) the email of the user link -- (string) the broker email link """ threadedDatabase = UserHandler() try: for user in threadedDatabase.getUsersByType("website_admin") : emailTemplate = {'[REG_NAME]': username, '[REG_TITLE]':title, '[REG_AGENCY]':agency,'[REG_EMAIL]' : userEmail,'[URL]':link} newEmail = sesEmail(user.email, system_email,templateType="account_creation",parameters=emailTemplate,database=threadedDatabase) newEmail.send() finally: InterfaceHolder.closeOne(threadedDatabase) requestFields = RequestDictionary(self.request) if(not (requestFields.exists("email") and requestFields.exists("name") and requestFields.exists("agency") and requestFields.exists("title") and requestFields.exists("password"))): # Missing a required field, return 400 exc = ResponseException("Request body must include email, name, agency, title, and password", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc,exc.status) if(not self.checkPassword(requestFields.getValue("password"))): exc = ResponseException("Invalid Password", StatusCode.CLIENT_ERROR) return JsonResponse.error(exc,exc.status) # Find user that matches specified email user = self.interfaces.userDb.getUserByEmail(requestFields.getValue("email")) # Check that user's status is before submission of registration if not (self.interfaces.userDb.checkStatus(user,"awaiting_confirmation") or self.interfaces.userDb.checkStatus(user,"email_confirmed")): # Do not allow duplicate registrations exc = ResponseException("User already registered",StatusCode.CLIENT_ERROR) return JsonResponse.error(exc,exc.status) # Add user info to database self.interfaces.userDb.addUserInfo(user,requestFields.getValue("name"),requestFields.getValue("agency"),requestFields.getValue("title")) self.interfaces.userDb.setPassword(user,requestFields.getValue("password"),self.bcrypt) userLink= "".join([AccountHandler.FRONT_END, '#/login?redirect=/admin']) # Send email to approver list emailThread = Thread(target=ThreadedFunction, kwargs=dict(from_email=system_email,username=user.name,title=user.title,agency=user.agency,userEmail=user.email,link=userLink)) emailThread.start() #email user link= AccountHandler.FRONT_END emailTemplate = {'[EMAIL]' : system_email} newEmail = sesEmail(user.email, system_email,templateType="account_creation_user",parameters=emailTemplate,database=self.interfaces.userDb) newEmail.send() LoginSession.logout(session) # Mark user as awaiting approval self.interfaces.userDb.changeStatus(user,"awaiting_approval") return JsonResponse.create(StatusCode.OK,{"message":"Registration successful"})
def validateJob(self, request,interfaces): """ Gets file for job, validates each row, and sends valid rows to staging database Args: request -- HTTP request containing the jobId interfaces -- InterfaceHolder object to the databases Returns: Http response object """ # Create connection to job tracker database self.filename = None tableName = "" jobId = None jobTracker = None try: jobTracker = interfaces.jobDb requestDict = RequestDictionary(request) tableName = "" if(requestDict.exists("job_id")): jobId = requestDict.getValue("job_id") else: # Request does not have a job ID, can't validate raise ResponseException("No job ID specified in request",StatusCode.CLIENT_ERROR) # Check that job exists and is ready if(not (jobTracker.runChecks(jobId))): raise ResponseException("Checks failed on Job ID",StatusCode.CLIENT_ERROR) tableName = interfaces.stagingDb.getTableName(jobId) jobType = interfaces.jobDb.checkJobType(jobId) except ResponseException as e: CloudLogger.logError(str(e),e,traceback.extract_tb(sys.exc_info()[2])) if(e.errorType == None): # Error occurred while trying to get and check job ID e.errorType = ValidationError.jobError interfaces.errorDb.writeFileError(jobId,self.filename,e.errorType,e.extraInfo) return JsonResponse.error(e,e.status,table=tableName) except Exception as e: exc = ResponseException(str(e),StatusCode.INTERNAL_ERROR,type(e)) CloudLogger.logError(str(e),e,traceback.extract_tb(sys.exc_info()[2])) self.markJob(jobId,jobTracker,"failed",interfaces.errorDb,self.filename,ValidationError.unknownError) return JsonResponse.error(exc,exc.status,table=tableName) try: jobTracker.markJobStatus(jobId,"running") if jobType == interfaces.jobDb.getJobTypeId("csv_record_validation"): self.runValidation(jobId,interfaces) elif jobType == interfaces.jobDb.getJobTypeId("validation"): self.runCrossValidation(jobId, interfaces) else: raise ResponseException("Bad job type for validator", StatusCode.INTERNAL_ERROR) interfaces.errorDb.markFileComplete(jobId,self.filename) return JsonResponse.create(StatusCode.OK,{"table":tableName}) except ResponseException as e: CloudLogger.logError(str(e),e,traceback.extract_tb(sys.exc_info()[2])) self.markJob(jobId,jobTracker,"invalid",interfaces.errorDb,self.filename,e.errorType,e.extraInfo) return JsonResponse.error(e,e.status,table=tableName) except ValueError as e: CloudLogger.logError(str(e),e,traceback.extract_tb(sys.exc_info()[2])) # Problem with CSV headers exc = ResponseException(str(e),StatusCode.CLIENT_ERROR,type(e),ValidationError.unknownError) #"Internal value error" self.markJob(jobId,jobTracker,"invalid",interfaces.errorDb,self.filename,ValidationError.unknownError) return JsonResponse.error(exc,exc.status,table=tableName) except Error as e: CloudLogger.logError(str(e),e,traceback.extract_tb(sys.exc_info()[2])) # CSV file not properly formatted (usually too much in one field) exc = ResponseException("Internal error",StatusCode.CLIENT_ERROR,type(e),ValidationError.unknownError) self.markJob(jobId,jobTracker,"invalid",interfaces.errorDb,self.filename,ValidationError.unknownError) return JsonResponse.error(exc,exc.status,table=tableName) except Exception as e: CloudLogger.logError(str(e),e,traceback.extract_tb(sys.exc_info()[2])) exc = ResponseException(str(e),StatusCode.INTERNAL_ERROR,type(e),ValidationError.unknownError) self.markJob(jobId,jobTracker,"failed",interfaces.errorDb,self.filename,ValidationError.unknownError) return JsonResponse.error(exc,exc.status,table=tableName)