Using this method in a post-function (or an event triggered listener) to create an issue seems to always use the Context's "LoggedInUser" (JiraAuthenticationContext.getLoggedInUser()).:
IssueService.IssueResult create(@Nullable
ApplicationUser user,
IssueService.CreateValidationResult createValidationResult)
This create method's documentation https://docs.atlassian.com/software/jira/docs/api/7.6.1/index.html?com/atlassian/jira/bc/issue/IssueService.html states this for the user parameter:
"Parameters:
user - who the permission checks will be run against (can be null, indicating an anonymous user)."
But this seems to be false. No matter which ApplicationUser you hand over to the method, it always uses the Context's LoggedInUser.
The workaround is to set the context's loggedInUser to the intended user before creating the issue by using this method.
I encountered this curiosity while debugging a script where an issue should be created with an automated admin user, but the transition button is pressed by a non-admin user.
So my question is: Is this intended, an Atlassian bug, or am I missing something.
Steps to reproduce:
1. Use the above method to create an issue via post-function.
2. Set the "user" parameter of the method to:
ComponentAccessor.getUserManager().getUserByName($some user's username with create permissions)
3. The user who presses the transition/workflow button must NOT have the permissions to create any issues in the target project.
Example Code that can be run from Script Runners console (adjust variables for project ID, issuetype and adminUser obviously):
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.bc.issue.IssueService.CreateValidationResult
import com.atlassian.jira.bc.issue.IssueService.IssueResult
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.issue.search.SearchResults
import com.atlassian.jira.bc.issue.search.SearchService.ParseResult
import com.atlassian.jira.web.bean.PagerFilter
import org.apache.log4j.Logger
import org.apache.log4j.Level
Logger logger = Logger.getLogger("create.example")
logger.setLevel(Level.DEBUG)
IssueManager issueManager = ComponentAccessor.getIssueManager()
UserManager userManager = ComponentAccessor.getUserManager()
CustomFieldManager customFieldManager1 = ComponentAccessor.getCustomFieldManager()
IssueService issueService = ComponentAccessor.getIssueService()
ApplicationUser appUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser() //Non-Admin User
ApplicationUser adminUser = userManager.getUserByName("autoassist") //Admin User
//Setting loggedInUser to adminUser (autoassist):
ComponentAccessor.getJiraAuthenticationContext().setLoggedInUser(adminUser);
String newSummary = "Create Test"
//creating with appUser, which is not adminUser "autoassist":
MutableIssue newIssue = createIssue(appUser, newSummary, issueService, logger)
logger.debug("New Issue: " + newIssue?.getKey())
//Both return "autoassist" as the Reporter and Creator:
logger.debug("Creator: " + newIssue?.getCreator())
logger.debug("Reporter: " + newIssue?.getReporter())
//** METHODS:
public MutableIssue createIssue(ApplicationUser appUser, String summary, IssueService issueService, Logger logger){
//ComponentAccessor.getJiraAuthenticationContext().setLoggedInUser(appUser);
IssueInputParameters issueInputParameters1 = issueService.newIssueInputParameters(new HashMap())
issueInputParameters1.setProjectId(13609L) //set project Id
issueInputParameters1.setIssueTypeId("10100") //set issuetype
issueInputParameters1.setSummary(summary)
//issueInputParameters1.setReporterId(appUser.username)
issueInputParameters1.setSkipScreenCheck(true)
issueInputParameters1.setApplyDefaultValuesWhenParameterNotProvided(true)
//issueInputParameters1.setRetainExistingValuesWhenParameterNotProvided(true, true)
CreateValidationResult createValidationResult = issueService.validateCreate(appUser, issueInputParameters1)
boolean isValid = createValidationResult.isValid()
Map<String, String> errorCollection = createValidationResult.getErrorCollection().getErrors();
if(errorCollection){
logger.info("ERROR: Validation errors:" + errorCollection);
for (String errorKey : errorCollection.keySet()) {
logger.debug(errorKey)
logger.debug(errorCollection.get(errorKey))
}
}
if(isValid){
IssueResult issueResult = issueService.create(appUser, createValidationResult)
MutableIssue newIssue = (MutableIssue)issueResult.getIssue()
logger.debug("CreatedIssue: " + issueResult + " Issue Key: " + newIssue)
return newIssue
}
}
Hi @Joerg can you share your script? You need to call also validateCreate method. What user do you use for this?
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.bc.issue.IssueService.CreateValidationResult
import com.atlassian.jira.bc.issue.IssueService.IssueResult
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.issue.search.SearchResults
import com.atlassian.jira.bc.issue.search.SearchService.ParseResult
import com.atlassian.jira.web.bean.PagerFilter
import org.apache.log4j.Logger
import org.apache.log4j.Level
Logger logger = Logger.getLogger("create.example")
logger.setLevel(Level.DEBUG)
IssueManager issueManager = ComponentAccessor.getIssueManager()
UserManager userManager = ComponentAccessor.getUserManager()
CustomFieldManager customFieldManager1 = ComponentAccessor.getCustomFieldManager()
IssueService issueService = ComponentAccessor.getIssueService()
ApplicationUser appUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser() //Non-Admin User
ApplicationUser adminUser = userManager.getUserByName("autoassist") //Admin User
//Setting loggedInUser to adminUser (autoassist):
ComponentAccessor.getJiraAuthenticationContext().setLoggedInUser(adminUser);
String newSummary = "Create Test"
//creating with appUser, which is not adminUser "autoassist":
MutableIssue newIssue = createIssue(appUser, newSummary, issueService, logger)
logger.debug("New Issue: " + newIssue?.getKey())
//Both return "autoassist" as the Reporter and Creator:
logger.debug("Creator: " + newIssue?.getCreator())
logger.debug("Reporter: " + newIssue?.getReporter())
//** METHODS:
public MutableIssue createIssue(ApplicationUser appUser, String summary, IssueService issueService, Logger logger){
//ComponentAccessor.getJiraAuthenticationContext().setLoggedInUser(appUser);
IssueInputParameters issueInputParameters1 = issueService.newIssueInputParameters(new HashMap())
issueInputParameters1.setProjectId(13609L) //set project Id
issueInputParameters1.setIssueTypeId("10100") //set issuetype
issueInputParameters1.setSummary(summary)
//issueInputParameters1.setReporterId(appUser.username)
issueInputParameters1.setSkipScreenCheck(true)
issueInputParameters1.setApplyDefaultValuesWhenParameterNotProvided(true)
//issueInputParameters1.setRetainExistingValuesWhenParameterNotProvided(true, true)
CreateValidationResult createValidationResult = issueService.validateCreate(appUser, issueInputParameters1)
boolean isValid = createValidationResult.isValid()
Map<String, String> errorCollection = createValidationResult.getErrorCollection().getErrors();
if(errorCollection){
logger.info("ERROR: Validation errors:" + errorCollection);
for (String errorKey : errorCollection.keySet()) {
logger.debug(errorKey)
logger.debug(errorCollection.get(errorKey))
}
}
if(isValid){
IssueResult issueResult = issueService.create(appUser, createValidationResult)
MutableIssue newIssue = (MutableIssue)issueResult.getIssue()
logger.debug("CreatedIssue: " + issueResult + " Issue Key: " + newIssue)
return newIssue
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Joerg , it is interesting. I checked Jira source codes and it looks like setApplyDefaultValuesWhenParameterNotProvided might be the problem.
Short description:
public void populateDefaults(Map<String, Object> fieldValuesHolder, Issue issue) {
ApplicationUser remoteUser = getDefaultValue(issue);
if (remoteUser != null)
fieldValuesHolder.put(getId(), remoteUser.getName());
}
public ApplicationUser getDefaultValue(Issue issue) {
// The default value that should be set if the user cannot modify this field is the remote user's name
return getAuthenticationContext().getUser();
}
Can you try to call the method setApplyDefaultValuesWhenParameterNotProvided with false parameter?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Did some test anyway:
adjusted the script. I removed the create permission in the project from the "appUser". Only the adminUser now has create permission there:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.bc.issue.IssueService.CreateValidationResult
import com.atlassian.jira.bc.issue.IssueService.IssueResult
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.issue.search.SearchResults
import com.atlassian.jira.bc.issue.search.SearchService.ParseResult
import com.atlassian.jira.web.bean.PagerFilter
import org.apache.log4j.Logger
import org.apache.log4j.Level
Logger logger = Logger.getLogger("create.example")
logger.setLevel(Level.DEBUG)
IssueManager issueManager = ComponentAccessor.getIssueManager()
UserManager userManager = ComponentAccessor.getUserManager()
CustomFieldManager customFieldManager1 = ComponentAccessor.getCustomFieldManager()
IssueService issueService = ComponentAccessor.getIssueService()
//ApplicationUser appUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser() //Non-Admin User
ApplicationUser appUser = userManager.getUserByName($userWithoutCreatePermissionInProject) //Random User without create permissions in the project
ApplicationUser adminUser = userManager.getUserByName("autoassist") //Admin User
//Setting loggedInUser to User without create permissions in the project:
ComponentAccessor.getJiraAuthenticationContext().setLoggedInUser(appUser);
logger.debug("AppUser without Create Permission: " + appUser)
String newSummary = "Create Test"
//creating with adminUser "autoassist":
MutableIssue newIssue = createIssue(adminUser, newSummary, issueService, logger)
logger.debug("New Issue: " + newIssue?.getKey())
//Both return "autoassist" as the Reporter and Creator:
logger.debug("Creator: " + newIssue?.getCreator())
logger.debug("Reporter: " + newIssue?.getReporter())
//** METHODS:
public MutableIssue createIssue(ApplicationUser appUser, String summary, IssueService issueService, Logger logger){
//ComponentAccessor.getJiraAuthenticationContext().setLoggedInUser(appUser);
IssueInputParameters issueInputParameters1 = issueService.newIssueInputParameters(new HashMap())
issueInputParameters1.setProjectId(13609L) //set project Id
issueInputParameters1.setIssueTypeId("10100") //set issuetype
issueInputParameters1.setSummary(summary)
issueInputParameters1.setReporterId(appUser.username)
// There seems to be no method to set creator: issueInputParameters1.setCreatorId(appUser.username) ?
issueInputParameters1.setSkipScreenCheck(true)
issueInputParameters1.setApplyDefaultValuesWhenParameterNotProvided(false)
//issueInputParameters1.setRetainExistingValuesWhenParameterNotProvided(true, true)
CreateValidationResult createValidationResult = issueService.validateCreate(appUser, issueInputParameters1)
boolean isValid = createValidationResult.isValid()
Map<String, String> errorCollection = createValidationResult.getErrorCollection().getErrors();
if(errorCollection){
logger.info("ERROR: Validation errors:" + errorCollection);
for (String errorKey : errorCollection.keySet()) {
logger.debug(errorKey)
logger.debug(errorCollection.get(errorKey))
}
}
if(isValid){
IssueResult issueResult = issueService.create(appUser, createValidationResult)
MutableIssue newIssue = (MutableIssue)issueResult.getIssue()
logger.debug("CreatedIssue: " + issueResult + " Issue Key: " + newIssue)
return newIssue
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Joerg sorry for late response, I played with it few evenings and it's working now for me
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.bc.issue.IssueService.CreateValidationResult
import com.atlassian.jira.bc.issue.IssueService.IssueResult
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.issue.search.SearchResults
import com.atlassian.jira.bc.issue.search.SearchService.ParseResult
import com.atlassian.jira.web.bean.PagerFilter
import org.apache.log4j.Logger
import org.apache.log4j.Level
IssueManager issueManager = ComponentAccessor.getIssueManager()
UserManager userManager = ComponentAccessor.getUserManager()
CustomFieldManager customFieldManager1 = ComponentAccessor.getCustomFieldManager()
IssueService issueService = ComponentAccessor.getIssueService()
ApplicationUser appUser = userManager.getUserByName("a.leng@external.com") //Random User without create permissions in the project
ApplicationUser adminUser = userManager.getUserByName("martin.bayer@external.com") //Admin User
String newSummary = "Create Test"
//creating with adminUser "autoassist":
MutableIssue newIssue = createIssue(adminUser, appUser, newSummary, issueService, log)
log.error("New Issue: " + newIssue?.getKey())
//Both return "autoassist" as the Reporter and Creator:
log.error("Creator: " + newIssue?.getCreator())
log.error("Reporter: " + newIssue?.getReporter())
//** METHODS:
public MutableIssue createIssue(ApplicationUser adminUser, ApplicationUser appUser, String summary, IssueService issueService, Logger logger){
//ComponentAccessor.getJiraAuthenticationContext().setLoggedInUser(appUser);
IssueInputParameters issueInputParameters1 = issueService.newIssueInputParameters(new HashMap())
issueInputParameters1.setProjectId(10248L) //set project Id
issueInputParameters1.setIssueTypeId("10122") //set issuetype
issueInputParameters1.setSummary(summary)
issueInputParameters1.setReporterId(appUser.username)
issueInputParameters1.setSkipScreenCheck(true)
issueInputParameters1.setApplyDefaultValuesWhenParameterNotProvided(false)
CreateValidationResult createValidationResult = issueService.validateCreate(adminUser, issueInputParameters1)
boolean isValid = createValidationResult.isValid() && !createValidationResult.hasWarnings()
Map<String, String> errorCollection = createValidationResult.getErrorCollection().getErrors();
log.error "1:" + createValidationResult.isValid();
log.error "2:" + createValidationResult.getWarningCollection().hasAnyWarnings();
log.error "3:" + createValidationResult.hasWarnings();
log.error createValidationResult.getErrorCollection().getErrors();
def warningCollection = createValidationResult.getWarningCollection();
if(errorCollection || warningCollection){
logger.error("ERROR: Validation errors:" + errorCollection);
logger.error("Warning: Validation errors:" + warningCollection.getWarnings());
for (String errorKey : errorCollection.keySet()) {
logger.error(errorKey)
logger.error(errorCollection.get(errorKey))
}
}else{
logger.error("No error collection")
}
if(isValid){
IssueResult issueResult = issueService.create(adminUser, createValidationResult)
MutableIssue newIssue = (MutableIssue)issueResult.getIssue()
logger.error("CreatedIssue: " + issueResult + " Issue Key: " + newIssue)
return newIssue
}else{
logger.error("Invalid request")
}
}
I hope it will help... a little :)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hey.
So basically you are confirming that the permissions are run against the loggedInUser then (unless there is none, then reporte is used)?
I wonder what is the point of the parameter in the validate and create methods of IssueService then? Is the user in parameter used to check permissions, but when it comes to storing the issue, there is an additional permission check for the creator (normally LoggedInUser), which has to have the create permission as well?
If so, then I wonder if this is a bug or oversight by Atlassian, because it is definitely confusing.
I guess my workaround would be (if the currently loggedInUser has no permissions, and I need to create the issue with another user) to:
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.