#1105 Add auth test case for config

This commit is contained in:
nkorange 2020-01-14 18:01:00 +08:00
parent 29119d0956
commit 1fb1f5f3e3
17 changed files with 538 additions and 23 deletions

View File

@ -274,14 +274,14 @@ public class ServerHttpAgent implements HttpAgent {
} }
private void injectSecurityInfo(List<String> params) { private void injectSecurityInfo(List<String> params) {
ArrayList<String> list = (ArrayList) params; //ArrayList<String> list = (ArrayList) params;
if (StringUtils.isNotBlank(securityProxy.getAccessToken())) { if (StringUtils.isNotBlank(securityProxy.getAccessToken())) {
list.add(Constants.ACCESS_TOKEN); params.add(Constants.ACCESS_TOKEN);
list.add(securityProxy.getAccessToken()); params.add(securityProxy.getAccessToken());
} }
if (StringUtils.isNotBlank(namespaceId)) { if (StringUtils.isNotBlank(namespaceId)) {
list.add("tenant"); params.add("tenant");
list.add(namespaceId); params.add(namespaceId);
} }
} }

View File

@ -359,7 +359,10 @@ public class ClientWorker {
*/ */
List<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) throws IOException { List<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) throws IOException {
List<String> params = Arrays.asList(Constants.PROBE_MODIFY_REQUEST, probeUpdateString);
List<String> params = new ArrayList<String>(2);
params.add(Constants.PROBE_MODIFY_REQUEST);
params.add(probeUpdateString);
List<String> headers = new ArrayList<String>(2); List<String> headers = new ArrayList<String>(2);
headers.add("Long-Pulling-Timeout"); headers.add("Long-Pulling-Timeout");
@ -516,6 +519,7 @@ public class ClientWorker {
// check server config // check server config
List<String> changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList); List<String> changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList);
LOGGER.info("get changedGroupKeys:" + changedGroupKeys);
for (String groupKey : changedGroupKeys) { for (String groupKey : changedGroupKeys) {
String[] key = GroupKey.parseKey(groupKey); String[] key = GroupKey.parseKey(groupKey);

View File

@ -282,6 +282,8 @@ public class ConfigController {
throw new IllegalArgumentException("invalid probeModify"); throw new IllegalArgumentException("invalid probeModify");
} }
log.info("listen config id:" + probeModify);
probeModify = URLDecoder.decode(probeModify, Constants.ENCODE); probeModify = URLDecoder.decode(probeModify, Constants.ENCODE);
Map<String, String> clientMd5Map; Map<String, String> clientMd5Map;
@ -291,6 +293,8 @@ public class ConfigController {
throw new IllegalArgumentException("invalid probeModify"); throw new IllegalArgumentException("invalid probeModify");
} }
log.info("listen config id 2:" + probeModify);
// do long-polling // do long-polling
inner.doPollingConfig(request, response, clientMd5Map, probeModify.length()); inner.doPollingConfig(request, response, clientMd5Map, probeModify.length());
} }
@ -376,7 +380,7 @@ public class ConfigController {
} }
@DeleteMapping(params = "beta=true") @DeleteMapping(params = "beta=true")
@Secured(action = ActionTypes.READ, parser = ConfigResourceParser.class) @Secured(action = ActionTypes.WRITE, parser = ConfigResourceParser.class)
public RestResult<Boolean> stopBeta(@RequestParam(value = "dataId") String dataId, public RestResult<Boolean> stopBeta(@RequestParam(value = "dataId") String dataId,
@RequestParam(value = "group") String group, @RequestParam(value = "group") String group,
@RequestParam(value = "tenant", required = false, @RequestParam(value = "tenant", required = false,
@ -545,6 +549,7 @@ public class ConfigController {
} }
@PostMapping(params = "clone=true") @PostMapping(params = "clone=true")
@Secured(action = ActionTypes.WRITE, parser = ConfigResourceParser.class)
public RestResult<Map<String, Object>> cloneConfig(HttpServletRequest request, public RestResult<Map<String, Object>> cloneConfig(HttpServletRequest request,
@RequestParam(value = "src_user", required = false) String srcUser, @RequestParam(value = "src_user", required = false) String srcUser,
@RequestParam(value = "tenant", required = true) String namespace, @RequestParam(value = "tenant", required = true) String namespace,

View File

@ -24,6 +24,7 @@ import com.alibaba.nacos.config.server.service.LongPollingService;
import com.alibaba.nacos.config.server.service.PersistService; import com.alibaba.nacos.config.server.service.PersistService;
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService; import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
import com.alibaba.nacos.config.server.utils.*; import com.alibaba.nacos.config.server.utils.*;
import com.alibaba.nacos.core.utils.Loggers;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -98,6 +99,8 @@ public class ConfigServletInner {
request.setAttribute("content", newResult); request.setAttribute("content", newResult);
} }
Loggers.AUTH.info("new content:" + newResult);
// 禁用缓存 // 禁用缓存
response.setHeader("Pragma", "no-cache"); response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0); response.setDateHeader("Expires", 0);

View File

@ -186,7 +186,8 @@ CREATE TABLE users (
CREATE TABLE roles ( CREATE TABLE roles (
username varchar(50) NOT NULL, username varchar(50) NOT NULL,
role varchar(50) NOT NULL role varchar(50) NOT NULL,
constraint uk_username_role UNIQUE (username,role)
); );
CREATE TABLE permissions ( CREATE TABLE permissions (

View File

@ -181,7 +181,8 @@ CREATE TABLE users (
CREATE TABLE roles ( CREATE TABLE roles (
username varchar(50) NOT NULL, username varchar(50) NOT NULL,
role varchar(50) NOT NULL role varchar(50) NOT NULL,
constraint uk_username_role UNIQUE (username,role)
); );
CREATE TABLE permissions ( CREATE TABLE permissions (

View File

@ -51,7 +51,7 @@ public class HealthController {
* @return HTTP code equal to 200 indicates that Nacos is in right states. HTTP code equal to 500 indicates that * @return HTTP code equal to 200 indicates that Nacos is in right states. HTTP code equal to 500 indicates that
* Nacos is in broken states. * Nacos is in broken states.
*/ */
@GetMapping("liveness") @GetMapping("/liveness")
public ResponseEntity liveness() { public ResponseEntity liveness() {
return ResponseEntity.ok().body("OK"); return ResponseEntity.ok().body("OK");
} }
@ -62,7 +62,7 @@ public class HealthController {
* @return HTTP code equal to 200 indicates that Nacos is ready. HTTP code equal to 500 indicates that Nacos is not * @return HTTP code equal to 200 indicates that Nacos is ready. HTTP code equal to 500 indicates that Nacos is not
* ready. * ready.
*/ */
@GetMapping("readiness") @GetMapping("/readiness")
public ResponseEntity readiness(HttpServletRequest request) { public ResponseEntity readiness(HttpServletRequest request) {
boolean isConfigReadiness = isConfigReadiness(); boolean isConfigReadiness = isConfigReadiness();
boolean isNamingReadiness = isNamingReadiness(request); boolean isNamingReadiness = isNamingReadiness(request);

View File

@ -34,7 +34,7 @@ import java.util.Map;
@RequestMapping("/v1/console/server") @RequestMapping("/v1/console/server")
public class ServerStateController { public class ServerStateController {
@GetMapping("state") @GetMapping("/state")
public ResponseEntity serverState() { public ResponseEntity serverState() {
Map<String,String> serverState = new HashMap<>(3); Map<String,String> serverState = new HashMap<>(3);
serverState.put("standalone_mode",SystemUtils.STANDALONE_MODE ? serverState.put("standalone_mode",SystemUtils.STANDALONE_MODE ?

View File

@ -28,6 +28,7 @@ import com.alibaba.nacos.core.auth.Permission;
import com.alibaba.nacos.core.utils.Loggers; import com.alibaba.nacos.core.utils.Loggers;
import io.jsonwebtoken.lang.Collections; import io.jsonwebtoken.lang.Collections;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.mina.util.ConcurrentHashSet;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -59,6 +60,8 @@ public class NacosRoleServiceImpl {
@Autowired @Autowired
private PermissionPersistService permissionPersistService; private PermissionPersistService permissionPersistService;
private Set<String> roleSet = new ConcurrentHashSet<>();
private Map<String, List<RoleInfo>> roleInfoMap = new ConcurrentHashMap<>(); private Map<String, List<RoleInfo>> roleInfoMap = new ConcurrentHashMap<>();
private Map<String, List<PermissionInfo>> permissionInfoMap = new ConcurrentHashMap<>(); private Map<String, List<PermissionInfo>> permissionInfoMap = new ConcurrentHashMap<>();
@ -70,22 +73,23 @@ public class NacosRoleServiceImpl {
if (roleInfoPage == null) { if (roleInfoPage == null) {
return; return;
} }
Set<String> roleSet = new HashSet<>(16); Set<String> tmpRoleSet = new HashSet<>(16);
Map<String, List<RoleInfo>> tmpRoleInfoMap = new ConcurrentHashMap<>(16); Map<String, List<RoleInfo>> tmpRoleInfoMap = new ConcurrentHashMap<>(16);
for (RoleInfo roleInfo : roleInfoPage.getPageItems()) { for (RoleInfo roleInfo : roleInfoPage.getPageItems()) {
if (!tmpRoleInfoMap.containsKey(roleInfo.getUsername())) { if (!tmpRoleInfoMap.containsKey(roleInfo.getUsername())) {
tmpRoleInfoMap.put(roleInfo.getUsername(), new ArrayList<>()); tmpRoleInfoMap.put(roleInfo.getUsername(), new ArrayList<>());
} }
tmpRoleInfoMap.get(roleInfo.getUsername()).add(roleInfo); tmpRoleInfoMap.get(roleInfo.getUsername()).add(roleInfo);
roleSet.add(roleInfo.getRole()); tmpRoleSet.add(roleInfo.getRole());
} }
Map<String, List<PermissionInfo>> tmpPermissionInfoMap = new ConcurrentHashMap<>(16); Map<String, List<PermissionInfo>> tmpPermissionInfoMap = new ConcurrentHashMap<>(16);
for (String role : roleSet) { for (String role : tmpRoleSet) {
Page<PermissionInfo> permissionInfoPage = permissionPersistService.getPermissions(role, 1, Integer.MAX_VALUE); Page<PermissionInfo> permissionInfoPage = permissionPersistService.getPermissions(role, 1, Integer.MAX_VALUE);
tmpPermissionInfoMap.put(role, permissionInfoPage.getPageItems()); tmpPermissionInfoMap.put(role, permissionInfoPage.getPageItems());
} }
roleSet = tmpRoleSet;
roleInfoMap = tmpRoleInfoMap; roleInfoMap = tmpRoleInfoMap;
permissionInfoMap = tmpPermissionInfoMap; permissionInfoMap = tmpPermissionInfoMap;
} catch (Exception e) { } catch (Exception e) {
@ -178,6 +182,9 @@ public class NacosRoleServiceImpl {
if (userDetailsService.getUser(username) == null) { if (userDetailsService.getUser(username) == null) {
throw new IllegalArgumentException("user '" + username + "' not found!"); throw new IllegalArgumentException("user '" + username + "' not found!");
} }
if (GLOBAL_ADMIN_ROLE.equals(role)) {
throw new IllegalArgumentException("role '" + GLOBAL_ADMIN_ROLE + "' is not permitted to create!");
}
rolePersistService.addRole(role, username); rolePersistService.addRole(role, username);
} }
@ -199,6 +206,9 @@ public class NacosRoleServiceImpl {
} }
public void addPermission(String role, String resource, String action) { public void addPermission(String role, String resource, String action) {
if (!roleSet.contains(role)) {
throw new IllegalArgumentException("role " + role + " not found!");
}
permissionPersistService.addPermission(role, resource, action); permissionPersistService.addPermission(role, resource, action);
} }

View File

@ -35,3 +35,6 @@ nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/
nacos.core.auth.system.type=nacos nacos.core.auth.system.type=nacos
nacos.core.auth.enabled=false nacos.core.auth.enabled=false
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789 nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
tldSkipPatterns=derbyLocale_*.jar,jaxb-api.jar,jsr173_1.0_api.jar,jaxb1-impl.jar,activation.jar

View File

@ -67,7 +67,7 @@ public class AuthFilter implements Filter {
} }
if (Loggers.AUTH.isDebugEnabled()) { if (Loggers.AUTH.isDebugEnabled()) {
Loggers.AUTH.debug("auth filter start, request: {}", req.getRequestURI()); Loggers.AUTH.debug("auth filter start, request: {} {}", req.getMethod(), req.getRequestURI());
} }
try { try {
@ -76,7 +76,8 @@ public class AuthFilter implements Filter {
Method method = methodsCache.getMethod(req.getMethod(), path); Method method = methodsCache.getMethod(req.getMethod(), path);
if (method == null) { if (method == null) {
throw new NoSuchMethodException(); chain.doFilter(request, response);
return;
} }
if (method.isAnnotationPresent(Secured.class) && authConfigs.isAuthEnabled()) { if (method.isAnnotationPresent(Secured.class) && authConfigs.isAuthEnabled()) {
@ -95,17 +96,20 @@ public class AuthFilter implements Filter {
throw new AccessException("resource name invalid!"); throw new AccessException("resource name invalid!");
} }
if (Loggers.AUTH.isDebugEnabled()) {
Loggers.AUTH.debug("auth now, request: {} {}", req.getMethod(), req.getRequestURI());
}
authManager.auth(new Permission(resource, action), authManager.login(req)); authManager.auth(new Permission(resource, action), authManager.login(req));
} }
} catch (AccessException e) { } catch (AccessException e) {
if (Loggers.AUTH.isDebugEnabled()) {
Loggers.AUTH.debug("access denied, request: {} {}", req.getMethod(), req.getRequestURI());
}
resp.sendError(HttpServletResponse.SC_FORBIDDEN, e.getErrMsg()); resp.sendError(HttpServletResponse.SC_FORBIDDEN, e.getErrMsg());
return; return;
} catch (NoSuchMethodException e) {
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED,
"no such api:" + req.getMethod() + ":" + req.getRequestURI());
return;
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ExceptionUtil.getAllExceptionMsg(e)); resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ExceptionUtil.getAllExceptionMsg(e));
return; return;

View File

@ -15,6 +15,8 @@
*/ */
package com.alibaba.nacos.core.auth; package com.alibaba.nacos.core.auth;
import com.alibaba.fastjson.JSON;
/** /**
* Permission to auth * Permission to auth
* *
@ -57,4 +59,9 @@ public class Permission {
public void setAction(String action) { public void setAction(String action) {
this.action = action; this.action = action;
} }
@Override
public String toString() {
return JSON.toJSONString(this);
}
} }

View File

@ -206,6 +206,7 @@
<descriptors> <descriptors>
<descriptor>release-nacos.xml</descriptor> <descriptor>release-nacos.xml</descriptor>
</descriptors> </descriptors>
<tarLongFileMode>posix</tarLongFileMode>
</configuration> </configuration>
<executions> <executions>
<execution> <execution>

View File

@ -0,0 +1,28 @@
package com.alibaba.nacos.test.core.auth;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.test.base.HttpClient4Test;
import com.alibaba.nacos.test.base.Params;
import org.junit.Assert;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
public class AuthBase extends HttpClient4Test {
public String login() {
ResponseEntity<String> response = request("/nacos/v1/auth/users/login",
Params.newParams()
.appendParam("username", "nacos")
.appendParam("password", "nacos")
.done(),
String.class,
HttpMethod.POST);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
JSONObject json = JSON.parseObject(response.getBody());
Assert.assertTrue(json.containsKey("accessToken"));
return json.getString("accessToken");
}
}

View File

@ -0,0 +1,271 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.test.core.auth;
import com.alibaba.nacos.Nacos;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigChangeEvent;
import com.alibaba.nacos.api.config.ConfigChangeItem;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.PropertyChangeType;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.http.HttpAgent;
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
import com.alibaba.nacos.test.base.Params;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import java.net.URL;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.fail;
/**
* @author nkorange
* @since 1.2.0
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos", "server.port=7001"},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ConfigAuth_ITCase extends AuthBase {
@LocalServerPort
private int port;
private String accessToken;
public static final long TIME_OUT = 2000;
public ConfigService iconfig = null;
private String dataId = "yanlin";
private String group = "yanlin";
private String username = "username1";
private String password = "password1";
private String role = "role1";
private Properties properties;
private String namespace1 = "namespace1";
private String namespace2 = "namespace2";
@Before
public void init() throws Exception {
TimeUnit.SECONDS.sleep(5L);
String url = String.format("http://localhost:%d/", port);
this.base = new URL(url);
accessToken = login();
// Create a user:
ResponseEntity<String> response = request("/nacos/v1/auth/users",
Params.newParams()
.appendParam("username", username)
.appendParam("password", password)
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.POST);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
// Create a role:
response = request("/nacos/v1/auth/roles",
Params.newParams()
.appendParam("role", role)
.appendParam("username", username)
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.POST);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
// Add read permission for namespace1:
response = request("/nacos/v1/auth/permissions",
Params.newParams()
.appendParam("role", role)
.appendParam("resource", namespace1 + ":*:*")
.appendParam("action", "r")
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.POST);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
// Add read/write permission for namespace2:
response = request("/nacos/v1/auth/permissions",
Params.newParams()
.appendParam("role", role)
.appendParam("resource", namespace2 + ":*:*")
.appendParam("action", "rw")
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.POST);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
// Init properties:
properties = new Properties();
properties.put(PropertyKeyConst.USERNAME, username);
properties.put(PropertyKeyConst.PASSWORD, password);
properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1" + ":" + port);
}
@After
public void destroy() {
// Delete permission:
ResponseEntity<String> response = request("/nacos/v1/auth/permissions",
Params.newParams()
.appendParam("role", role)
.appendParam("resource", namespace1 + ":*:*")
.appendParam("action", "r")
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.DELETE);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
// Delete permission:
response = request("/nacos/v1/auth/permissions",
Params.newParams()
.appendParam("role", role)
.appendParam("resource", namespace2 + ":*:*")
.appendParam("action", "rw")
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.DELETE);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
// Delete a role:
response = request("/nacos/v1/auth/roles",
Params.newParams()
.appendParam("role", role)
.appendParam("username", username)
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.DELETE);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
// Delete a user:
response = request("/nacos/v1/auth/users",
Params.newParams()
.appendParam("username", username)
.appendParam("password", password)
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.DELETE);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
}
@Test
public void publishConfigWithReadPermission() throws Exception {
properties.put(PropertyKeyConst.NAMESPACE, namespace1);
// Construct configService:
iconfig = NacosFactory.createConfigService(properties);
final String content = "test";
try {
iconfig.publishConfig(dataId, group, content);
fail();
} catch (NacosException ne) {
Assert.assertEquals(HttpStatus.FORBIDDEN.value(), ne.getErrCode());
}
}
@Test
public void publishConfigWithReadWritePermission() throws Exception {
properties.put(PropertyKeyConst.NAMESPACE, namespace2);
// Construct configService:
iconfig = NacosFactory.createConfigService(properties);
final String content = "test";
boolean result = iconfig.publishConfig(dataId, group, content);
Assert.assertTrue(result);
TimeUnit.SECONDS.sleep(2L);
String value = iconfig.getConfig(dataId, group, TIME_OUT);
Assert.assertEquals(content, value);
result = iconfig.removeConfig(dataId, group);
Thread.sleep(TIME_OUT);
Assert.assertTrue(result);
TimeUnit.SECONDS.sleep(2L);
value = iconfig.getConfig(dataId, group, TIME_OUT);
System.out.println(value);
Assert.assertNull(value);
}
@Test
public void listenConfigWithReadWritePermission() throws Exception {
CountDownLatch latch = new CountDownLatch(1);
final String dataId = "test" + System.currentTimeMillis();
final String group = "DEFAULT_GROUP";
final String content = "config data";
properties.put(PropertyKeyConst.NAMESPACE, namespace2);
// Construct configService:
iconfig = NacosFactory.createConfigService(properties);
iconfig.addListener(dataId, group, new AbstractConfigChangeListener() {
@Override
public void receiveConfigChange(ConfigChangeEvent event) {
ConfigChangeItem cci = event.getChangeItem("content");
Assert.assertEquals(null, cci.getOldValue());
Assert.assertEquals(content, cci.getNewValue());
Assert.assertEquals(PropertyChangeType.ADDED, cci.getType());
System.out.println(cci);
latch.countDown();
}
});
iconfig.publishConfig(dataId, group, content);
latch.await();
}
}

View File

@ -0,0 +1,177 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.nacos.test.core.auth;
import com.alibaba.nacos.Nacos;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.test.base.Params;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Properties;
/**
* @author nkorange
* @since 1.2.0
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos", "server.port=7001"},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class NamingAuth_ITCase extends AuthBase {
@LocalServerPort
private int port;
private String accessToken;
private String username = "username1";
private String password = "password1";
private String role = "role1";
private Properties properties;
private String namespace1 = "namespace1";
private String namespace2 = "namespace2";
@Before
public void init() {
accessToken = login();
// Create a user:
ResponseEntity<String> response = request("/nacos/v1/auth/users",
Params.newParams()
.appendParam("username", username)
.appendParam("password", password)
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.POST);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
// Create a role:
response = request("/nacos/v1/auth/roles",
Params.newParams()
.appendParam("role", role)
.appendParam("username", username)
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.POST);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
// Add read permission for namespace1:
response = request("/nacos/v1/auth/permissions",
Params.newParams()
.appendParam("role", role)
.appendParam("resource", namespace1 + ":*:*")
.appendParam("action", "r")
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.POST);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
// Add read/write permission for namespace2:
response = request("/nacos/v1/auth/permissions",
Params.newParams()
.appendParam("role", role)
.appendParam("resource", namespace2 + ":*:*")
.appendParam("action", "rw")
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.POST);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
// Init properties:
properties = new Properties();
properties.put(PropertyKeyConst.USERNAME, username);
properties.put(PropertyKeyConst.PASSWORD, password);
properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1" + ":" + port);
}
@After
public void destroy() {
// Delete permission:
ResponseEntity<String> response = request("/nacos/v1/auth/permissions",
Params.newParams()
.appendParam("role", role)
.appendParam("resource", namespace1 + ":*:*")
.appendParam("action", "r")
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.DELETE);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
// Delete permission:
response = request("/nacos/v1/auth/permissions",
Params.newParams()
.appendParam("role", role)
.appendParam("resource", namespace2 + ":*:*")
.appendParam("action", "rw")
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.DELETE);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
// Delete a role:
response = request("/nacos/v1/auth/roles",
Params.newParams()
.appendParam("role", role)
.appendParam("username", username)
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.DELETE);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
// Delete a user:
response = request("/nacos/v1/auth/users",
Params.newParams()
.appendParam("username", username)
.appendParam("password", password)
.appendParam("accessToken", accessToken)
.done(),
String.class,
HttpMethod.DELETE);
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
}
@Test
public void writeWithReadPermission() {
properties.put(PropertyKeyConst.NAMESPACE, namespace1);
}
}

View File

@ -14,7 +14,7 @@ management.metrics.export.influx.enabled=false
#management.metrics.export.influx.consistency=one #management.metrics.export.influx.consistency=one
#management.metrics.export.influx.compressed=true #management.metrics.export.influx.compressed=true
server.tomcat.accesslog.enabled=false server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D
# default current work dir # default current work dir
server.tomcat.basedir= server.tomcat.basedir=
@ -26,7 +26,7 @@ nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/
nacos.core.auth.system.type=nacos nacos.core.auth.system.type=nacos
### If turn on auth system: ### If turn on auth system:
nacos.core.auth.enabled=true nacos.core.auth.enabled=false
nacos.core.auth.caching.enabled=false nacos.core.auth.caching.enabled=false