Set security level based on group

Name Set security level based on group
Version 1.0
Product Versions JIRA 3.4+
Author(s) Rodrigo Borghette Schmidt
Homepage Set security level based on group
Price free!
License BSD
JavaDocs  
IssueTracking  
Download JAR https://svn.atlassian.com/svn/public/contrib/jira/jira-security-level-plugin/jars/jira-security-level-plugin-1.0.jar
Download Source https://svn.atlassian.com/svn/public/contrib/jira/jira-security-level-plugin/

Description

A workflow postfunction it sets the issue security level based on one group the reporter is member of.

The group and security level have both the same name and in order to make this work as we expect, the user cannot be member of more than one group that has the same name of a security level.

For our convenience, we decided to add a leading "#" to the security level name, so that we can control when the plugin should act or not. So, the group and security level names must be the same, except that the security level name has a "#" at the beginning. If you have any doubt, please let me know.

Installation

  1. Download the jar and place in your webapp's lib folder
  2. Restart JIRA
  3. Add the post function to your workflow step(s)

Usage

Example

We've been using this here to automatically set the issue security level for one of our projects according to the geographic region our customers are located. For example, if we have a customer in US, he is member of a group named US and there is a security level named #US. If he is in Latin America, another group called LA and a security level called #LA and so on. In this way, when he creates an issue, he does not need to have set security level permission and customers from other regions won't see/mess with his issues.

Version History

Version Author Notes
1.0 Rodrigo Borghette Schmidt Initial release

Screenshots

Labels

workflow workflow Delete
plugin plugin Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Aug 09, 2006

    Neal Applebaum says:

    Thank you for contributing this. I think this alone makes JIRA usable as a helpd...

    Thank you for contributing this. I think this alone makes JIRA usable as a helpdesk tool. I do have one question - is it mandatory that the security level be named with a "#"? I tried naming the Security level exactly the same as the User Group, but it didn't work that way.

    1. Feb 14, 2007

      Rodrigo Borghette Schmidt says:

      Hi Neal, Yes, it is necessary to place a "#" at the beginning of the security l...

      Hi Neal,

      Yes, it is necessary to place a "#" at the beginning of the security level's name. In order to modify this behaviour, it is necessary to change the source e rebuild the plugin.


  2. Jun 02, 2007

    Henry Zhang says:

    I have test this plugin under jira 3.9, it did not work!

    I have test this plugin under jira 3.9, it did not work!

    1. Jun 02, 2007

      Neal Applebaum says:

      Oh, that's not good. This plug-in is crucial to my implementation of JIRA (I am ...

      Oh, that's not good. This plug-in is crucial to my implementation of JIRA (I am still on 3.6.5)

  3. Jul 04, 2007

    Ákos Diviánszky says:

    We had the same problem here, the plugin was not working under 3.9. Changing the...

    We had the same problem here, the plugin was not working under 3.9.
    Changing the max version string directly in the jar file solved the problem.

  4. Aug 09, 2007

    Simone Kaiser says:

    We upgraded from release 3.7.1 to release 3.10 and the plugin does not work any ...

    We upgraded from release 3.7.1 to release 3.10 and the plugin does not work any longer. How do I change the max version string in the jar file? Which variable is it? Which steps have to be done?

    1. Sep 26, 2007

      mameha says:

      I updated that variable (to version 9.9) but the plugin still does not work in J...

      I updated that variable (to version 9.9) but the plugin still does not work in JIRA 3.9

      FYI, the variable is amended by unpacking the .jar, then amending the line in atlassian-plugin.xml then repacking the .jar and installing in JIRA's WEBINF/lib as usual.

      If anyone cracked this please post the answer. 

  5. Sep 06, 2007

    MehmetM says:

    It's the working copy for 3.9, 3.10. I wrote it as Listener and I've add some fu...

    It's the working copy for 3.9, 3.10. I wrote it as Listener and I've add some functionalty (prefix can be defined and projects can be defined)

    package tr.com.yourcompany.jira.securitylevel;
    
    import com.atlassian.jira.ManagerFactory;
    import com.atlassian.jira.event.issue.AbstractIssueEventListener;
    import com.atlassian.jira.event.issue.IssueEvent;
    import com.atlassian.jira.event.issue.IssueEventListener;
    import com.atlassian.jira.issue.MutableIssue;
    import com.atlassian.jira.issue.security.IssueSecurityLevelManager;
    
    import com.opensymphony.user.User;
    
    import java.util.Collection;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    import org.ofbiz.core.entity.GenericValue;
    
    
    public class SetSecurityLevelListener extends AbstractIssueEventListener implements IssueEventListener
    {
    
    	private final IssueSecurityLevelManager issueSecurityLevelManager = ManagerFactory.getIssueSecurityLevelManager();
      private final String SECURTY_LEVEL_PREFIX = "Securty Level Name Prefix (Default #)";
      private final String PROJECTS_TO_SET = "Project Keys (Enter project keys with (;) without space; Null for All Projects)";
    
    	private String projectsToSet;
    	private String securtyLevelPrefix;
    
      public void init(Map params)
      {
        projectsToSet = null;
        if (params.containsKey(PROJECTS_TO_SET )){
          projectsToSet = (String)params.get(PROJECTS_TO_SET)+";";
        }
        securtyLevelPrefix = "#";
        if (params.containsKey(SECURTY_LEVEL_PREFIX )){
          securtyLevelPrefix= (String)params.get(SECURTY_LEVEL_PREFIX);
        }
      }
    
      public String[] getAcceptedParams()
      {
        return new String[]{PROJECTS_TO_SET, SECURTY_LEVEL_PREFIX};
      }
    
      public void issueCreated(IssueEvent event) {
    		MutableIssue issue = (MutableIssue)event.getIssue();
        if (projectsToSet !=null && projectsToSet.indexOf(issue.getProjectObject().getKey()+";")<0)
        {
          return;
        }
    		User reporter = issue.getReporter();
    		List reporterGroups = reporter.getGroups();
    		try {
    			Collection issueSecurityLevels = issueSecurityLevelManager.getUsersSecurityLevels(issue.getGenericValue(), reporter);
          groups:
    			for (Iterator iterator = reporterGroups.iterator(); iterator.hasNext();) {
    				String groupName = (String) iterator.next();
    				for (Iterator iterator1 = issueSecurityLevels.iterator(); iterator1.hasNext();) {
    					GenericValue securityLevel = (GenericValue) iterator1.next();
    					String s = securityLevel.getString("name");
    					if (s.startsWith(securtyLevelPrefix) && s.subSequence(1, s.length()).equals(groupName)) {
    						issue.setSecurityLevel(securityLevel);
    						issue.store();
    						break groups;
    					}
    				}
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return;
      }
    
      public boolean isInternal()
      {
        return false;
      }
    
      public boolean isUnique()
      {
        return false;
      }
    
      public String getDescription()
      {
        return "It sets the issue security level based on one group the reporter is member of.
    The group and security level have both the same name and in order to make this work as we expect, the user cannot be member of more than one group that has the same name of a security level.";
      }
    
    }
    1. Sep 09, 2007

      Aggelos T. Paraskevopoulos says:

      Mehmet, is there a potential problem with implementing this as a listener, I me...

      Mehmet,

      is there a potential problem with implementing this as a listener, I mean you risk of sending notifications to users that after changing the security level won't be allowed to see the issue? I'm not sure in what order the event listeners are fired, so if the notification (e.g. MailListener) takes place before the auto security level listener, emails are sent without respecting the visibility of the issue.

  6. Sep 10, 2007

    Emily Stumpf says:

    I tried this with 3.10 and it worked fine (the original, not the Listener one).

    I tried this with 3.10 and it worked fine (the original, not the Listener one).

  7. Oct 19, 2007

    William Chever says:

    Rodrigo, Thanks a lot for this!  This solves a critical issue in our e...

    Rodrigo,

    Thanks a lot for this!  This solves a critical issue in our environment.

    Bill

    ...

    But in using it, I figured a way to accomplish the same thing easily.  We are using 3.10.

    We have a field called Account Name set up as a group picker.  Create one security level, make it the default and add to it your internal support group, and then add to it the Group Selector option and select the Account Name field.  All users in a particular group can see all their own issues, but no one else's, and your internal support group can see everything.  No need for the plugin or maintaining the various security levels when adding a group.

    Bill

  8. Nov 19, 2007

    Joshua Goodall says:

    Is that issue.store() actually required? Surely com.atlassian.jira.workflow.func...

    Is that issue.store() actually required? Surely com.atlassian.jira.workflow.function.issue.IssueStoreFunction takes care of that for you for every transition anyway?

  9. Jan 03, 2008

    Tom Clarkson says:

    Hey guys, this is great work! Has anyone tried setting the security in a po...

    Hey guys, this is great work!

    Has anyone tried setting the security in a post workflow function based on component? How different it would be from this function?

    We have users who can be in multiple groups and  this function cannot determine which security level to assign because they are in more than one group.

    If the security could be set based on the component, it would not matter how many groups a user was in - the security would work. 

     Cheers, Tom

  10. Jan 17, 2008

    Emily Stumpf says:

    Does anyone know if this plugin has been updated to deal with the index changes ...

    Does anyone know if this plugin has been updated to deal with the index changes of [Jira 3.11|http://confluence.atlassian.com/display/JIRA/JIRA+3.11+Release+Notes]?

    Thanks!

    Emily 

  11. May 06

    Erin says:

    Has this been tested with 3.12.3? I'm getting this exception when I click "Crea...

    Has this been tested with 3.12.3? I'm getting this exception when I click "Create Issue" for projects which use this function on the initial "Create" transition. It does create the issue and set the security level correctly, it just throws this error as well.

    java.lang.NullPointerException at com.atlassian.jira.issue.managers.DefaultIssueManager.notifyTrackbacks(DefaultIssueManager.java:384) at com.atlassian.jira.issue.managers.DefaultIssueManager.createIssue(DefaultIssueManager.java:366) at com.atlassian.jira.issue.managers.DefaultIssueManager.createIssue(DefaultIssueManager.java:313) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.atlassian.util.profiling.object.ObjectProfiler.profiledInvoke(ObjectProfiler.java:71) at com.atlassian.jira.config.component.SwitchingInvocationHandler.invoke(SwitchingInvocationHandler.java:28) at $Proxy3.createIssue(Unknown Source) at com.atlassian.jira.web.action.issue.CreateIssueDetails.createIssue(CreateIssueDetails.java:141) at com.atlassian.jira.web.action.issue.CreateIssueDetails.doExecute(CreateIssueDetails.java:110) at webwork.action.ActionSupport.execute(ActionSupport.java:153) at com.atlassian.jira.action.JiraActionSupport.execute(JiraActionSupport.java:54) at webwork.dispatcher.GenericDispatcher.executeAction(GenericDispatcher.java:132) at com.atlassian.jira.web.dispatcher.JiraServletDispatcher.service(JiraServletDispatcher.java:211) at javax.servlet.http.HttpServlet.service(HttpServlet.java:803) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.jira.web.filters.AccessLogFilter.doFilter(AccessLogFilter.java:73) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:119) at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:55) at com.atlassian.jira.web.filters.SitemeshExcludePathFilter.doFilter(SitemeshExcludePathFilter.java:38) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.seraph.filter.SecurityFilter.doFilter(SecurityFilter.java:192) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.seraph.filter.TrustedApplicationsFilter.doFilter(TrustedApplicationsFilter.java:120) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.seraph.filter.BaseLoginFilter.doFilter(BaseLoginFilter.java:125) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.util.profiling.filters.ProfilingFilter.doFilter(ProfilingFilter.java:132) at com.atlassian.jira.web.filters.JIRAProfilingFilter.doFilter(JIRAProfilingFilter.java:16) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.jira.web.filters.ActionCleanupDelayFilter.doFilter(ActionCleanupDelayFilter.java:43) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.jira.web.filters.RequestCleanupFilter.doFilter(RequestCleanupFilter.java:50) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.johnson.filters.AbstractJohnsonFilter.doFilter(AbstractJohnsonFilter.java:72) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:350) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.gzipfilter.GzipFilter.doFilter(GzipFilter.java:79) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.core.filters.AbstractEncodingFilter.doFilter(AbstractEncodingFilter.java:37) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at com.atlassian.jira.appconsistency.db.DatabaseCompatibilityEnforcerFilter.doFilter(DatabaseCompatibilityEnforcerFilter.java:39) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874) at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528) at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689) at java.lang.Thread.run(Thread.java:619)


  12. Jul 24

    Michele Tuveri says:

    It works fine in my environment with Jira 3.12.3 That's what I noted: the plug...

    It works fine in my environment with Jira 3.12.3
    That's what I noted:

    • the plugin post-function can't be the first (no ticket yet to set the Security Level)
    • the plugin post-function must be put before the reindexing standard post-function (elsewere the query Find Issues will not work fine)
    • then you just have to add as many new SL (of course, according to the plugin Description) as you need, into the Security Level Schema involved with the Jira project where you are raising the new tickets. The Reporter can belong to many groups; I have composed my SL Schemas in order to ever have only one SL to choose for any Reporter
    • you can also bulk update the old SL with the new one into the former tickets (just try to cancel the old SL and follow the tool)