def ProcessFormData(self, mr, post_data): """Validate and store the contents of the issues tracker admin page. Args: mr: commonly used info parsed from the request. post_data: HTML form data from the request. Returns: String URL to redirect the user to, or None if response was already sent. """ config, component_def = self._GetComponentDef(mr) allow_edit = permissions.CanEditComponentDef( mr.auth.effective_ids, mr.perms, mr.project, component_def, config) if not allow_edit: raise permissions.PermissionException( 'User is not allowed to edit or delete this component') if 'deletecomponent' in post_data: allow_delete = not tracker_bizobj.FindDescendantComponents( config, component_def) if not allow_delete: raise permissions.PermissionException( 'User tried to delete component that had subcomponents') return self._ProcessDeleteComponent(mr, component_def) else: return self._ProcessEditComponent(mr, post_data, config, component_def)
def components_delete(self, request): """Delete a component.""" mar = self.mar_factory(request) config = self._services.config.GetProjectConfig(mar.cnxn, mar.project_id) component_path = request.componentPath component_def = tracker_bizobj.FindComponentDef( component_path, config) if not component_def: raise config_svc.NoSuchComponentException( 'The component %s does not exist.' % component_path) if not permissions.CanViewComponentDef( mar.auth.effective_ids, mar.perms, mar.project, component_def): raise permissions.PermissionException( 'User is not allowed to view this component %s' % component_path) if not permissions.CanEditComponentDef( mar.auth.effective_ids, mar.perms, mar.project, component_def, config): raise permissions.PermissionException( 'User is not allowed to delete this component %s' % component_path) allow_delete = not tracker_bizobj.FindDescendantComponents( config, component_def) if not allow_delete: raise permissions.PermissionException( 'User tried to delete component that had subcomponents') self._services.issue.DeleteComponentReferences( mar.cnxn, component_def.component_id) self._services.config.DeleteComponentDef( mar.cnxn, mar.project_id, component_def.component_id) return message_types.VoidMessage()
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. """ config, component_def = self._GetComponentDef(mr) users_by_id = framework_views.MakeAllUserViews(mr.cnxn, self.services.user, component_def.admin_ids, component_def.cc_ids) component_def_view = tracker_views.ComponentDefView( mr.cnxn, self.services, component_def, users_by_id) initial_admins = [ users_by_id[uid].email for uid in component_def.admin_ids ] initial_cc = [users_by_id[uid].email for uid in component_def.cc_ids] initial_labels = [ self.services.config.LookupLabel(mr.cnxn, mr.project_id, label_id) for label_id in component_def.label_ids ] creator, created = self._GetUserViewAndFormattedTime( mr, component_def.creator_id, component_def.created) modifier, modified = self._GetUserViewAndFormattedTime( mr, component_def.modifier_id, component_def.modified) allow_edit = permissions.CanEditComponentDef(mr.auth.effective_ids, mr.perms, mr.project, component_def, config) subcomponents = tracker_bizobj.FindDescendantComponents( config, component_def) templates = self.services.config.TemplatesWithComponent( mr.cnxn, component_def.component_id, config) allow_delete = allow_edit and not subcomponents and not templates return { 'admin_tab_mode': servlet.Servlet.PROCESS_TAB_COMPONENTS, 'component_def': component_def_view, 'initial_leaf_name': component_def_view.leaf_name, 'initial_docstring': component_def.docstring, 'initial_deprecated': ezt.boolean(component_def.deprecated), 'initial_admins': initial_admins, 'initial_cc': initial_cc, 'initial_labels': initial_labels, 'allow_edit': ezt.boolean(allow_edit), 'allow_delete': ezt.boolean(allow_delete), 'subcomponents': subcomponents, 'templates': templates, 'creator': creator, 'created': created, 'modifier': modifier, 'modified': modified, }
def components_create(self, request): """Create a component.""" mar = self.mar_factory(request) if not mar.perms.CanUsePerm( permissions.EDIT_PROJECT, mar.auth.effective_ids, mar.project, []): raise permissions.PermissionException( 'User is not allowed to create components for this project') config = self._services.config.GetProjectConfig(mar.cnxn, mar.project_id) leaf_name = request.componentName if not tracker_constants.COMPONENT_NAME_RE.match(leaf_name): raise config_svc.InvalidComponentNameException( 'The component name %s is invalid.' % leaf_name) parent_path = request.parentPath if parent_path: parent_def = tracker_bizobj.FindComponentDef(parent_path, config) if not parent_def: raise config_svc.NoSuchComponentException( 'Parent component %s does not exist.' % parent_path) if not permissions.CanEditComponentDef( mar.auth.effective_ids, mar.perms, mar.project, parent_def, config): raise permissions.PermissionException( 'User is not allowed to add a subcomponent to component %s' % parent_path) path = '%s>%s' % (parent_path, leaf_name) else: path = leaf_name if tracker_bizobj.FindComponentDef(path, config): raise config_svc.InvalidComponentNameException( 'The name %s is already in use.' % path) created = int(time.time()) user_emails = set() user_emails.update([mar.auth.email] + request.admin + request.cc) user_ids_dict = self._services.user.LookupUserIDs( mar.cnxn, list(user_emails), autocreate=False) admin_ids = [user_ids_dict[uname] for uname in request.admin] cc_ids = [user_ids_dict[uname] for uname in request.cc] label_ids = [] # TODO(jrobbins): allow API clients to specify this too. component_id = self._services.config.CreateComponentDef( mar.cnxn, mar.project_id, path, request.description, request.deprecated, admin_ids, cc_ids, created, user_ids_dict[mar.auth.email], label_ids) return api_pb2_v1.Component( componentId=component_id, projectName=request.projectId, componentPath=path, description=request.description, admin=request.admin, cc=request.cc, deprecated=request.deprecated, created=datetime.datetime.fromtimestamp(created), creator=mar.auth.email)
def ProcessFormData(self, mr, post_data): """Processes a POST command to delete components. Args: mr: commonly used info parsed from the request. post_data: HTML form data from the request. Returns: String URL to redirect the user to, or None if response was already sent. """ config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id) component_defs = self._GetComponentDefs(mr, post_data, config) # Reverse the component_defs so that we start deleting from subcomponents. component_defs.reverse() # Collect errors. perm_errors = [] subcomponents_errors = [] templates_errors = [] # Collect successes. deleted_components = [] for component_def in component_defs: allow_edit = permissions.CanEditComponentDef( mr.auth.effective_ids, mr.perms, mr.project, component_def, config) if not allow_edit: perm_errors.append(component_def.path) subcomponents = tracker_bizobj.FindDescendantComponents( config, component_def) if subcomponents: subcomponents_errors.append(component_def.path) templates = self.services.template.TemplatesWithComponent( mr.cnxn, component_def.component_id) if templates: templates_errors.append(component_def.path) allow_delete = allow_edit and not subcomponents and not templates if allow_delete: self._ProcessDeleteComponent(mr, component_def) deleted_components.append(component_def.path) # Refresh project config after the component deletion. config = self.services.config.GetProjectConfig( mr.cnxn, mr.project_id) return framework_helpers.FormatAbsoluteURL( mr, urls.ADMIN_COMPONENTS, ts=int(time.time()), failed_perm=','.join(perm_errors), failed_subcomp=','.join(subcomponents_errors), failed_templ=','.join(templates_errors), deleted=','.join(deleted_components))
def ProcessFormData(self, mr, post_data): """Validate and store the contents of the issues tracker admin page. Args: mr: commonly used info parsed from the request. post_data: HTML form data from the request. Returns: String URL to redirect the user to, or None if response was already sent. """ config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id) parent_path = post_data.get('parent_path', '') parsed = component_helpers.ParseComponentRequest( mr, post_data, self.services) if parent_path: parent_def = tracker_bizobj.FindComponentDef(parent_path, config) if not parent_def: self.abort(500, 'parent component not found') allow_parent_edit = permissions.CanEditComponentDef( mr.auth.effective_ids, mr.perms, mr.project, parent_def, config) if not allow_parent_edit: raise permissions.PermissionException( 'User is not allowed to add a subcomponent here') path = '%s>%s' % (parent_path, parsed.leaf_name) else: path = parsed.leaf_name leaf_name_error_msg = LeafNameErrorMessage(parent_path, parsed.leaf_name, config) if leaf_name_error_msg: mr.errors.leaf_name = leaf_name_error_msg if mr.errors.AnyErrors(): self.PleaseCorrect( mr, parent_path=parent_path, initial_leaf_name=parsed.leaf_name, initial_docstring=parsed.docstring, initial_deprecated=ezt.boolean(parsed.deprecated), initial_admins=parsed.admin_usernames, initial_cc=parsed.cc_usernames, initial_labels=parsed.label_strs, ) return created = int(time.time()) creator_id = self.services.user.LookupUserID(mr.cnxn, mr.auth.email, autocreate=False) self.services.config.CreateComponentDef(mr.cnxn, mr.project_id, path, parsed.docstring, parsed.deprecated, parsed.admin_ids, parsed.cc_ids, created, creator_id, label_ids=parsed.label_ids) return framework_helpers.FormatAbsoluteURL(mr, urls.ADMIN_COMPONENTS, saved=1, ts=int(time.time()))
def components_update(self, request): """Update a component.""" mar = self.mar_factory(request) config = self._services.config.GetProjectConfig(mar.cnxn, mar.project_id) component_path = request.componentPath component_def = tracker_bizobj.FindComponentDef( component_path, config) if not component_def: raise config_svc.NoSuchComponentException( 'The component %s does not exist.' % component_path) if not permissions.CanViewComponentDef( mar.auth.effective_ids, mar.perms, mar.project, component_def): raise permissions.PermissionException( 'User is not allowed to view this component %s' % component_path) if not permissions.CanEditComponentDef( mar.auth.effective_ids, mar.perms, mar.project, component_def, config): raise permissions.PermissionException( 'User is not allowed to edit this component %s' % component_path) original_path = component_def.path new_path = component_def.path new_docstring = component_def.docstring new_deprecated = component_def.deprecated new_admin_ids = component_def.admin_ids new_cc_ids = component_def.cc_ids update_filterrule = False for update in request.updates: if update.field == api_pb2_v1.ComponentUpdateFieldID.LEAF_NAME: leaf_name = update.leafName if not tracker_constants.COMPONENT_NAME_RE.match(leaf_name): raise config_svc.InvalidComponentNameException( 'The component name %s is invalid.' % leaf_name) if '>' in original_path: parent_path = original_path[:original_path.rindex('>')] new_path = '%s>%s' % (parent_path, leaf_name) else: new_path = leaf_name conflict = tracker_bizobj.FindComponentDef(new_path, config) if conflict and conflict.component_id != component_def.component_id: raise config_svc.InvalidComponentNameException( 'The name %s is already in use.' % new_path) update_filterrule = True elif update.field == api_pb2_v1.ComponentUpdateFieldID.DESCRIPTION: new_docstring = update.description elif update.field == api_pb2_v1.ComponentUpdateFieldID.ADMIN: user_ids_dict = self._services.user.LookupUserIDs( mar.cnxn, list(update.admin), autocreate=True) new_admin_ids = [user_ids_dict[email] for email in update.admin] elif update.field == api_pb2_v1.ComponentUpdateFieldID.CC: user_ids_dict = self._services.user.LookupUserIDs( mar.cnxn, list(update.cc), autocreate=True) new_cc_ids = [user_ids_dict[email] for email in update.cc] update_filterrule = True elif update.field == api_pb2_v1.ComponentUpdateFieldID.DEPRECATED: new_deprecated = update.deprecated else: logging.error('Unknown component field %r', update.field) new_modified = int(time.time()) new_modifier_id = self._services.user.LookupUserID( mar.cnxn, mar.auth.email, autocreate=False) logging.info( 'Updating component id %d: path-%s, docstring-%s, deprecated-%s,' ' admin_ids-%s, cc_ids-%s modified by %s', component_def.component_id, new_path, new_docstring, new_deprecated, new_admin_ids, new_cc_ids, new_modifier_id) self._services.config.UpdateComponentDef( mar.cnxn, mar.project_id, component_def.component_id, path=new_path, docstring=new_docstring, deprecated=new_deprecated, admin_ids=new_admin_ids, cc_ids=new_cc_ids, modified=new_modified, modifier_id=new_modifier_id) # TODO(sheyang): reuse the code in componentdetails if original_path != new_path: # If the name changed then update all of its subcomponents as well. subcomponent_ids = tracker_bizobj.FindMatchingComponentIDs( original_path, config, exact=False) for subcomponent_id in subcomponent_ids: if subcomponent_id == component_def.component_id: continue subcomponent_def = tracker_bizobj.FindComponentDefByID( subcomponent_id, config) subcomponent_new_path = subcomponent_def.path.replace( original_path, new_path, 1) self._services.config.UpdateComponentDef( mar.cnxn, mar.project_id, subcomponent_def.component_id, path=subcomponent_new_path) if update_filterrule: filterrules_helpers.RecomputeAllDerivedFields( mar.cnxn, self._services, mar.project, config) return message_types.VoidMessage()