def ParsePersonData(self, mr, post_data): """Parse the POST data for a project member. Args: mr: common information parsed from the user's request. post_data: dictionary of lists of values for each HTML form field. Returns: A tuple with user_id, role, extra_perms, and notes. """ if not mr.specified_user_id: raise monorailrequest.InputException('Field user_id is missing') role = post_data.get('role', '').lower() extra_perms = [] for ep in post_data.getall('extra_perms'): perm = framework_bizobj.CanonicalizeLabel(ep) # Perms with leading underscores are reserved. perm = perm.strip('_') if perm: extra_perms.append(perm) notes = post_data.get('notes', '').strip() ac_exclusion = post_data.get('ac_exclude', '') return mr.specified_user_id, role, extra_perms, notes, bool( ac_exclusion)
def GatherPageData(self, mr): """Build up a dictionary of data values to use when rendering the page.""" # We are not actually in /p/PROJECTNAME, so mr.project_name is None. # Putting the ProjectMoved page inside a moved project would make # the redirect logic much more complicated. if not mr.specified_project: raise monorailrequest.InputException('No project specified') project = self.services.project.GetProjectByName( mr.cnxn, mr.specified_project) if not project: self.abort(404, 'project not found') if not project.moved_to: # Only show this page for projects that are actually moved. # Don't allow hackers to construct misleading links to this servlet. logging.info('attempt to view ProjectMoved for non-moved project: %s', mr.specified_project) self.abort(400, 'This project has not been moved') if framework_bizobj.RE_PROJECT_NAME.match(project.moved_to): moved_to_url = framework_helpers.FormatAbsoluteURL( mr, urls.SUMMARY, include_project=True, project_name=project.moved_to) elif (project.moved_to.startswith('https://') or project.moved_to.startswith('http://')): moved_to_url = project.moved_to else: # Prevent users from using javascript: or any other tricky URL scheme. moved_to_url = '#invalid-destination-url' return { 'project_name': mr.specified_project, 'moved_to_url': moved_to_url, }
def HandleRequest(self, mr): """Retrieves the star persistence object and sets a star.""" starrer_id = mr.auth.user_id item = mr.GetParam( 'item') # a project name or a user/hotlist ID number scope = mr.GetParam('scope') starred = bool(mr.GetIntParam('starred')) logging.info('Handling user set star request: %r %r %r %r', starrer_id, item, scope, starred) if scope == PROJECT_STARS_SCOPE: project = self.services.project.GetProjectByName(mr.cnxn, item) self.services.project_star.SetStar(mr.cnxn, project.project_id, starrer_id, starred) elif scope == USER_STARS_SCOPE: user_id = int(item) self.services.user_star.SetStar(mr.cnxn, user_id, starrer_id, starred) elif scope == HOTLIST_STARS_SCOPE: hotlist_id = int(item) self.services.hotlist_star.SetStar(mr.cnxn, hotlist_id, starrer_id, starred) else: raise monorailrequest.InputException('unexpected star scope: %s' % scope) return { 'starred': starred, }
def _ParseOneRule(cnxn, predicate, action_type, action_value, user_service, rule_num, error_list): """Parse one FilterRule based on the action type.""" if action_type == 'default_status': status = framework_bizobj.CanonicalizeLabel(action_value) rule = MakeRule(predicate, default_status=status) elif action_type == 'default_owner': if action_value: try: user_id = user_service.LookupUserID(cnxn, action_value) except user_svc.NoSuchUserException: user_id = framework_constants.NO_USER_SPECIFIED error_list.append('Rule %d: No such user: %s' % (rule_num, action_value)) else: user_id = framework_constants.NO_USER_SPECIFIED rule = MakeRule(predicate, default_owner_id=user_id) elif action_type == 'add_ccs': cc_ids = [] for email in re.split('[,;\s]+', action_value): if not email.strip(): continue try: user_id = user_service.LookupUserID(cnxn, email.strip(), autocreate=True) cc_ids.append(user_id) except user_svc.NoSuchUserException: error_list.append('Rule %d: No such user: %s' % (rule_num, email.strip())) rule = MakeRule(predicate, add_cc_ids=cc_ids) elif action_type == 'add_labels': add_labels = framework_constants.IDENTIFIER_RE.findall(action_value) rule = MakeRule(predicate, add_labels=add_labels) elif action_type == 'also_notify': add_notify = [] for addr in re.split('[,;\s]+', action_value): if validate.IsValidEmail(addr.strip()): add_notify.append(addr.strip()) else: error_list.append('Rule %d: Invalid email address: %s' % (rule_num, addr.strip())) rule = MakeRule(predicate, add_notify=add_notify) else: logging.info('unexpected action type, probably tampering:%r', action_type) raise monorailrequest.InputException() return rule
def HandleRequest(self, mr): """Processes a user's POST request to dismiss a cue card. Args: mr: commonly used info parsed from the request. """ cue_id = mr.GetParam('cue_id') if not cue_id: raise monorailrequest.InputException('no cue_id specified') logging.info('Handling user set cue request: %r', cue_id) new_dismissed_cues = mr.auth.user_pb.dismissed_cues new_dismissed_cues.append(cue_id) self.services.user.UpdateUserSettings( mr.cnxn, mr.auth.user_id, mr.auth.user_pb, dismissed_cues=new_dismissed_cues)
def GatherPageData(self, mr): """Build up a dictionary of data values to use when rendering the page. Args: mr: commonly used info parsed from the request. Returns: A dict of values used by EZT for rendering the page. """ artifact_name = mr.GetParam('name') if not artifact_name: raise monorailrequest.InputException() # someone forged a link artifact_detail_url = '/p/%s/issues/detail?id=%s' % ( mr.project_name, mr.continue_issue_id) return { 'artifact_name': artifact_name, 'artifact_detail_url': artifact_detail_url, }
def GatherPageData(self, mr): """Build up a dictionary of data values to use when rendering the page. Args: mr: commonly used info parsed from the request. Returns: Dict of values used by EZT for rendering the page. """ with self.profiler.Phase('getting issues'): if not mr.local_id_list: raise monorailrequest.InputException() requested_issues = self.services.issue.GetIssuesByLocalIDs( mr.cnxn, mr.project_id, sorted(mr.local_id_list)) with self.profiler.Phase('filtering issues'): # TODO(jrobbins): filter out issues that the user cannot edit and # provide that as feedback rather than just siliently ignoring them. open_issues, closed_issues = ( tracker_helpers.GetAllowedOpenedAndClosedIssues( mr, [issue.issue_id for issue in requested_issues], self.services)) issues = open_issues + closed_issues if not issues: self.abort(404, 'no issues found') config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id) type_label_set = { lab.lower() for lab in issues[0].labels if lab.lower().startswith('type-') } for issue in issues[1:]: new_type_set = { lab.lower() for lab in issue.labels if lab.lower().startswith('type-') } type_label_set &= new_type_set field_views = [ tracker_views.MakeFieldValueView(fd, config, type_label_set, [], [], {}) # TODO(jrobbins): field-level view restrictions, display options # TODO(jrobbins): custom fields in templates supply values to view. for fd in config.field_defs if not fd.is_deleted ] # Explicitly set all field views to not required. We do not want to force # users to have to set it for issues missing required fields. # See https://bugs.chromium.org/p/monorail/issues/detail?id=500 for more # details. for fv in field_views: fv.field_def.is_required_bool = None with self.profiler.Phase('making issue proxies'): issue_views = [ template_helpers.EZTItem( local_id=issue.local_id, summary=issue.summary, closed=ezt.boolean(issue in closed_issues)) for issue in issues ] num_seconds = (int(len(issue_views) * self._SECONDS_PER_UPDATE) + self._SECONDS_OVERHEAD) page_perms = self.MakePagePerms(mr, None, permissions.CREATE_ISSUE, permissions.DELETE_ISSUE) return { 'issue_tab_mode': 'issueBulkEdit', 'issues': issue_views, 'num_issues': len(issue_views), 'show_progress': ezt.boolean(num_seconds > self._SLOWNESS_THRESHOLD), 'num_seconds': num_seconds, 'initial_blocked_on': '', 'initial_blocking': '', 'initial_comment': '', 'initial_status': '', 'initial_owner': '', 'initial_merge_into': '', 'initial_cc': '', 'initial_components': '', 'labels': [], 'fields': field_views, 'restrict_to_known': ezt.boolean(config.restrict_to_known), 'page_perms': page_perms, 'statuses_offer_merge': config.statuses_offer_merge, }
def GatherPageData(self, mr): """Build up a dictionary of data values to use when rendering the page.""" if not mr.project_name: raise monorailrequest.InputException('No project specified') return {}