Accessing deployed ProcessDefinitions outside a process

Hi everyone,

I am currently working on my own implementation of the Tasklist for my JavaEE processes. I want to show the authenticated user all processes he can start and all tasks that are assigned to him.

The authentication works fine. After a custom login page, I have access to the camunda user (id, firstname, email…) and can show him all his assigned tasks. But I have a problem getting a list of of the deployed processDefinitions.

When I use the following code inside a usertask it works:

@Inject 
private RepositoryService repositoryService;   

private List<ProcessDefinition> allProcesses;   

public List<ProcessDefinition> getAllProcesses() { 
    allProcesses = 
      repositoryService.createProcessDefinitionQuery().includeProcessDefinitionsWithoutTenantId().list() 
    return allProcesses; 
} 
// I added 'includeProcessDefinitionsWithoutTenantId' to make sure I get all processes because none have tenants
//it might also work just to do query().list(). But thats not part of the question ;) 

But if I use exactly the same code in my HomePageController, ‘allProcesses’ has no entries.
I think the injection of the RepositoryService worked - it is at least not null. But it seems not to have access to the deployed processes. Do you know what I did wrong? And how can I fix this problem?

(By the way, I also injected the IdentityService and TaskService and both work fine.)

Thanks in advance!
Leo :slight_smile:

Hi @Leo,

maybe the authentication is not set for this request?

It could explain the behaviour.

Hope this helps, Ingo

Thanks for the response :slight_smile:

The authentification should be set. At least I can access the

identityService.getCurrentAuthentication().getUserId()

in the same class.
I find this very confusing that the injection of the identityService and TaskService worked but the repositoryService seems to not know anything.

Here is my code:


import java.io.Serializable;
import java.util.List;
import java.util.logging.Logger;

import javax.enterprise.context.ConversationScoped;
import javax.inject.Inject;
import javax.inject.Named;

import org.camunda.bpm.engine.IdentityService;
import org.camunda.bpm.engine.RepositoryService;
import org.camunda.bpm.engine.TaskService;
import org.camunda.bpm.engine.identity.User;
import org.camunda.bpm.engine.repository.ProcessDefinition;
import org.camunda.bpm.engine.task.Task;

@Named
@ConversationScoped
public class StartseiteController implements Serializable{

	private static final long serialVersionUID = -6909925701157694823L;

	@Inject
	private TaskService taskService;
	
	@Inject
	private IdentityService identityService;

	@Inject
	private RepositoryService repositoryService;
	
	private final Logger LOGGER = Logger.getLogger(StartseiteController.class.getName());

	private String firstname;
	private List<ProcessDefinition> allProcesses;
	private List<Task> openTasks;

	// does not work. Always returns a list with no entries.
	public List<ProcessDefinition> getAllProcesses() {
		if (allProcesses == null) {
			//startbareProzesse = repositoryService.createProcessDefinitionQuery()
			//		.startableByUser(identityService.getCurrentAuthentication().getUserId()).list();
			allProcesses = repositoryService.createProcessDefinitionQuery().includeProcessDefinitionsWithoutTenantId().list();
			LOGGER.info("allProcesses"+allProcesses.size()); //always logs "0"
		}
		return allProcesses;
	}

	//works
	public List<Task> getOpenTasks() {
		if (openTasks == null) {
			openTasks = taskService.createTaskQuery().taskAssigneeIn(identityService.getCurrentAuthentication().getUserId()).list();
			LOGGER.info("openTasks"+openTasks.size()); //logs the currect number of assigned tasks
		}
		return openTasks;
	}
	
	//works
	public String getFirstname() {
		if(firstname == null) {
			User user = identityService.createUserQuery().userId(identityService.getCurrentAuthentication().getUserId()).singleResult();
			firstname = user.getFirstName();
		}
		return firstname;
	}
}

And here is a simplified version of the login method of the login.xhtml-Controller: (‘the authentificationController’ gets called by a session-scoped LoginFormController.)

import java.util.List;
import java.util.logging.Logger;

import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.inject.Named;

import org.camunda.bpm.engine.IdentityService;

@Named
@Stateless
public class AuthentifizierungController {

	@Inject
	private IdentityService identityService;

	private final Logger LOGGER = Logger.getLogger(AuthentifizierungController.class.getName());
	
	
	public boolean handleLogin(String nutzerKennung) throws Exception {
		if(identityService.getCurrentAuthentication()!=null) {
			LOGGER.severe("\n\n Fehler: Es ist derzeit ein Nutzer eingeloggt. \n\n");
			throw new Exception("Es ist bereits ein Nutzer eingeloggt");
		}
		identityService.setAuthenticatedUserId(nutzerKennung);
		return true;
	}
	
	public void logout() {
		identityService.clearAuthentication();
	}
}

Sorry but I have to return to the topic. I haven’t fixed the problem yet. But I began to
isolate the problem:

It has something to do with the redirection from login.xhtml to startseite.xhtml AND/OR the authenticatedUser as @Ingo_Richtsmeier suggested.

Because when i changed the StartseiteController.class in a way that I can access the startseite.xhtml without the login-step I see all processes, tasks and userInformation of the authenticated user.

Do you know what I am doing wrong? I still don’t get why I can access everything about the autheticated user but not the processes. At least everything should break… not just one part ^^

Thanks in advance!
Leo

Here is my simplefied code which still returns a empty allProcessesList:

startseite.xhtml:

...
		<h:form id="loginForm">
				<h:panelGrid columns="2" class="zweiSpaltenForm">
					<h:outputLabel for="nutzerKennung" value="Nutzername" />
					<h:inputText id="nutzerKennung"
						value="#{loginFormularController.nutzerKennung}" required="true"
						requiredMessage="Nutzername benötigt" />
				<h:commandButton id="submit_button" value="Login"
					action="#{loginFormularController.login()}" />
				<h:messages showDetail="true"></h:messages>
			</h:form>
...

LoginFormularController.java

import java.io.Serializable;
import java.util.logging.Logger;

import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;

import org.camunda.bpm.engine.IdentityService;

@Named
@SessionScoped
public class LoginFormularController implements Serializable {

	@Inject
	private IdentityService identityService;

	@Inject
	private Logger LOGGER;


	private static final long serialVersionUID = -4877226356894468571L;

	private String nutzerKennung;

	public String getNutzerKennung() {
		return nutzerKennung;
	}

	public void setNutzerKennung(String nutzerKennung) {
		this.nutzerKennung = nutzerKennung;
	}


	public String login() {
		try {
			if (identityService.getCurrentAuthentication() != null) {
				LOGGER.severe("\n\n Fehler: Es ist derzeit ein Nutzer eingeloggt. \n\n");
				throw new Exception("Es ist bereits ein Nutzer eingeloggt");
			}
			identityService.setAuthenticatedUserId(nutzerKennung);
			return "startseite.jsf";
		} catch (Exception e) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage(FacesMessage.SEVERITY_ERROR, "Es ist ein Fehler aufgetreten", ""));
			return "login";
		}
	}
}

and finally
StartseiteController.java

import java.io.Serializable;
import java.util.List;
import java.util.logging.Logger;

import javax.enterprise.context.ConversationScoped;
import javax.inject.Inject;
import javax.inject.Named;

import org.camunda.bpm.engine.IdentityService;
import org.camunda.bpm.engine.RepositoryService;
import org.camunda.bpm.engine.TaskService;
import org.camunda.bpm.engine.identity.User;
import org.camunda.bpm.engine.repository.ProcessDefinition;
import org.camunda.bpm.engine.task.Task;

@Named
@ConversationScoped
public class StartseiteController implements Serializable{

	private static final long serialVersionUID = -6909925701157694823L;

	@Inject
	private TaskService taskService;
	
	@Inject
	private IdentityService identityService;

	@Inject
	private RepositoryService repositoryService;
	
	private final Logger LOGGER = Logger.getLogger(StartseiteController.class.getName());

	private String firstname;
	private List<ProcessDefinition> allProcesses;
	private List<Task> openTasks;
    private String authenticatedUserId;

	@PostConstruct
	void init() {
		authenticatedUserId= identityService.getCurrentAuthentication().getUserId();
	}


	// does not work. Always returns a list with no entries.
	public List<ProcessDefinition> getAllProcesses() {
		if (allProcesses == null) {
			allProcesses = repositoryService.createProcessDefinitionQuery().latestVersion().list();
			LOGGER.info("allProcesses"+allProcesses.size()); //always logs "0"
		}
		return allProcesses;
	}

	//works
	public List<Task> getOpenTasks() {
		if (openTasks == null) {
			openTasks = taskService.createTaskQuery().taskAssigneeIn(authenticatedUserId).list();
			LOGGER.info("openTasks"+openTasks.size()); //logs the currect number of assigned tasks
		}
		return openTasks;
	}
	
	//works
	public String getFirstname() {
		if(firstname == null) {
			User user = identityService.createUserQuery().userId(authenticatedUserId).singleResult();
			firstname = user.getFirstName();
		}
		return firstname;
	}
}

Here is another piece of the puzzle:

if i write in the StartseiteController and enter after starting the server directly in the startseite.xhtml it everything works.

	@PostConstruct
	void init() {
		authenticatedUserId = "demo";
	}

if i write the same thing in the StartseiteController and enter after starting the server directly in the login.xhtml and authenticate myself there, allProcesses has no entries. Even if I dont use the identityService.getCurrentAuthentication().getUserId() at all in the StartseiteController.

	@PostConstruct
	void init() {
		authenticatedUserId = "demo";
	}

If I write in the StartseiteController and enter after starting the server directly in the startseite.xhtml the List allProcesses also has no entries

	@PostConstruct
	void init() {
        identityService.setAuthenticatedUserId("demo");
		authenticatedUserId = identityService.getCurrentAuthentication().getUserId();
	}

I hope this helps helping me ^^

Finally I found the source of the problem! I used the wrong identityService method.

I used

identityService.setAuthenticatedUserId(userId);

instead of

identityService.setAuthentication(userId, groups);

I thought if I use setAuthenticatedUserId, the currentAuthentication gets the authorizations of all groups the user is a member of…

My code now looks like this and works:

	public String login() {
		try {
			if (isAUserAuthenticated()) {
				throw new Exception("A User is already authenticated");
			}
			List<Group> groupList = identityService.createGroupQuery().groupMember(userId).list();
			List<String> groupIdList = new ArrayList<String>();
			groupList.forEach(group -> {
				groupIdList.add(group.getId());
			});
			identityService.setAuthentication(userId, groupIdList);
			return "startseite.jsf";
		} catch (Exception e) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage(FacesMessage.SEVERITY_ERROR, "An Error occurred", ""));
			return "login";
		}
	}

The only remaining question is: What is the use case for ‘identityService.setAuthenticatedUserId(userId)’ ?

I am so glad I finally found the issue! :smiley: