def check_artifact_access(user, artifact): """Checks whether user has access to an artifact Parameters ---------- user : qiita_db.user.User object User to check artifact : qiita_db.artifact.Artifact Artifact to check access for Raises ------ QiitaHTTPError If the user doesn't have access to the given artifact """ if user.level in ('admin', 'wet-lab admin'): return if artifact.visibility != 'public': study = artifact.study analysis = artifact.analysis if study: if not study.has_access(user): raise QiitaHTTPError(403, "Access denied to study %s" % artifact.id) elif analysis: if not analysis.has_access(user): raise QiitaHTTPError( 403, "Access denied to artifact %s" % artifact.id) else: # This can't happen but worth adding a check raise QiitaHTTPError(500, "Error accessing artifact %s" % artifact.id)
def safe_execution(): try: yield except HTTPError: # The HTTPError is already handled nicely by tornado, just re-raise raise except Exception as e: # Any other error we need to catch and re-raise as a QiitaHTTPError # so we can make sure that tornado will handle it gracefully and send # a useful error message to the user raise QiitaHTTPError(500, str(e))
def artifact_patch_request(user, artifact_id, req_op, req_path, req_value=None, req_from=None): """Modifies an attribute of the artifact Parameters ---------- user : qiita_db.user.User The user performing the patch operation artifact_id : int Id of the artifact in which the patch operation is being performed req_op : str The operation to perform on the artifact req_path : str The prep information and attribute to patch req_value : str, optional The value that needs to be modified req_from : str, optional The original path of the element Raises ------ QiitaHTTPError If `req_op` != 'replace' If the path parameter is incorrect If missing req_value If the attribute to replace is not known """ if req_op == 'replace': req_path = [v for v in req_path.split('/') if v] if len(req_path) != 1: raise QiitaHTTPError(404, 'Incorrect path parameter') attribute = req_path[0] # Check if the user actually has access to the artifact artifact = Artifact(artifact_id) check_artifact_access(user, artifact) if not req_value: raise QiitaHTTPError(404, 'Missing value to replace') if attribute == 'name': artifact.name = req_value return elif attribute == 'visibility': if req_value not in get_visibilities(): raise QiitaHTTPError( 400, 'Unknown visibility value: %s' % req_value) if (req_value == 'private' and qiita_config.require_approval and not user.level == 'admin'): raise QiitaHTTPError( 403, 'User does not have permissions ' 'to approve change') try: artifact.visibility = req_value except Exception as e: raise QiitaHTTPError(403, str(e).replace('\n', '<br/>')) sid = artifact.study.id if artifact.visibility == 'awaiting_approval': email_to = '*****@*****.**' subject = ('QIITA: Artifact %s awaiting_approval. Study %d, ' 'Prep %d' % (artifact_id, sid, artifact.prep_templates[0].id)) message = ('%s requested approval. <a ' 'href="https://qiita.ucsd.edu/study/description/' '%d">Study %d</a>.' % (user.email, sid, sid)) try: send_email(email_to, subject, message) except Exception: msg = ("Couldn't send email to admins, please email us " "directly to <a href='mailto:{0}'>{0}</a>.".format( email_to)) raise QiitaHTTPError(400, msg) else: msg = '%s changed artifact %s (study %d) to %s' % ( user.email, artifact_id, sid, req_value) LogEntry.create('Warning', msg) else: # We don't understand the attribute so return an error raise QiitaHTTPError( 404, 'Attribute "%s" not found. Please, ' 'check the path parameter' % attribute) else: raise QiitaHTTPError( 400, 'Operation "%s" not supported. Current ' 'supported operations: replace' % req_op)
def artifact_patch_request(user, artifact_id, req_op, req_path, req_value=None, req_from=None): """Modifies an attribute of the artifact Parameters ---------- user : qiita_db.user.User The user performing the patch operation artifact_id : int Id of the artifact in which the patch operation is being performed req_op : str The operation to perform on the artifact req_path : str The prep information and attribute to patch req_value : str, optional The value that needs to be modified req_from : str, optional The original path of the element Raises ------ QiitaHTTPError If `req_op` != 'replace' If the path parameter is incorrect If missing req_value If the attribute to replace is not known """ if req_op == 'replace': req_path = [v for v in req_path.split('/') if v] if len(req_path) != 1: raise QiitaHTTPError(404, 'Incorrect path parameter') attribute = req_path[0] # Check if the user actually has access to the artifact artifact = Artifact(artifact_id) check_artifact_access(user, artifact) if not req_value: raise QiitaHTTPError(404, 'Missing value to replace') if attribute == 'name': artifact.name = req_value return elif attribute == 'visibility': if req_value not in get_visibilities(): raise QiitaHTTPError( 400, 'Unknown visibility value: %s' % req_value) # Set the approval to private if needs approval and admin if req_value == 'private': if not qiita_config.require_approval: artifact.visibility = 'private' # Set the approval to private if approval not required elif user.level == 'admin': artifact.visibility = 'private' # Trying to set approval without admin privileges else: raise QiitaHTTPError( 403, 'User does not have permissions ' 'to approve change') else: artifact.visibility = req_value else: # We don't understand the attribute so return an error raise QiitaHTTPError( 404, 'Attribute "%s" not found. Please, ' 'check the path parameter' % attribute) else: raise QiitaHTTPError( 400, 'Operation "%s" not supported. Current ' 'supported operations: replace' % req_op)