Skip to content

Commit 8273198

Browse files
committed
#1105 Add integration tests
1 parent 02fea89 commit 8273198

File tree

24 files changed

+835
-66
lines changed

24 files changed

+835
-66
lines changed

BUILDING

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ Build Instructions for NACOS
3535
Execute the following command in order to build the tar.gz packages and install JAR into local repository:
3636

3737
#build nacos
38-
$ mvn -Prelease-nacos -DskipTests clean install -U
38+
$ mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U

api/src/main/java/com/alibaba/nacos/api/common/Constants.java

+2
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ public class Constants {
7676

7777
public static final String TOKEN_TTL = "tokenTtl";
7878

79+
public static final String GLOBAL_ADMIN = "globalAdmin";
80+
7981
public static final String TOKEN_REFRESH_WINDOW = "tokenRefreshWindow";
8082

8183
/**

config/src/main/resources/META-INF/nacos-db.sql

+8-1
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ CREATE TABLE roles (
189189
role varchar(50) NOT NULL
190190
);
191191

192+
CREATE TABLE permissions (
193+
role varchar(50) NOT NULL,
194+
resource varchar(512) NOT NULL,
195+
action varchar(8) NOT NULL,
196+
constraint uk_role_permission UNIQUE (role,resource,action)
197+
);
198+
192199
INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
193200

194-
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');
201+
INSERT INTO roles (username, role) VALUES ('nacos', 'GLOBAL_ADMIN');

config/src/main/resources/META-INF/schema.sql

+8-1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,13 @@ CREATE TABLE roles (
184184
role varchar(50) NOT NULL
185185
);
186186

187+
CREATE TABLE permissions (
188+
role varchar(50) NOT NULL,
189+
resource varchar(512) NOT NULL,
190+
action varchar(8) NOT NULL,
191+
constraint uk_role_permission UNIQUE (role,resource,action)
192+
);
193+
187194
INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
188195

189-
INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');
196+
INSERT INTO roles (username, role) VALUES ('nacos', 'GLOBAL_ADMIN');

console/src/main/java/com/alibaba/nacos/console/controller/UserController.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public class UserController {
7676
@PostMapping
7777
public Object createUser(@RequestParam String username, @RequestParam String password) {
7878

79-
User user = userDetailsService.getUser(username);
79+
User user = userDetailsService.getUserFromDatabase(username);
8080
if (user != null) {
8181
throw new IllegalArgumentException("user '" + username + "' already exist!");
8282
}
@@ -112,7 +112,7 @@ public Object deleteUser(@RequestParam String username) {
112112
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.WRITE)
113113
public Object updateUser(@RequestParam String username, @RequestParam String newPassword) {
114114

115-
User user = userDetailsService.getUser(username);
115+
User user = userDetailsService.getUserFromDatabase(username);
116116
if (user == null) {
117117
throw new IllegalArgumentException("user " + username + " not exist!");
118118
}
@@ -162,6 +162,7 @@ public Object login(@RequestParam String username, @RequestParam String password
162162
JSONObject result = new JSONObject();
163163
result.put(Constants.ACCESS_TOKEN, user.getToken());
164164
result.put(Constants.TOKEN_TTL, authConfigs.getTokenValidityInSeconds());
165+
result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin());
165166
return result;
166167
}
167168

@@ -196,8 +197,8 @@ public RestResult<String> updatePassword(@RequestParam(value = "oldPassword") St
196197
RestResult<String> rr = new RestResult<String>();
197198
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
198199
String username = ((UserDetails) principal).getUsername();
199-
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
200-
String password = userDetails.getPassword();
200+
User user = userDetailsService.getUserFromDatabase(username);
201+
String password = user.getPassword();
201202

202203
// TODO: throw out more fine grained exceptions
203204
try {

console/src/main/java/com/alibaba/nacos/console/exception/ConsoleExceptionHandler.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package com.alibaba.nacos.console.exception;
1717

1818
import com.alibaba.nacos.core.auth.AccessException;
19+
import org.slf4j.Logger;
20+
import org.slf4j.LoggerFactory;
1921
import org.springframework.http.HttpStatus;
2022
import org.springframework.http.ResponseEntity;
2123
import org.springframework.web.bind.annotation.ControllerAdvice;
@@ -30,14 +32,21 @@
3032
@ControllerAdvice
3133
public class ConsoleExceptionHandler {
3234

35+
private static final Logger logger = LoggerFactory.getLogger(ConsoleExceptionHandler.class);
36+
3337
@ExceptionHandler(AccessException.class)
3438
private ResponseEntity<String> handleAccessException(AccessException e) {
35-
3639
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getErrMsg());
3740
}
3841

3942
@ExceptionHandler(IllegalArgumentException.class)
4043
private ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException e) {
4144
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.toString());
4245
}
46+
47+
@ExceptionHandler(Exception.class)
48+
private ResponseEntity<String> handleException(Exception e) {
49+
logger.error("CONSOLE", e);
50+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.toString());
51+
}
4352
}

console/src/main/java/com/alibaba/nacos/console/security/nacos/NacosAuthManager.java

+11-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package com.alibaba.nacos.console.security.nacos;
1717

1818
import com.alibaba.nacos.api.common.Constants;
19+
import com.alibaba.nacos.config.server.auth.RoleInfo;
1920
import com.alibaba.nacos.console.security.nacos.roles.NacosRoleServiceImpl;
2021
import com.alibaba.nacos.console.security.nacos.users.NacosUser;
2122
import com.alibaba.nacos.core.auth.AccessException;
@@ -34,6 +35,7 @@
3435
import org.springframework.stereotype.Component;
3536

3637
import javax.servlet.http.HttpServletRequest;
38+
import java.util.List;
3739

3840
/**
3941
* Builtin access control entry of Nacos
@@ -74,10 +76,17 @@ public User login(Object request) throws AccessException {
7476
Authentication authentication = tokenManager.getAuthentication(token);
7577
SecurityContextHolder.getContext().setAuthentication(authentication);
7678

77-
String userId = authentication.getName();
79+
String username = authentication.getName();
7880
NacosUser user = new NacosUser();
79-
user.setUserName(userId);
81+
user.setUserName(username);
8082
user.setToken(token);
83+
List<RoleInfo> roleInfoList = roleService.getRoles(username);
84+
for (RoleInfo roleInfo : roleInfoList) {
85+
if (roleInfo.getRole().equals(NacosRoleServiceImpl.GLOBAL_ADMIN_ROLE)) {
86+
user.setGlobalAdmin(true);
87+
break;
88+
}
89+
}
8190
return user;
8291
}
8392

console/src/main/java/com/alibaba/nacos/console/security/nacos/roles/NacosRoleServiceImpl.java

+37-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.alibaba.nacos.config.server.model.Page;
2424
import com.alibaba.nacos.console.security.nacos.NacosAuthConfig;
2525
import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl;
26+
import com.alibaba.nacos.core.auth.AuthConfigs;
2627
import com.alibaba.nacos.core.auth.Permission;
2728
import com.alibaba.nacos.core.utils.Loggers;
2829
import io.jsonwebtoken.lang.Collections;
@@ -44,7 +45,10 @@
4445
@Service
4546
public class NacosRoleServiceImpl {
4647

47-
private static final String GLOBAL_ADMIN_ROLE = "GLOBAL_ADMIN";
48+
public static final String GLOBAL_ADMIN_ROLE = "GLOBAL_ADMIN";
49+
50+
@Autowired
51+
private AuthConfigs authConfigs;
4852

4953
@Autowired
5054
private RolePersistService rolePersistService;
@@ -95,13 +99,13 @@ private void reload() {
9599
* Note if the user has many roles, this method returns true if any one role of the user has the
96100
* desired permission.
97101
*
98-
* @param username user info
102+
* @param username user info
99103
* @param permission permission to auth
100104
* @return true if granted, false otherwise
101105
*/
102106
public boolean hasPermission(String username, Permission permission) {
103107

104-
List<RoleInfo> roleInfoList = roleInfoMap.get(username);
108+
List<RoleInfo> roleInfoList = getRoles(username);
105109
if (Collections.isEmpty(roleInfoList)) {
106110
return false;
107111
}
@@ -120,7 +124,7 @@ public boolean hasPermission(String username, Permission permission) {
120124

121125
// For other roles, use a pattern match to decide if pass or not.
122126
for (RoleInfo roleInfo : roleInfoList) {
123-
List<PermissionInfo> permissionInfoList = permissionInfoMap.get(roleInfo.getRole());
127+
List<PermissionInfo> permissionInfoList = getPermissions(roleInfo.getRole());
124128
if (Collections.isEmpty(permissionInfoList)) {
125129
continue;
126130
}
@@ -136,11 +140,36 @@ public boolean hasPermission(String username, Permission permission) {
136140
return false;
137141
}
138142

143+
public List<RoleInfo> getRoles(String username) {
144+
List<RoleInfo> roleInfoList = roleInfoMap.get(username);
145+
if (!authConfigs.isCachingEnabled()) {
146+
Page<RoleInfo> roleInfoPage = getRolesFromDatabase(username, 1, Integer.MAX_VALUE);
147+
if (roleInfoPage != null) {
148+
roleInfoList = roleInfoPage.getPageItems();
149+
}
150+
}
151+
return roleInfoList;
152+
}
153+
139154
public Page<RoleInfo> getRolesFromDatabase(String userName, int pageNo, int pageSize) {
140155
Page<RoleInfo> roles = rolePersistService.getRolesByUserName(userName, pageNo, pageSize);
156+
if (roles == null) {
157+
return new Page<>();
158+
}
141159
return roles;
142160
}
143161

162+
public List<PermissionInfo> getPermissions(String role) {
163+
List<PermissionInfo> permissionInfoList = permissionInfoMap.get(role);
164+
if (!authConfigs.isCachingEnabled()) {
165+
Page<PermissionInfo> permissionInfoPage = getPermissionsFromDatabase(role, 1, Integer.MAX_VALUE);
166+
if (permissionInfoPage != null) {
167+
permissionInfoList = permissionInfoPage.getPageItems();
168+
}
169+
}
170+
return permissionInfoList;
171+
}
172+
144173
public Page<PermissionInfo> getPermissionsByRoleFromDatabase(String role, int pageNo, int pageSize) {
145174
return permissionPersistService.getPermissions(role, pageNo, pageSize);
146175
}
@@ -157,11 +186,15 @@ public void deleteRole(String role, String userName) {
157186
}
158187

159188
public void deleteRole(String role) {
189+
160190
rolePersistService.deleteRole(role);
161191
}
162192

163193
public Page<PermissionInfo> getPermissionsFromDatabase(String role, int pageNo, int pageSize) {
164194
Page<PermissionInfo> pageInfo = permissionPersistService.getPermissions(role, pageNo, pageSize);
195+
if (pageInfo == null) {
196+
return new Page<>();
197+
}
165198
return pageInfo;
166199
}
167200

console/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUser.java

+10
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public class NacosUser extends User {
2727

2828
private String token;
2929

30+
private boolean globalAdmin = false;
31+
3032
public String getToken() {
3133
return token;
3234
}
@@ -35,6 +37,14 @@ public void setToken(String token) {
3537
this.token = token;
3638
}
3739

40+
public boolean isGlobalAdmin() {
41+
return globalAdmin;
42+
}
43+
44+
public void setGlobalAdmin(boolean globalAdmin) {
45+
this.globalAdmin = globalAdmin;
46+
}
47+
3848
@Override
3949
public String toString() {
4050
return JSON.toJSONString(this);

console/src/main/java/com/alibaba/nacos/console/security/nacos/users/NacosUserDetailsServiceImpl.java

+17-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.alibaba.nacos.config.server.auth.UserPersistService;
2020
import com.alibaba.nacos.config.server.model.Page;
2121
import com.alibaba.nacos.config.server.model.User;
22+
import com.alibaba.nacos.core.auth.AuthConfigs;
2223
import com.alibaba.nacos.core.utils.Loggers;
2324
import org.springframework.beans.factory.annotation.Autowired;
2425
import org.springframework.scheduling.annotation.Scheduled;
@@ -44,6 +45,9 @@ public class NacosUserDetailsServiceImpl implements UserDetailsService {
4445
@Autowired
4546
private UserPersistService userPersistService;
4647

48+
@Autowired
49+
private AuthConfigs authConfigs;
50+
4751
@Scheduled(initialDelay = 5000, fixedDelay = 15000)
4852
private void reload() {
4953
try {
@@ -66,6 +70,10 @@ private void reload() {
6670
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
6771

6872
User user = userMap.get(username);
73+
if (!authConfigs.isCachingEnabled()) {
74+
user = userPersistService.findUserByUsername(username);
75+
}
76+
6977
if (user == null) {
7078
throw new UsernameNotFoundException(username);
7179
}
@@ -81,7 +89,15 @@ public Page<User> getUsersFromDatabase(int pageNo, int pageSize) {
8189
}
8290

8391
public User getUser(String username) {
84-
return userMap.get(username);
92+
User user = userMap.get(username);
93+
if (!authConfigs.isCachingEnabled()) {
94+
user = getUserFromDatabase(username);
95+
}
96+
return user;
97+
}
98+
99+
public User getUserFromDatabase(String username) {
100+
return userPersistService.findUserByUsername(username);
85101
}
86102

87103
public void createUser(String username, String password) {

core/src/main/java/com/alibaba/nacos/core/auth/AuthConfigs.java

+5
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ public boolean isAuthEnabled() {
7474
.getProperty("nacos.core.auth.enabled", "false"));
7575
}
7676

77+
public boolean isCachingEnabled() {
78+
return BooleanUtils.toBoolean(reloadableConfigs.getProperties()
79+
.getProperty("nacos.core.auth.caching.enabled", "true"));
80+
}
81+
7782
@Bean
7883
public FilterRegistrationBean authFilterRegistration() {
7984
FilterRegistrationBean<AuthFilter> registration = new FilterRegistrationBean<>();

core/src/main/java/com/alibaba/nacos/core/env/ReloadableConfigs.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,12 @@
3535
* @author nkorange
3636
* @since 1.2.0
3737
*/
38-
@ConditionalOnProperty(name = "spring.config.location", matchIfMissing = false)
3938
@Component
4039
public class ReloadableConfigs {
4140

4241
private Properties properties;
4342

44-
@Value("${spring.config.location}")
43+
@Value("${spring.config.location:}")
4544
private String path;
4645

4746
private static final String FILE_PREFIX = "file:";

distribution/conf/application.properties

+3
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ nacos.core.auth.default.token.expire.seconds=18000
104104
### The default token:
105105
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
106106

107+
### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay.
108+
nacos.core.auth.caching.enabled=true
109+
107110

108111
#*************** Istio Related Configurations ***************#
109112
### If turn on the MCP server:

naming/src/main/java/com/alibaba/nacos/naming/misc/HttpClient.java

+1-4
Original file line numberDiff line numberDiff line change
@@ -419,10 +419,7 @@ private static HttpResult getResult(HttpURLConnection conn) throws IOException {
419419
inputStream = new GZIPInputStream(inputStream);
420420
}
421421

422-
HttpResult result = new HttpResult(respCode, IoUtils.toString(inputStream, getCharset(conn)), respHeaders);
423-
inputStream.close();
424-
425-
return result;
422+
return new HttpResult(respCode, IoUtils.toString(inputStream, getCharset(conn)), respHeaders);
426423
}
427424

428425
private static String getCharset(HttpURLConnection conn) {

pom.xml

+11-6
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,11 @@
525525
<artifactId>nacos-example</artifactId>
526526
<version>${project.version}</version>
527527
</dependency>
528+
<dependency>
529+
<groupId>${project.groupId}</groupId>
530+
<artifactId>nacos-address</artifactId>
531+
<version>${project.version}</version>
532+
</dependency>
528533

529534
<dependency>
530535
<groupId>${project.groupId}</groupId>
@@ -539,12 +544,12 @@
539544
<version>1.2.58</version>
540545
</dependency>
541546

542-
<!-- javax libs-->
543-
<dependency>
544-
<groupId>javax.ws.rs</groupId>
545-
<artifactId>javax.ws.rs</artifactId>
546-
<version>2.1</version>
547-
</dependency>
547+
<!-- &lt;!&ndash; javax libs&ndash;&gt;-->
548+
<!-- <dependency>-->
549+
<!-- <groupId>javax.ws.rs</groupId>-->
550+
<!-- <artifactId>javax.ws.rs</artifactId>-->
551+
<!-- <version>1.0</version>-->
552+
<!-- </dependency>-->
548553

549554
<dependency>
550555
<groupId>javax.servlet</groupId>

0 commit comments

Comments
 (0)