From e133642a6c553f005c3fd3b048f1cea4c2759a68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=87=95=E9=B9=8F?= Date: Thu, 29 Oct 2020 15:33:53 +0800 Subject: [PATCH] =?UTF-8?q?activiti=E6=88=90=E5=8A=9F=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 +- .../com/example/demo/DemoApplication.java | 87 ++++++++++++++++++- .../demo/DemoApplicationConfiguration.java | 58 +++++++++++++ .../java/com/example/demo/SecurityUtil.java | 77 ++++++++++++++++ src/main/resources/application.yml | 5 ++ 5 files changed, 229 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/example/demo/DemoApplicationConfiguration.java create mode 100644 src/main/java/com/example/demo/SecurityUtil.java diff --git a/build.gradle b/build.gradle index efd0c49..38db876 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,9 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'com.aiprose:jpa-common-utils:2.3.4' - implementation 'org.activiti:activiti-spring-boot-starter:7.1.0.M5' + implementation 'org.activiti:activiti-spring-boot-starter:7.1.0.M4' + implementation 'org.activiti:activiti-image-generator:7.1.0.M4' + runtimeOnly 'mysql:mysql-connector-java' diff --git a/src/main/java/com/example/demo/DemoApplication.java b/src/main/java/com/example/demo/DemoApplication.java index 64b538a..73fa6a2 100644 --- a/src/main/java/com/example/demo/DemoApplication.java +++ b/src/main/java/com/example/demo/DemoApplication.java @@ -1,13 +1,98 @@ package com.example.demo; +import lombok.extern.slf4j.Slf4j; +import org.activiti.api.runtime.shared.query.Page; +import org.activiti.api.runtime.shared.query.Pageable; +import org.activiti.api.task.model.Task; +import org.activiti.api.task.model.builders.TaskPayloadBuilder; +import org.activiti.api.task.runtime.TaskRuntime; +import org.activiti.api.task.runtime.events.TaskAssignedEvent; +import org.activiti.api.task.runtime.events.TaskCompletedEvent; +import org.activiti.api.task.runtime.events.listener.TaskRuntimeEventListener; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +@Slf4j @SpringBootApplication -public class DemoApplication { +public class DemoApplication implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } + @Autowired + private TaskRuntime taskRuntime; + + @Autowired + private SecurityUtil securityUtil; + + @Override + public void run(String... args) { + + // Using Security Util to simulate a logged in user + securityUtil.logInAs("salaboy"); + + // Let's create a Group Task (not assigned, all the members of the group can claim it) + // Here 'salaboy' is the owner of the created task + log.info("> Creating a Group Task for 'activitiTeam'"); + taskRuntime.create(TaskPayloadBuilder.create() + .withName("First Team Task") + .withDescription("This is something really important") + .withCandidateGroup("activitiTeam") + .withPriority(10) + .build()); + + // Let's log in as 'other' user that doesn't belong to the 'activitiTeam' group + securityUtil.logInAs("other"); + + // Let's get all my tasks (as 'other' user) + log.info("> Getting all the tasks"); + Page tasks = taskRuntime.tasks(Pageable.of(0, 10)); + + // No tasks are returned + log.info("> Other cannot see the task: " + tasks.getTotalItems()); + + + // Now let's switch to a user that belongs to the activitiTeam + securityUtil.logInAs("erdemedeiros"); + + // Let's get 'erdemedeiros' tasks + log.info("> Getting all the tasks"); + tasks = taskRuntime.tasks(Pageable.of(0, 10)); + + // 'erdemedeiros' can see and claim the task + log.info("> erdemedeiros can see the task: " + tasks.getTotalItems()); + + + String availableTaskId = tasks.getContent().get(0).getId(); + + // Let's claim the task, after the claim, nobody else can see the task and 'erdemedeiros' becomes the assignee + log.info("> Claiming the task"); + taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(availableTaskId).build()); + + + // Let's complete the task + log.info("> Completing the task"); + taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(availableTaskId).build()); + + + } + + @Bean + public TaskRuntimeEventListener taskAssignedListener() { + return taskAssigned -> log.info(">>> Task Assigned: '" + + taskAssigned.getEntity().getName() + + "' We can send a notification to the assginee: " + taskAssigned.getEntity().getAssignee()); + } + + @Bean + public TaskRuntimeEventListener taskCompletedListener() { + return taskCompleted -> log.info(">>> Task Completed: '" + + taskCompleted.getEntity().getName() + + "' We can send a notification to the owner: " + taskCompleted.getEntity().getOwner()); + } + } diff --git a/src/main/java/com/example/demo/DemoApplicationConfiguration.java b/src/main/java/com/example/demo/DemoApplicationConfiguration.java new file mode 100644 index 0000000..247e371 --- /dev/null +++ b/src/main/java/com/example/demo/DemoApplicationConfiguration.java @@ -0,0 +1,58 @@ +package com.example.demo; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author yanpeng + * @version 1.0 + * @desc TODO + * @company 北京中经网软件有限公司 + * @date 2020/10/29 13:54 + */ +@Slf4j +@Configuration +public class DemoApplicationConfiguration { + + @Bean + public UserDetailsService myUserDetailsService() { + + InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager(); + + String[][] usersGroupsAndRoles = { + {"salaboy", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"}, + {"ryandawsonuk", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"}, + {"erdemedeiros", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"}, + {"other", "password", "ROLE_ACTIVITI_USER", "GROUP_otherTeam"}, + {"admin", "password", "ROLE_ACTIVITI_ADMIN"}, + }; + + for (String[] user : usersGroupsAndRoles) { + List authoritiesStrings = Arrays.asList(Arrays.copyOfRange(user, 2, user.length)); + log.info("> Registering new user: " + user[0] + " with the following Authorities[" + authoritiesStrings + "]"); + inMemoryUserDetailsManager.createUser(new User(user[0], passwordEncoder().encode(user[1]), + authoritiesStrings.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList()))); + } + + + return inMemoryUserDetailsManager; + } + + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/example/demo/SecurityUtil.java b/src/main/java/com/example/demo/SecurityUtil.java new file mode 100644 index 0000000..f532683 --- /dev/null +++ b/src/main/java/com/example/demo/SecurityUtil.java @@ -0,0 +1,77 @@ +package com.example.demo; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.context.SecurityContextImpl; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.stereotype.Component; + +import java.util.Collection; + + +/** + * @author yanpeng + * @version 1.0 + * @desc TODO + * @company 北京中经网软件有限公司 + * @date 2020/10/29 13:48 + */ +@Component +public class SecurityUtil { + + private Logger logger = LoggerFactory.getLogger(SecurityUtil.class); + + @Autowired + private UserDetailsService userDetailsService; + + public void logInAs(String username) { + + UserDetails user = userDetailsService.loadUserByUsername(username); + if (user == null) { + throw new IllegalStateException("User " + username + " doesn't exist, please provide a valid user"); + } + logger.info("> Logged in as: " + username); + SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() { + @Override + public Collection getAuthorities() { + return user.getAuthorities(); + } + + @Override + public Object getCredentials() { + return user.getPassword(); + } + + @Override + public Object getDetails() { + return user; + } + + @Override + public Object getPrincipal() { + return user; + } + + @Override + public boolean isAuthenticated() { + return true; + } + + @Override + public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { + + } + + @Override + public String getName() { + return user.getUsername(); + } + })); + org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username); + } +} \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index c20280c..c6fd6ff 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,11 @@ server: port: 9981 spring: + activiti: + database-schema-update: true + history-level: full + db-history-used: true + jpa: hibernate: ddl-auto: update