Project

General

Profile

JOIN/WHERE SQL for selecting issues viewable by a user

Added by Randy Syring about 14 years ago

Can someone tell me what the JOIN/WHERE SQL would be to select issues that are viewable by a given user id? I have an external application that needs to retrieve issues for a user, but only those they could see if they were logged into redmine.

The logic seems to be:

  • if admin -> show all issues
  • show issues if user is part of a project with a role that has view permissions

Replies (1)

RE: JOIN/WHERE SQL for selecting issues viewable by a user - Added by Randy Syring about 14 years ago

turns out not to be too complicated, the SQL would look something like:

SELECT *
FROM   "issues" 
LEFT OUTER JOIN "issue_statuses" 
  ON "issue_statuses".id = "issues".status_id
LEFT OUTER JOIN "projects" 
  ON "projects".id = "issues".project_id
WHERE 
       ( 1 = 0
           OR projects.is_public = 't'
           OR projects.id IN ( 5, 6, 7 )
        )

where 5,6,7 are the projects the user has the 'view_issues' permission.

And here is my Python code which uses SQLAlchemy queries:

def apply_user_filter_to_query(user_id, q):
    rmuser = db.sess.query(RmUser).get(user_id)
    if not rmuser:
        raise ValueError('user_id %s not found' % user_id)

    # if the user is an administrative user, no filter is applied
    if not rmuser.admin:
        proj_ids = user_projects_with_view_issue_perms(user_id)
        return q.where(or_(
            text( '1 = 0'), 
            projects.c.is_public == True,
            projects.c.id.in_(proj_ids)
        ))
    return q

def user_projects_with_view_issue_perms(user_id):
    sql = """ 
        select p.id
        from projects p
        inner join members m
        on m.project_id = p.id
        inner join member_roles mr
        on mr.member_id = m.id
        inner join roles r
        on r.id = mr.role_id
        where m.user_id = :user_id and r.permissions like '%\:view_issues%'
    """ 
    result = db.sess.execute(sql, {'user_id': user_id})
    return [row['id'] for row in result]

def issues_list_users(user_id, fusers, fstatuses, is_grouped):
    issue_select = apply_user_filter_to_query(user_id, iss_select_all)
    ...
user_issues = issues_list_users(session_user.id, ...)
    (1-1/1)