AnsweredAssumed Answered

Activiti/Spring Boot- Spring Security - User and Membership management

Question asked by neohadoop on Jul 14, 2016
I am using spring boot plus activiti.

Pom.xml:
<code>
<dependencies>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-jpa</artifactId>
      </dependency>
      <dependency>
         <groupId>org.activiti</groupId>
         <artifactId>activiti-spring-boot-starter-jpa</artifactId>
         <version>5.19.0</version>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-thymeleaf</artifactId>
      </dependency>
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
      <dependency>
         <groupId>org.activiti</groupId>
         <artifactId>activiti-spring-boot-starter-security</artifactId>
         <version>5.19.0</version>
      </dependency>
        <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-aop</artifactId>
      </dependency>
        <dependency>
          <groupId>org.springframework.security</groupId>
          <artifactId>spring-security-ldap</artifactId>
      </dependency>
      <dependency>
           <groupId>org.springframework.ldap</groupId>
           <artifactId>spring-ldap-core</artifactId>
           <version>2.1.0.RELEASE</version>
       </dependency>
      <dependency>
         <groupId>org.activiti</groupId>
         <artifactId>activiti-spring-boot-starter-basic</artifactId>
         <version>5.19.0</version>
      </dependency>
       <dependency>
          <groupId>org.thymeleaf.extras</groupId>
          <artifactId>thymeleaf-extras-springsecurity4</artifactId>
         <version>2.1.2.RELEASE</version>
      </dependency>
      
      <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <scope>runtime</scope>
      </dependency>
      <dependency>
          <groupId>org.forgerock.openam</groupId>
           <artifactId>openam-clientsdk</artifactId>
           <version>10.1.0-Xpress</version>
       </dependency>
      <dependency>
         <groupId>com.twilio.sdk</groupId>
         <artifactId>twilio-java-sdk</artifactId>
         <version>3.4.1</version>
         <scope>compile</scope>
         <exclusions>
            <exclusion>
               <groupId>org.apache.httpcomponents</groupId>
               <artifactId>httpclient</artifactId>
            </exclusion>
         </exclusions>
      </dependency>
      <dependency>
         <groupId>com.sendgrid</groupId>
         <artifactId>sendgrid-java</artifactId>
         <version>2.1.0</version>
      </dependency>
      <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
      </dependency>
      
      
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
      <dependency>
         <groupId>org.liquibase</groupId>
         <artifactId>liquibase-core</artifactId>
         <version>3.5.0</version>
      </dependency>
   </dependencies>
<code>

My APP User Creation Class:
<java>
public class UserService implements IUserService {

   @Autowired
   private UserRepository repo;

   @Autowired
   private IdentityService identityService;
   
   @Override
   public User addUserGroup(User user) {
      UserRoleGroup urg = UserRoleGroup.getNewInstance();
      urg.setUser(user);
      urg.setGroup(user.getRole().getGroup());
      user.getGroups().add(urg);
      return user;
   }

   @Override
   public User create(User model) {
      User appUser = repo.saveAndFlush(model);
      //Add this new user to workflow
      addUserToWorkflow(appUser, false);
      return appUser;
   }
   
   @Override
   public boolean delete(Serializable key) {
      repo.delete((String) key);
      return true;
   }

      @Override
   public User update(User model) {
      User updatedAppUser = repo.saveAndFlush(model);
      //Update the Workflow user
      addUserToWorkflow(updatedAppUser, true);
      return updatedAppUser;
   }


//HOW to keep MY App user information and Group Memebership in Activiti in sync???
   private void addUserToWorkflow(User appUser, Boolean isUserUpdated){
      //Now create workflow membership, groups for the user
      if(appUser != null && appUser.getId() != null) {
         if (!isUserUpdated && identityService.createUserQuery().userId(appUser.getId().toString()).count() == 0) {

            org.activiti.engine.identity.User wfUser = identityService.newUser(appUser.getId().toString());
            wfUser.setFirstName(appUser.getFirstName());
            wfUser.setLastName(appUser.getLastName());
            identityService.saveUser(wfUser);
            if (appUser != null && appUser.getRole() != null && appUser.getRole().getGroup() != null) {
                  identityService.createMembership(appUser.getId().toString(), appUser.getRole().getGroup().getValue());
            }
         } else {
            org.activiti.engine.identity.User existingWFUser = identityService.createUserQuery().userId(appUser.getId()).singleResult();
            existingWFUser.setFirstName(appUser.getFirstName());
            existingWFUser.setLastName(appUser.getLastName());
            identityService.saveUser(existingWFUser);
            if (appUser != null && appUser.getRole() != null && appUser.getRole().getGroup() != null) {
            
               identityService.createMembership(appUser.getId().toString(), appUser.getRole().getGroup().getValue());
            }
         }
      }
   }
<java>

Tools Used:
1) Spring Boot with JPA
2) MySQL
3) Activiti 5.19 (I can change to newer or any other version, if you suggest)


Business Requirements:
1) Approve/Rejection/Status update workflow
2) Assign a task to group
3) Once #2 task completed, move to next task and assign that to next group until End state

Statuses in workflow:
DRAFT -> REVIEW -> APPROVE -> SIGNED -> COMPLETED with boundary event 'REJECTED'

Questions:
1) How to keep my app's User and their roles/Groups in sync with Activititi? DO I have to keep them in sync in the first place?
2) How can I use my app's Users/Groups to assign to the activiti user task with expression without Activiti users/groups?

Any help or direction here is very much appreciated!!!!!!!!

Outcomes