def _get_trac_project_name(env): """Helper for migrating to environment based constructors.""" from multiproject.common.environment import TracEnvironment return TracEnvironment.read(conf.resolveProjectName(env)).identifier
def expand_macro(self, formatter, name, content, args=None): """ Expand the macro. We will accept a parameter to point us to another project if necessary. """ if name != 'Announcements': return None data = {} req = formatter.req env_name = None count = 0 title = None env = None # Parse settings for the macro env_name, count, title = self._parse_args(args, content) if not count: self.log.debug("Defaulting count to 5") count = 5 data['news_title'] = title current_env_name = self.env.project_identifier if not env_name: env_name = current_env_name data['env_name'] = env_name # Check if the project exists. mpp_env = None try: mpp_env = TracEnvironment.read(env_name) except TracError: data['news_error'] = "Couldn't find project '{0}'".format(env_name) self.log.error(data['news_error']) # Then check the permissions if mpp_env: # Check if project's announcements have been configured as hidden if env_name != current_env_name: env = open_environment(os.path.join( self.config.get('multiproject', 'sys_projects_root'), env_name), use_cache=True) else: env = self.env if not env.config.getbool('discussion', 'show_news_forum', True): self.log.debug( "Project announcements hidden, not showing with macro") return None # Check permission in specified environment permcache = PermissionCache(env, username=req.authname) if 'DISCUSSION_VIEW' in permcache: try: news = ProjectNews(env_name) data['newsitems'] = news.get_project_news( limit=count, f_name="Announcements") data['news_forum_id'] = news.get_news_forum_id() except Exception, e: self.log.exception( "Failed to read project {0} news.".format(env_name)) raise TracError( "Couldn't read news for project '{0}': {1}".format( env_name, e)) else: data[ 'news_error'] = "No permission to read news from project '{0}'".format( env_name)
def expand_macro(self, formatter, name, content, args=None): """ Expand the macro. We will accept a parameter to point us to another project if necessary. """ if name != "Announcements": return None data = {} req = formatter.req env_name = None count = 0 title = None env = None # Parse settings for the macro env_name, count, title = self._parse_args(args, content) if not count: self.log.debug("Defaulting count to 5") count = 5 data["news_title"] = title current_env_name = self.env.project_identifier if not env_name: env_name = current_env_name data["env_name"] = env_name # Check if the project exists. mpp_env = None try: mpp_env = TracEnvironment.read(env_name) except TracError: data["news_error"] = "Couldn't find project '{0}'".format(env_name) self.log.error(data["news_error"]) # Then check the permissions if mpp_env: # Check if project's announcements have been configured as hidden if env_name != current_env_name: env = open_environment( os.path.join(self.config.get("multiproject", "sys_projects_root"), env_name), use_cache=True ) else: env = self.env if not env.config.getbool("discussion", "show_news_forum", True): self.log.debug("Project announcements hidden, not showing with macro") return None # Check permission in specified environment permcache = PermissionCache(env, username=req.authname) if "DISCUSSION_VIEW" in permcache: try: news = ProjectNews(env_name) data["newsitems"] = news.get_project_news(limit=count, f_name="Announcements") data["news_forum_id"] = news.get_news_forum_id() except Exception, e: self.log.exception("Failed to read project {0} news.".format(env_name)) raise TracError("Couldn't read news for project '{0}': {1}".format(env_name, e)) else: data["news_error"] = "No permission to read news from project '{0}'".format(env_name)
def check_permission(self, action, username, resource, perm): """ Checks permissions - Actual checking is done on CQDEPermissionPolicy class """ # FIXME: Dirty hack to screw ILegacyAttachmentPolicy. perm_maps = { "ATTACHMENT_CREATE": { "ticket": "TICKET_APPEND", "wiki": "WIKI_MODIFY", "milestone": "MILESTONE_MODIFY", "discussion": "DISCUSSION_ATTACH", }, "ATTACHMENT_VIEW": { "ticket": "TICKET_VIEW", "wiki": "WIKI_VIEW", "milestone": "MILESTONE_VIEW", "discussion": "DISCUSSION_ATTACH", }, "ATTACHMENT_DELETE": { "ticket": "TICKET_ADMIN", "wiki": "WIKI_DELETE", "milestone": "MILESTONE_DELETE", "discussion": "DISCUSSION_ATTACH", }, } perm_map = perm_maps.get(action) if perm_map and resource and resource.realm == "attachment": action = perm_map.get(resource.parent.realm) policy = CQDEPermissionPolicy(self.env) # Project context check if resource and resource.realm == "project": # NOTE: Load project to get environment key required by check_permission # NOTE: Internal TracEnvironment cannot be used because env can be home, whereas project id is not project = Project.get(id=resource.id) if project and policy.check_permission(project.trac_environment_key, action, username): return True return False # Ticket authors should be able to edit their own tickets # (excluding 'anonymous') if ( username != "anonymous" and resource and resource.id and resource.realm == "ticket" and action in ("TICKET_CHGPROP", "TICKET_EDIT_DESCRIPTION") ): ticket = Ticket(self.env, int(resource.id)) if ticket.exists and username == ticket["reporter"]: return True # Load lightweight trac environment to get environment id, required by internal check_permission env_name = conf.resolveProjectName(self.env) environment = TracEnvironment.read(env_name) # Check permission using global permission policy and storage if not policy.check_permission(environment.environment_id, action, username): return False # Additional, resources based checks # User author check if action in ("USER_ADMIN", "USER_AUTHOR", "USER_VIEW", "USER_MODIFY", "USER_DELETE") and resource: # Check if USER_ADMIN permission in home project home_perm = PermissionCache(conf.home_env, username) if "USER_ADMIN" in home_perm: return True userstore = conf.getUserStore() resource_user = userstore.getUserWhereId(resource.id) user = userstore.getUser(username) # Allow manage own and authored account if action in ("USER_ADMIN", "USER_AUTHOR"): return resource_user.author_id == user.id or resource_user.id == user.id # Allow to manage itself return resource_user.id == user.id return True