Skip to content

Commit 416bac4

Browse files
authored
Merge pull request kaakaww#25 from kaakaww/feature/SCAN-300/add-multi-tenancy
Feature/scan 300/add multi tenancy
2 parents b353997 + eed63fe commit 416bac4

File tree

16 files changed

+252
-50
lines changed

16 files changed

+252
-50
lines changed

src/main/java/hawk/Application.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.Arrays;
44
import java.util.stream.Stream;
55

6+
import hawk.context.TenantContext;
67
import hawk.entity.Item;
78
import hawk.entity.User;
89
import hawk.repos.ItemRepo;
@@ -60,13 +61,22 @@ public CommandLineRunner commandLineRunner(ApplicationContext ctx, ItemRepo repo
6061
if (userRepo.count() == 0) {
6162
userRepo.findAll().forEach(item -> System.out.println(String.format("item: %s", item.getName())));
6263

64+
TenantContext.setCurrentTenant("1234567");
6365
Stream.of(1, 2, 3).forEach(i -> {
66+
System.out.println(String.format("Adding user%d", i));
67+
userRepo.save(new User(String.format("user%d", i), String.format("we have the best users, users%d", i), "1234567"));
68+
});
69+
userRepo.save(new User("user", "The auth user", "1234567"));
70+
71+
TenantContext.setCurrentTenant("12345678");
72+
Stream.of(4, 5, 6).forEach(i -> {
6473
System.out.println(String.format("Adding item%d", i));
65-
userRepo.save(new User(String.format("user%d", i), String.format("we have the best users, users%d", i)));
74+
userRepo.save(new User(String.format("user%d", i), String.format("we have the best users, users%d", i), "12345678"));
6675
});
6776

77+
6878
System.out.println(String.format("Items in DB %d", userRepo.count()));
69-
userRepo.findAll().forEach(item -> System.out.println(String.format("item: %s", item.getName())));
79+
userRepo.findAll().forEach(item -> System.out.println(String.format("user: %s", item.getName())));
7080
}
7181

7282
};

src/main/java/hawk/Config.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package hawk;
22

33
import hawk.service.SearchService;
4+
import hawk.service.UserSearchService;
45
import hawk.service.UserService;
56
import org.springframework.context.annotation.Bean;
67
import org.springframework.context.annotation.Configuration;
@@ -10,12 +11,13 @@
1011
@Configuration
1112
@EnableJpaRepositories
1213
public class Config implements WebMvcConfigurer {
13-
1414
@Bean
1515
public SearchService searchService(){
1616
return new SearchService();
1717
}
1818
@Bean
19+
public UserSearchService userSearchService() { return new UserSearchService(); }
20+
@Bean
1921
public UserService userService() { return new UserService(); }
2022

2123
}

src/main/java/hawk/api/AuthenticationRequest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ public class AuthenticationRequest implements Serializable {
1515
private static final long serialVersionUID = -6986746375915710855L;
1616
private String username;
1717
private String password;
18+
private String tenant;
1819
}

src/main/java/hawk/api/jwt/JwtAuthController.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package hawk.api.jwt;
22

33
import hawk.api.AuthenticationRequest;
4+
import hawk.repos.UserRepo;
45
import org.springframework.beans.factory.annotation.Autowired;
56
import org.springframework.http.ResponseEntity;
67
import org.springframework.security.authentication.AuthenticationManager;
@@ -27,12 +28,15 @@ public class JwtAuthController {
2728
private final AuthenticationManager authenticationManager;
2829
private final JwtTokenProvider jwtTokenProvider;
2930
private final UserDetailsService userDetailsService;
31+
private final UserRepo userRepo;
3032

3133
@Autowired
32-
public JwtAuthController(AuthenticationManager authenticationManager, JwtTokenProvider jwtTokenProvider, UserDetailsService userDetailsService) {
34+
public JwtAuthController(AuthenticationManager authenticationManager, JwtTokenProvider jwtTokenProvider, UserDetailsService userDetailsService,
35+
UserRepo userRepo) {
3336
this.authenticationManager = authenticationManager;
3437
this.jwtTokenProvider = jwtTokenProvider;
3538
this.userDetailsService = userDetailsService;
39+
this.userRepo = userRepo;
3640
}
3741

3842
@PostMapping("/signin")
@@ -44,8 +48,11 @@ public ResponseEntity signin(@RequestBody AuthenticationRequest data) {
4448
if (null == userDetails) {
4549
throw new UsernameNotFoundException("username");
4650
}
51+
52+
String tenantId = this.userRepo.findByName(username).getTenantId();
4753
String token = jwtTokenProvider.createToken(username,
48-
userDetails.getAuthorities().stream().map(auth -> ((GrantedAuthority) auth).toString()).collect(Collectors.toList()));
54+
userDetails.getAuthorities().stream().map(auth -> ((GrantedAuthority) auth).toString()).collect(Collectors.toList()),
55+
tenantId);
4956
Map<Object, Object> model = new HashMap<>();
5057
model.put("username", username);
5158
model.put("token", token);

src/main/java/hawk/api/jwt/JwtFilter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package hawk.api.jwt;
22

33
import hawk.api.jwt.JwtTokenProvider;
4+
import hawk.context.TenantContext;
45
import org.springframework.security.core.Authentication;
56
import org.springframework.security.core.context.SecurityContextHolder;
67
import org.springframework.web.filter.GenericFilterBean;
@@ -28,6 +29,7 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain filter
2829
if (token != null && jwtTokenProvider.validateToken(token)) {
2930
Authentication auth = token != null ? jwtTokenProvider.getAuthentication(token) : null;
3031
SecurityContextHolder.getContext().setAuthentication(auth);
32+
TenantContext.setCurrentTenant(jwtTokenProvider.getTenantId(token));
3133
}
3234

3335
filterChain.doFilter(req, res);

src/main/java/hawk/api/jwt/JwtTokenProvider.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ protected void init() {
3636
secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes());
3737
}
3838

39-
public String createToken(String username, List<String> roles) {
39+
public String createToken(String username, List<String> roles, String companyId) {
4040
Claims claims = Jwts.claims().setSubject(username);
4141
claims.put("roles", roles);
42+
claims.put("tenantId", companyId);
4243
Date now = new Date();
4344
Date validity = new Date(now.getTime() + validityInMilliseconds);
4445
return Jwts.builder()//
@@ -58,6 +59,10 @@ private String getUsername(String token) {
5859
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();
5960
}
6061

62+
public String getTenantId(String token) {
63+
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().get("tenantId", String.class);
64+
}
65+
6166
public String resolveToken(HttpServletRequest req) {
6267
String bearerToken = req.getHeader("Authorization");
6368
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package hawk.api.jwt;
22

3+
import hawk.entity.User;
34
import hawk.form.Search;
4-
import hawk.service.SearchService;
5+
import hawk.service.UserSearchService;
56
import hawk.service.UserService;
67
import org.springframework.beans.factory.annotation.Autowired;
78
import org.springframework.http.ResponseEntity;
@@ -10,26 +11,37 @@
1011
import org.springframework.web.bind.annotation.RequestMapping;
1112
import org.springframework.web.bind.annotation.RestController;
1213

14+
import java.util.ArrayList;
15+
import java.util.List;
16+
1317
@RestController
1418
@RequestMapping("/api/jwt/users")
1519
public class JwtUserController {
1620

1721
private final UserService userService;
22+
private final UserSearchService userSearchService;
1823

1924
@Autowired
20-
public JwtUserController(UserService userService) {
25+
public JwtUserController(UserService userService, UserSearchService userSearchService) {
2126
this.userService = userService;
27+
this.userSearchService = userSearchService;
2228
}
2329

2430
@GetMapping("/search/")
2531
public ResponseEntity searchAll() {
2632
Search search = new Search("");
27-
return ResponseEntity.ok(userService.search(search));
33+
return ResponseEntity.ok(this.userService.findUsersByName(""));
2834
}
2935

3036
@GetMapping("/search/{text}")
3137
public ResponseEntity search(@PathVariable("text") String text) {
3238
Search search = new Search(text);
33-
return ResponseEntity.ok(userService.search(search));
39+
return ResponseEntity.ok(this.userService.findUsersByName(search.getSearchText()));
40+
}
41+
42+
@GetMapping("/search/bad/{text}")
43+
public ResponseEntity searchCrappy(@PathVariable("text") String text) {
44+
Search search = new Search(text);
45+
return ResponseEntity.ok(this.userSearchService.search(search));
3446
}
3547
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package hawk.aspect;
2+
3+
import hawk.context.TenantContext;
4+
import org.aspectj.lang.JoinPoint;
5+
import org.aspectj.lang.annotation.Aspect;
6+
import org.aspectj.lang.annotation.Before;
7+
import org.hibernate.Session;
8+
import org.springframework.stereotype.Component;
9+
import hawk.service.UserService;
10+
11+
@Aspect
12+
@Component
13+
public class UserServiceAspect {
14+
@Before("execution(* hawk.service.UserService.*(..))&& target(userService) ")
15+
public void aroundExecution(JoinPoint pjp, UserService userService) throws Throwable {
16+
org.hibernate.Filter filter = userService.entityManager.unwrap(Session.class).enableFilter("tenantFilter");
17+
filter.setParameter("tenantId", TenantContext.getCurrentTenant());
18+
filter.validate();
19+
}
20+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package hawk.context;
2+
3+
public class TenantContext {
4+
private static ThreadLocal<String> currentTenant = new InheritableThreadLocal<>();
5+
6+
public static String getCurrentTenant() {
7+
return currentTenant.get();
8+
}
9+
10+
public static void setCurrentTenant(String tenant) {
11+
currentTenant.set(tenant);
12+
}
13+
14+
public static void clear() {
15+
currentTenant.set(null);
16+
}
17+
}

src/main/java/hawk/controller/AdminController.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
package hawk.controller;
22

3-
import hawk.entity.Item;
3+
import hawk.entity.User;
44
import hawk.form.Search;
5-
import hawk.service.SearchService;
6-
import hawk.service.UserService;
5+
import hawk.service.UserSearchService;
76
import org.springframework.beans.factory.annotation.Autowired;
87
import org.springframework.stereotype.Controller;
98
import org.springframework.ui.Model;
@@ -16,7 +15,7 @@
1615
@Controller
1716
public class AdminController {
1817
@Autowired
19-
UserService userService;
18+
UserSearchService userSearchService;
2019

2120
@GetMapping("/admin")
2221
public String index(Model model) {
@@ -45,7 +44,7 @@ public String searchForm(Model model) {
4544

4645
@PostMapping( "/admin/search")
4746
public String searchSubmit(@ModelAttribute Search search, Model model) {
48-
List<Item> users = userService.search(search);
47+
List<User> users = userSearchService.search(search);
4948
model.addAttribute("users", users);
5049
model.addAttribute("search", search);
5150
model.addAttribute("title", "User Search");

0 commit comments

Comments
 (0)