How to create issue without logged in user

Hi Experts,

I have rest service to create issue in my jira plugin which is calling by third party api but the while creating issue i am getting below exception.

Exception:
[INFO] [talledLocalContainer] 2. Error while creating issue: {issuetype=The issue type selected is invalid., pid=Anonymous users do not have permission to create issues in this project. Please try logging in first.}

Note:
how to provide user in create method of issueService interface ( issueService.create(user, createValidationResult) because no buddy logged in while creating issue it is just background service which is calling by third party api to create issue in particular project. Please suggsest some idea to solve this problem.

Code:

IssueService issueService = ComponentAccessor.getComponent(IssueService.class);
		IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
		
		
		String projectKey="IHD";
		issueInputParameters.setSummary("123"+ ":"+"Create Jira Id");
		issueInputParameters.setIssueTypeId("10000");
		issueInputParameters.setAssigneeId("admin");
		issueInputParameters.setReporterId("admin");
		issueInputParameters.setPriorityId("1");
		issueInputParameters.setDescription("Create Jira Id");
		
		ProjectService projectService = ComponentAccessor.getComponent(ProjectService.class);
		Project project = projectService.getProjectByKey(ComponentAccessor.getUserManager().getUserByKey("dipesh"), projectKey).getProject();
		issueInputParameters.setProjectId(project.getId());
		
		CreateValidationResult  createValidationResult = issueService.validateCreate(ComponentAccessor.getUserManager().getUserByKey("dipesh"), issueInputParameters);
		
		
		if (_**createValidationResult.getErrorCollection().hasAnyErrors())**_ {
			// If the validation fails, render the list of issues with the error in a flash message
			System.out.println("Error while creating issue: "+createValidationResult.getErrorCollection().getErrors());
		}

		if (createValidationResult.isValid()) {
			**IssueResult createResult = issueService.create(ComponentAccessor.getUserManager().getUserByKey("dipesh"), createValidationResult);**
			System.out.println("Issue Created. issueId: "+createResult.getIssue().getId());
		}

Does the user with the user key with dipesh exist? If that’s a username - use getUserByName instead. I think your issue is that the user object is null (which is the system version of anonymous).

While you’re here:

Stop using ComponentAccessor - it’s a code smell. You’ll have issues with osgi at some point. It’s one of those things that you really should only use as a last resort. You’re basically causing OSGi to do a look up for services every time that your code gets triggered. Inject the services your using (makes unit testing and mocking so much easier - and the system will appreciate you :slight_smile: ).

2 Likes

Hi Daniel,

Thanks for your quick response. Yes dipesh user is available and having administration access also . I am successfully getting project information with the below code and that below project object is giving me project information also it means i am getting user information with my code.
code:

Project project = projectService.getProjectByKey(ComponentAccessor.getUserManager().getUserByKey("dipesh"), projectKey).getProject();

Note:
The problem is that once i call the below lines validateCreate method then the same user throwing exception “Anonymous users do not have permission to create issues in this project. Please try logging in first”. I don’t know why its is taking “dipesh” application user as Anonymous users only calling validateCreate method. So i am in trouble how to create issue without logged In user.

CreateValidationResult  createValidationResult = issueService.validateCreate(ComponentAccessor.getUserManager().getUserByKey("dipesh"), issueInputParameters);
		
		
		if (_**createValidationResult.getErrorCollection().hasAnyErrors())**_ {
			// If the validation fails, render the list of issues with the error in a flash message
			System.out.println("Error while creating issue: "+createValidationResult.getErrorCollection().getErrors());
		}

Can you validate that you’re getting an object back from the getUserManager().getUserByKey(“dipesh”) call? ProjectService is honoring the permissions on the project so if the project permission allows for anonymous users to browse the project - then passing in null will still let you get the project.

1 Like

Yes @daniel,

I am getting user object by getUserManager().getUserByKey(“dipesh”) and i am able to print the user information like email address etc. But i am having problem in below line. I am passing user object but internally i think it is validating only logged in user. How can i get logged in user as my service is not interacting with user interface.

issueService.validateCreate(ComponentAccessor.getUserManager().getUserByKey("dipesh"), issueInputParameters);

Hi @daniel,
I have user name and password of the dipesh user. Can we have some interface there i can logging in and get application user object and can pass to validateCreate method by programmatically .

What you are seeing is just JIRA’s way of freaking out when you attempt to pass an erroneous validation result to IssueService.create. It’s a particularly unhelpful error message, granted, but I’ve seen this before.

You are printing out a message if the validation result is invalid, but you actually need to prevent the call to IssueService.create in that case.

Hi @david.pinn,

I am validating result but my problem is passing application user in to methods(issueService.validateCreate(), issueService.create()). How can i pass if user in not logged in on application. Any reference for login method so i can pass username and password and get the applicationUser to create issue.

Code:

CreateValidationResult createValidationResult = issueService.validateCreate(**user**, issueInputParameters);

if (createValidationResult.isValid()) {
   		IssueResult createResult = issueService.create(user, createValidationResult);
}


The user does not need to be logged in; they just need to be a valid user with permission to create issues in the relevant project.

I suggest that you carefully examine IssueInputParameters. You might need to setSkipScreenCheck, for example.

1 Like

Hi @david.pinn,

I tried “setSkipScreenCheck” with false and true value. Still having same exception :confused:

Exception:
{issuetype=The issue type selected is invalid., pid=Anonymous users do not have permission to create issues in this project. Please try logging in first.}

Just realised that you’ve asked this question, essentially, before in “How to give administrative permission to Scheduler”. I thought it seemed familiar.

It seems that you may be stumbling over this code in the ProjectSystemField class:

    if (authenticationContext.getUser() != null) {
        errorCollectionToAddTo.addError(FIELD_PARAMETER_NAME, i18n.getText("createissue.projectnopermission"), Reason.FORBIDDEN);
    } else {
        errorCollectionToAddTo.addError(FIELD_PARAMETER_NAME, i18n.getText("createissue.projectnopermission.notloggedin"), Reason.NOT_LOGGED_IN);
    }

How about you try this: use com.atlassian.jira.issue.IssueManager which has the following method:

Issue createIssueObject(ApplicationUser remoteUser, Map<String, Object> fields) throws CreateException;

You can get the IssueManager via ComponentAccessor.getIssueManager, but as @daniel suggested, it’s better to get it injected via dependency injection.

Hi @david.pinn & @daniel,

I got the solution. I need to pass basic authentication of JIRA user in header of third party api client then i can able to get logged in user by below methods. Thanks to all.

Request xml of thirrd part api which is calling JIRA Rest service:

Note: You need to do base64 encode of your username and password in below format:
Example: username:password

Code to get logged in user:

ApplicationUser user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser();

Now i am able to create JIRA issues by third party api. :relaxed:

I am having this same issue, but there is a possibility of multiple threads running at the same time with different users. Setting the logged in user through the JiraAuthenticationContext will create a race condition. Is there a way to skip authentication for creating an issue?

I looked through documentation and the source code and it doesn’t look like there’s a way to spoof authentication.

I am trying using a synchronized method. It’s difficult to test but I will try to get back if it works.

I injected the IssueService and JiraAuthenticationContext via the @ComponentImport tag in the constructor.

    private synchronized IssueService.CreateValidationResult syncValidateSubTaskCreate(ApplicationUser user, long parentId, IssueInputParameters params) {
        jiraAuthenticationContext.setLoggedInUser(user);
        return issueService.validateSubTaskCreate(user, parentId, params);
    }

EDIT: Turns out this is not necessary, the JiraAuthenticationContext handles multiple threads at the same time even though it’s at the class level. I guess I got a little too excited about concepts from an advanced Java course I’m taking :grin: