コード例 #1
0
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
コード例 #2
0
    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)
コード例 #3
0
    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)
コード例 #4
0
    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