diff --git a/CHANGELOG.md b/CHANGELOG.md
index abdf5e4fa..e34fcf316 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.7.18b
+BUG FIXES:
+* Cell Owner URL being persisted without #fragment info. ([#479](https://github.com/personium/personium-core/issues/479))
+
## 1.7.18a
BUG FIXES:
* 500 Error when Non-Cell URL (incl. Unit URL) is given in p_target param at TokenEndpoint. ([#475](https://github.com/personium/personium-core/issues/475))
diff --git a/pom.xml b/pom.xml
index ad1ac07ce..17bcad3d5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
io.personium
personium-core
war
- 1.7.18a
+ 1.7.18b
personium-core Maven Webapp
http://maven.apache.org
diff --git a/src/main/java/io/personium/core/utils/HttpClientFactory.java b/src/main/java/io/personium/core/utils/HttpClientFactory.java
index 600ef0371..b2910098b 100644
--- a/src/main/java/io/personium/core/utils/HttpClientFactory.java
+++ b/src/main/java/io/personium/core/utils/HttpClientFactory.java
@@ -16,6 +16,8 @@
*/
package io.personium.core.utils;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
@@ -25,6 +27,7 @@
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.DnsResolver;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
@@ -34,6 +37,7 @@
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
+import org.apache.http.impl.conn.SystemDefaultDnsResolver;
import org.apache.http.ssl.SSLContextBuilder;
/**
@@ -44,6 +48,8 @@ public class HttpClientFactory {
public static final String TYPE_DEFAULT = "default";
/** Type of HTTP communication.*/
public static final String TYPE_INSECURE = "insecure";
+ /** Type name of HTTP client that always connect to .*/
+ public static final String TYPE_ALWAYS_LOCAL = "alwayslocal";
/** Connection timeout value.*/
private static final int TIMEOUT = 60000; // 20000;
@@ -69,10 +75,50 @@ public static CloseableHttpClient create(final String type) {
.setDefaultRequestConfig(config)
.useSystemProperties()
.build();
- } else if (!TYPE_INSECURE.equalsIgnoreCase(type)) {
+ } else if (TYPE_INSECURE.equalsIgnoreCase(type)) {
+ return createInsecure(config);
+ } else if (TYPE_ALWAYS_LOCAL.equalsIgnoreCase(type)) {
+ return createAlwaysLocal(config);
+ }
+ return null;
+
+ }
+ private static CloseableHttpClient createAlwaysLocal(RequestConfig config) {
+ SSLConnectionSocketFactory sf = null;
+ try {
+ sf = createInsecureSSLConnectionSocketFactory();
+ } catch (Exception e) {
return null;
}
+ Registry registry = RegistryBuilder.create()
+ .register("https", sf)
+ .register("http", PlainConnectionSocketFactory.INSTANCE)
+ .build();
+ /* Custom DNS resolver */
+ DnsResolver dnsResolver = new SystemDefaultDnsResolver() {
+ @Override
+ public InetAddress[] resolve(final String host) throws UnknownHostException {
+ // Always 127.0.0.1
+ return new InetAddress[] { InetAddress.getByName("127.0.0.1") };
+ }
+ };
+ HttpClientConnectionManager cm = new BasicHttpClientConnectionManager(registry,
+ null, /* Default ConnectionFactory */
+ null, /* Default SchemePortResolver */
+ dnsResolver /* Our DnsResolver */
+ );
+
+
+ return HttpClientBuilder.create()
+ .setDefaultRequestConfig(config)
+ .setConnectionManager(cm)
+ .useSystemProperties()
+ .build();
+
+
+ }
+ private static CloseableHttpClient createInsecure(RequestConfig config) {
SSLConnectionSocketFactory sf = null;
try {
sf = createInsecureSSLConnectionSocketFactory();
@@ -91,6 +137,7 @@ public static CloseableHttpClient create(final String type) {
.setConnectionManager(cm)
.useSystemProperties()
.build();
+
}
private static SSLConnectionSocketFactory createInsecureSSLConnectionSocketFactory()
diff --git a/src/main/java/io/personium/core/utils/UriUtils.java b/src/main/java/io/personium/core/utils/UriUtils.java
index d96a104a7..57f0c7a7e 100644
--- a/src/main/java/io/personium/core/utils/UriUtils.java
+++ b/src/main/java/io/personium/core/utils/UriUtils.java
@@ -237,6 +237,12 @@ public static String convertSchemeFromHttpToLocalUnit(String url) {
StringBuilder sb = new StringBuilder(SCHEME_LOCALUNIT);
sb.append(":").append(cellName).append(":");
sb.append(uri.getPath());
+ if (uri.getQuery() != null) {
+ sb.append("?").append(uri.getQuery());
+ }
+ if (uri.getFragment() != null) {
+ sb.append("#").append(uri.getFragment());
+ }
return sb.toString();
}
}
diff --git a/src/test/java/io/personium/core/utils/UriUtilsTest.java b/src/test/java/io/personium/core/utils/UriUtilsTest.java
index f92007653..c0d078f7f 100644
--- a/src/test/java/io/personium/core/utils/UriUtilsTest.java
+++ b/src/test/java/io/personium/core/utils/UriUtilsTest.java
@@ -143,6 +143,9 @@ public void convertSchemeFromHttpToLocalUnit_Normal_url_starts_with_uniturl() th
assertThat(
UriUtils.convertSchemeFromHttpToLocalUnit("https://unit.example/cell/"),
is("personium-localunit:/cell/"));
+ assertThat(
+ UriUtils.convertSchemeFromHttpToLocalUnit("https://unit.example/cell/#acct"),
+ is("personium-localunit:/cell/#acct"));
}
/**
@@ -161,6 +164,18 @@ public void convertSchemeFromHttpToLocalUnit_Normal_url_is_fqdn_base() throws Ex
assertThat(
UriUtils.convertSchemeFromHttpToLocalUnit("http://cell.unit.example/"),
is("personium-localunit:cell:/"));
+ assertThat(
+ UriUtils.convertSchemeFromHttpToLocalUnit("http://cell.unit.example/#account"),
+ is("personium-localunit:cell:/#account"));
+ assertThat(
+ UriUtils.convertSchemeFromHttpToLocalUnit("http://cell.unit.example/ab/?query=23"),
+ is("personium-localunit:cell:/ab/?query=23"));
+ assertThat(
+ UriUtils.convertSchemeFromHttpToLocalUnit("http://cell.unit.example/ab/?query=23#frag"),
+ is("personium-localunit:cell:/ab/?query=23#frag"));
+ assertThat(
+ UriUtils.convertSchemeFromHttpToLocalUnit("http://cell.unit.example/ab/#frag?query"),
+ is("personium-localunit:cell:/ab/#frag?query"));
}
/**
* Test convertSchemeFromHttpToLocalUnit().
diff --git a/src/test/java/io/personium/test/jersey/PersoniumTest.java b/src/test/java/io/personium/test/jersey/PersoniumTest.java
index b8824876d..10293e201 100644
--- a/src/test/java/io/personium/test/jersey/PersoniumTest.java
+++ b/src/test/java/io/personium/test/jersey/PersoniumTest.java
@@ -88,10 +88,9 @@ public void start() {
}
}
- @SuppressWarnings("deprecation")
@Override
public void stop() {
- this.server.stop();
+ this.server.shutdownNow();;
}
};
diff --git a/src/test/java/io/personium/test/jersey/cell/AllTests.java b/src/test/java/io/personium/test/jersey/cell/AllTests.java
index 74caaf6ee..446de0119 100644
--- a/src/test/java/io/personium/test/jersey/cell/AllTests.java
+++ b/src/test/java/io/personium/test/jersey/cell/AllTests.java
@@ -20,6 +20,8 @@
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
+import io.personium.test.jersey.unit.UnitUserCellTest;
+
/**
* パッケージ配下のテストケースを全て実行するためのテストスイート.
*/
diff --git a/src/test/java/io/personium/test/jersey/unit/PerCellSubdomainMode_UnitUserCellTest.java b/src/test/java/io/personium/test/jersey/unit/PerCellSubdomainMode_UnitUserCellTest.java
new file mode 100644
index 000000000..8516a481a
--- /dev/null
+++ b/src/test/java/io/personium/test/jersey/unit/PerCellSubdomainMode_UnitUserCellTest.java
@@ -0,0 +1,553 @@
+/**
+ * personium.io
+ * Copyright 2014 FUJITSU LIMITED
+ *
+ * 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 io.personium.test.jersey.unit;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+
+import org.apache.commons.io.Charsets;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.RequestBuilder;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.json.simple.JSONObject;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.net.HttpHeaders;
+
+import io.personium.common.auth.token.AbstractOAuth2Token.TokenDsigException;
+import io.personium.common.auth.token.AbstractOAuth2Token.TokenParseException;
+import io.personium.common.auth.token.AbstractOAuth2Token.TokenRootCrtException;
+import io.personium.common.auth.token.Role;
+import io.personium.common.auth.token.TransCellAccessToken;
+import io.personium.core.PersoniumUnitConfig;
+import io.personium.core.auth.AccessContext;
+import io.personium.core.auth.OAuth2Helper;
+import io.personium.core.model.Cell;
+import io.personium.core.model.ModelFactory;
+import io.personium.core.rs.PersoniumCoreApplication;
+import io.personium.core.utils.HttpClientFactory;
+import io.personium.core.utils.UriUtils;
+import io.personium.test.categories.Integration;
+import io.personium.test.categories.Regression;
+import io.personium.test.categories.Unit;
+import io.personium.test.jersey.AbstractCase;
+import io.personium.test.jersey.PersoniumIntegTestRunner;
+import io.personium.test.jersey.PersoniumTest;
+import io.personium.test.setup.Setup;
+import io.personium.test.unit.core.UrlUtils;
+import io.personium.test.utils.CellUtils;
+import io.personium.test.utils.DavResourceUtils;
+import io.personium.test.utils.Http;
+import io.personium.test.utils.TResponse;
+
+/**
+ * Test of UnitUser under the condition of Per Cell Subdomain Mode.
+ */
+@RunWith(PersoniumIntegTestRunner.class)
+@Category({Unit.class, Integration.class, Regression.class })
+public class PerCellSubdomainMode_UnitUserCellTest extends PersoniumTest {
+
+ private static Logger log = LoggerFactory.getLogger(PerCellSubdomainMode_UnitUserCellTest.class);
+
+ private static final String UNIT_USER_CELL = "unitusercell";
+ private static final String UNIT_USER_ACCOUNT = "UnitUserName";
+ private static final String UNIT_USER_ACCOUNT_PASS = "password";
+ private static final String CREATE_CELL = "createcell";
+
+ private static String unitAdminRole;
+ private static String contentsReaderRole;
+ private static String contentsAdminRole;
+
+ /** unitUser.issuers in properties. */
+ private static String issuersBackup = "";
+ private static String urlModeBackup = "";
+
+ private static String unitUserCellUrl;
+ private static String unitUserToken = null;
+
+ /**
+ * Constructor. テスト対象のパッケージをsuperに渡す必要がある
+ */
+ public PerCellSubdomainMode_UnitUserCellTest() {
+ super(new PersoniumCoreApplication());
+ }
+
+
+ private static void createUnitUserAccount() {
+ String accountODataUrl = unitUserCellUrl + "__ctl/Account";
+ try (CloseableHttpClient client = HttpClientFactory.create(HttpClientFactory.TYPE_ALWAYS_LOCAL)) {
+ HttpPost post = new HttpPost(accountODataUrl);
+ post.addHeader(HttpHeaders.AUTHORIZATION, AbstractCase.BEARER_MASTER_TOKEN);
+ post.addHeader(io.personium.common.utils.CommonUtils.HttpHeaders.X_PERSONIUM_CREDENTIAL,
+ UNIT_USER_ACCOUNT_PASS);
+ String jsonStr = Json.createObjectBuilder().add("Name", UNIT_USER_ACCOUNT).build().toString();
+ HttpEntity entity = new StringEntity(jsonStr);
+ post.setEntity(entity);
+ client.execute(post);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ private static void deleteUnitUserAccount() {
+ // Delete Unit User Account
+ String accountODataUrl = unitUserCellUrl + "__ctl/Account";
+ HttpDelete del = new HttpDelete(accountODataUrl + "(%27" + UNIT_USER_ACCOUNT + "%27)");
+ del.addHeader(HttpHeaders.AUTHORIZATION, AbstractCase.BEARER_MASTER_TOKEN);
+ try (CloseableHttpClient client = HttpClientFactory.create(HttpClientFactory.TYPE_ALWAYS_LOCAL)){
+ client.execute(del);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ private static String getUnitUserToken() {
+ String tokenEndpoint = unitUserCellUrl + "__token";
+ try (CloseableHttpClient client = HttpClientFactory.create(HttpClientFactory.TYPE_ALWAYS_LOCAL)) {
+ HttpPost post = new HttpPost(tokenEndpoint);
+ post.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.getMimeType());
+ post.setHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.getMimeType());
+ StringBuilder sb = new StringBuilder();
+ sb.append("grant_type=password&username=");
+ sb.append(UNIT_USER_ACCOUNT);
+ sb.append("&password=");
+ sb.append(UNIT_USER_ACCOUNT_PASS);
+ sb.append("&p_target=");
+ sb.append(UrlUtils.unitRoot());
+ HttpEntity entity = new StringEntity(sb.toString());
+ post.setEntity(entity);
+ try (CloseableHttpResponse res = client.execute(post)) {
+ assertEquals(200, res.getStatusLine().getStatusCode());
+ JsonObject jo = Json.createReader(new InputStreamReader(res.getEntity().getContent(), Charsets.UTF_8)).readObject();
+ return jo.getString(OAuth2Helper.Key.ACCESS_TOKEN);
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ private static void deleteUnitAdminRole() {
+ //RoleUtils.delete(UNIT_USER_CELL, AbstractCase.MASTER_TOKEN_NAME, unitAdminRole, null);
+ String roleODataUrl = unitUserCellUrl + "__ctl/Role(%27" + unitAdminRole + "%27)";
+ try (CloseableHttpClient client = HttpClientFactory.create(HttpClientFactory.TYPE_ALWAYS_LOCAL)) {
+ HttpDelete del = new HttpDelete(roleODataUrl);
+ del.addHeader(HttpHeaders.AUTHORIZATION, AbstractCase.BEARER_MASTER_TOKEN);
+ client.execute(del);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ private static void linkUuAccountAndUnitAdminRole() {
+ // LinksUtils.createLinks(UNIT_USER_CELL, Account.EDM_TYPE_NAME, UNIT_USER_ACCOUNT, null, Role.EDM_TYPE_NAME,
+ // unitAdminRole, null, AbstractCase.MASTER_TOKEN_NAME, HttpStatus.SC_NO_CONTENT);
+ String roleODataUrl = unitUserCellUrl + "__ctl/Role(Name=%27" + unitAdminRole + "%27)";
+ String accountRoleLinkUrl = unitUserCellUrl + "__ctl/Account(%27" + UNIT_USER_ACCOUNT + "%27)/$links/_Role";
+ try (CloseableHttpClient client = HttpClientFactory.create(HttpClientFactory.TYPE_ALWAYS_LOCAL)) {
+ HttpPost post = new HttpPost(accountRoleLinkUrl);
+ post.addHeader(HttpHeaders.AUTHORIZATION, AbstractCase.BEARER_MASTER_TOKEN);
+ String jsonStr = Json.createObjectBuilder()
+ .add("uri", roleODataUrl)
+ .build().toString();
+ HttpEntity entity = new StringEntity(jsonStr);
+ post.setEntity(entity);
+ client.execute(post);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ private static void createUnitAdminRole() {
+// RoleUtils.create(UNIT_USER_CELL, AbstractCase.MASTER_TOKEN_NAME, unitAdminRole,
+// null, HttpStatus.SC_CREATED);
+ String roleODataUrl = unitUserCellUrl + "__ctl/Role";
+ try (CloseableHttpClient client = HttpClientFactory.create(HttpClientFactory.TYPE_ALWAYS_LOCAL)) {
+ HttpPost post = new HttpPost(roleODataUrl);
+ post.addHeader(HttpHeaders.AUTHORIZATION, AbstractCase.BEARER_MASTER_TOKEN);
+ String jsonStr = Json.createObjectBuilder().add("Name", unitAdminRole).build().toString();
+ HttpEntity entity = new StringEntity(jsonStr);
+ post.setEntity(entity);
+ client.execute(post);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Before class.
+ * @throws Exception Unintended exception in test
+ */
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ // Override issuers in unitconfig.
+ urlModeBackup = PersoniumUnitConfig.get(PersoniumUnitConfig.PATH_BASED_CELL_URL_ENABLED);
+ PersoniumUnitConfig.set(PersoniumUnitConfig.PATH_BASED_CELL_URL_ENABLED,
+ "false");
+ issuersBackup = PersoniumUnitConfig.get(PersoniumUnitConfig.UNIT_USER_ISSUERS);
+ PersoniumUnitConfig.set(PersoniumUnitConfig.UNIT_USER_ISSUERS,
+ UriUtils.SCHEME_LOCALUNIT + ":" + UNIT_USER_CELL + ":/");
+
+ // Read role name from AccessContext
+ Field admin = AccessContext.class.getDeclaredField("ROLE_UNIT_ADMIN");
+ admin.setAccessible(true);
+ unitAdminRole = (String) admin.get(null);
+ Field contentsReader = AccessContext.class.getDeclaredField("ROLE_CELL_CONTENTS_READER");
+ contentsReader.setAccessible(true);
+ contentsReaderRole = (String) contentsReader.get(null);
+ Field contentsAdmin = AccessContext.class.getDeclaredField("ROLE_CELL_CONTENTS_ADMIN");
+ contentsAdmin.setAccessible(true);
+ contentsAdminRole = (String) contentsAdmin.get(null);
+
+
+ unitUserCellUrl = UriUtils.resolveLocalUnit("personium-localunit:" + UNIT_USER_CELL + ":/");
+
+ }
+
+
+ /**
+ * After class.
+ */
+ @AfterClass
+ public static void afterClass() {
+
+ // Restore issuers in unitconfig.
+ PersoniumUnitConfig.set(PersoniumUnitConfig.UNIT_USER_ISSUERS,
+ issuersBackup != null ? issuersBackup : ""); // CHECKSTYLE IGNORE
+ PersoniumUnitConfig.set(PersoniumUnitConfig.PATH_BASED_CELL_URL_ENABLED, urlModeBackup);
+ }
+
+ /**
+ * マスタートークンでX_PERSONIUM_UnitUserヘッダを指定すると指定したユニットユーザトークンになることを確認.
+ */
+ @Test
+ public void マスタートークンでX_PERSONIUM_UnitUserヘッダを指定すると指定したユニットユーザトークンになることを確認() {
+ // マスタートークンでX-Personium-UnitUserヘッダを指定すると指定した値のOwnerでセルが作成される。
+ CellUtils.create(CREATE_CELL, AbstractCase.MASTER_TOKEN_NAME, unitUserCellUrl, HttpStatus.SC_CREATED);
+
+ // ユニットユーザトークンを使えば取得可能なことを確認
+ CellUtils.get(CREATE_CELL, AbstractCase.MASTER_TOKEN_NAME, unitUserCellUrl, HttpStatus.SC_OK);
+
+ // オーナーが異なるユニットユーザトークン(マスタートークンのヘッダ指定での降格を利用)を使うと削除できないことを確認
+ CellUtils.delete(AbstractCase.MASTER_TOKEN_NAME, CREATE_CELL, Setup.OWNER_HMC, HttpStatus.SC_FORBIDDEN);
+
+ // オーナーが一致するユニットユーザトークン(マスタートークンのヘッダ指定での降格を利用)を使うと削除できることを確認
+ CellUtils.delete(AbstractCase.MASTER_TOKEN_NAME, CREATE_CELL, unitUserCellUrl,
+ HttpStatus.SC_NO_CONTENT);
+ }
+
+ /**
+ * ユニットユーザートークンでセル作成を行いオーナーが設定されることを確認.
+ * @throws TokenRootCrtException
+ * @throws TokenDsigException
+ * @throws TokenParseException
+ */
+ @Test
+ public void ユニットユーザートークンでセル作成を行いオーナーが設定されることを確認() throws TokenParseException, TokenDsigException, TokenRootCrtException {
+ try {
+ // 本テスト用 Unit User Cell の作成
+ CellUtils.create(UNIT_USER_CELL, AbstractCase.MASTER_TOKEN_NAME, -1);
+ // Create Account
+ createUnitUserAccount();
+ // retrieve a Unit User Token
+ unitUserToken = getUnitUserToken();
+
+ //
+ TransCellAccessToken tcToken = TransCellAccessToken.parse(unitUserToken);
+ String subject = tcToken.getSubject();
+ log.info("##TOKEN##");
+ log.info("Subject: "+ subject);
+ log.info("Issuer : "+ tcToken.getSubject());
+ log.info("Target : "+ tcToken.getTarget());
+ String localunitSubject = UriUtils.convertSchemeFromHttpToLocalUnit(subject);
+ log.info("Owner Should be : "+ localunitSubject);
+
+ // ユニットユーザートークンを使ってセル作成をする.
+ // オーナーがユニットユーザー(ここだとuserNameアカウントのURL)になるはず。
+ CellUtils.create(CREATE_CELL, unitUserToken, HttpStatus.SC_CREATED);
+
+ Cell cell = ModelFactory.cellFromName(CREATE_CELL);
+ String owner = cell.getOwnerRaw();
+ log.info(" OWNER = " + owner);
+ assertEquals(localunitSubject, owner);
+
+
+ } finally {
+ // Delete Unit User Account
+ deleteUnitUserAccount();
+
+
+ // 本テスト用セルの削除
+ CellUtils.delete(AbstractCase.MASTER_TOKEN_NAME, CREATE_CELL, -1);
+ // Delete Unit User Cell for the tests
+ CellUtils.delete(AbstractCase.MASTER_TOKEN_NAME, UNIT_USER_CELL, -1);
+ }
+ }
+
+ /**
+ * ユニットユーザートークンでセル作成を行いオーナーとして各種処理が可能なことを確認.
+ * @throws TokenRootCrtException
+ * @throws TokenDsigException
+ * @throws TokenParseException
+ */
+ @Test
+ public void ユニットユーザートークンでセル作成を行いオーナーとして各種処理が可能なことを確認() throws TokenParseException, TokenDsigException, TokenRootCrtException {
+ try {
+ // Creating Unit User Cell for this test case.
+ CellUtils.create(UNIT_USER_CELL, AbstractCase.MASTER_TOKEN_NAME, HttpStatus.SC_CREATED);
+
+ // Add Account
+ // Create Account
+ createUnitUserAccount();
+ // retrieve a Unit User Token
+ unitUserToken = getUnitUserToken();
+ // ユニットユーザートークンを使ってセル作成をする.
+ // オーナーがユニットユーザー(ここだとuserNameアカウントのURL)になるはず。
+ CellUtils.create(CREATE_CELL, unitUserToken, HttpStatus.SC_CREATED);
+
+ // ユニットユーザートークンを使ってセル更新ができることを確認
+ CellUtils.update(CREATE_CELL, CREATE_CELL, unitUserToken,
+ HttpStatus.SC_NO_CONTENT);
+
+ // オーナーが異なるユニットユーザートークン(マスタートークンのヘッダ指定での降格を利用)を使ってセル更新ができないことを確認
+ CellUtils.update(CREATE_CELL, CREATE_CELL, AbstractCase.MASTER_TOKEN_NAME,
+ UrlUtils.subjectUrl(UNIT_USER_CELL, "hoge"), HttpStatus.SC_FORBIDDEN);
+
+ // マスタートークンを使ってセル更新ができることを確認
+ CellUtils.update(CREATE_CELL, CREATE_CELL, AbstractCase.MASTER_TOKEN_NAME,
+ HttpStatus.SC_NO_CONTENT);
+
+ // ユニットユーザトークンを使えば取得可能なことを確認
+ CellUtils.get(CREATE_CELL, unitUserToken, HttpStatus.SC_OK);
+
+ // マスタートークンのオーナーヘッダ指定を使えば取得可能なことを確認
+ CellUtils.get(CREATE_CELL, AbstractCase.MASTER_TOKEN_NAME,
+ unitUserCellUrl + "#" + UNIT_USER_ACCOUNT, HttpStatus.SC_OK);
+
+ // オーナーが異なるユニットユーザトークン(マスタートークンのヘッダ指定での降格を利用)を使うと取得できないことを確認
+ CellUtils.get(CREATE_CELL, AbstractCase.MASTER_TOKEN_NAME,
+ UrlUtils.subjectUrl(UNIT_USER_CELL, "hoge"), HttpStatus.SC_FORBIDDEN);
+
+ // ユニットユーザートークンを使ってセル削除ができることを確認
+ CellUtils.delete(unitUserToken, CREATE_CELL, HttpStatus.SC_NO_CONTENT);
+ } finally {
+ // アカウント削除
+ deleteUnitUserAccount();
+
+ // 本テスト用セルの削除
+ CellUtils.delete(AbstractCase.MASTER_TOKEN_NAME, CREATE_CELL, -1);
+ CellUtils.delete(AbstractCase.MASTER_TOKEN_NAME, UNIT_USER_CELL, -1);
+ }
+ }
+
+
+ /**
+ * ユニットアドミンロールをもつユニットユーザートークンでセル作成を行いオーナーが設定されないことを確認.
+ */
+ @Test
+ public void ユニットアドミンロールをもつユニットユーザートークンでセル作成を行いオーナーが設定されないことを確認() {
+
+ try {
+ // 本テスト用セルの作成
+ CellUtils.create(UNIT_USER_CELL, AbstractCase.MASTER_TOKEN_NAME, HttpStatus.SC_CREATED);
+
+ // アカウント追加
+ createUnitUserAccount();
+
+ // Add unitAdminRole
+ createUnitAdminRole();
+
+ // linkUnit AdminRole with account
+ linkUuAccountAndUnitAdminRole();
+
+
+ // 認証(ユニットユーザートークン取得)
+ unitUserToken = getUnitUserToken();
+
+ // ユニットユーザートークンを使ってセル作成をするとオーナーがユニットユーザー(ここだとuserNameアカウントのURL)になるはず。
+ CellUtils.create(CREATE_CELL, unitUserToken, HttpStatus.SC_CREATED);
+
+ // UnitUserTokenを自作
+ TransCellAccessToken tcat = new TransCellAccessToken(UrlUtils.cellRoot(UNIT_USER_CELL),
+ UrlUtils.subjectUrl(UNIT_USER_CELL, UNIT_USER_ACCOUNT),
+ UrlUtils.getBaseUrl() + "/", new ArrayList(), null, null);
+
+ // ユニットユーザトークンでは取得できないことを確認
+ CellUtils.get(CREATE_CELL, tcat.toTokenString(), HttpStatus.SC_FORBIDDEN);
+
+ // セルのオーナーが見指定のため、マスタートークンのオーナーヘッダ指定を使うと取得不可なことを確認
+ CellUtils.get(CREATE_CELL, AbstractCase.MASTER_TOKEN_NAME,
+ UrlUtils.subjectUrl(UNIT_USER_CELL, UNIT_USER_ACCOUNT), HttpStatus.SC_FORBIDDEN);
+
+ // オーナーが設定されていないのでマスタートークンのみアクセス可能
+ CellUtils.get(CREATE_CELL, AbstractCase.MASTER_TOKEN_NAME, HttpStatus.SC_OK);
+ } finally {
+ // ロール削除(BOXに結びつかない)
+ deleteUnitAdminRole();
+
+ // アカウント削除
+ deleteUnitUserAccount();
+ // 本テスト用セルの削除
+ CellUtils.delete(AbstractCase.MASTER_TOKEN_NAME, UNIT_USER_CELL, -1);
+ CellUtils.delete(AbstractCase.MASTER_TOKEN_NAME, CREATE_CELL, -1);
+ }
+ }
+
+
+
+
+ /**
+ * セルレベルPROPPATCHをユニットユーザトークンで実行可能なことを確認.
+ * @throws TokenParseException トークンパースエラー
+ */
+ @Test
+ public void セルレベルPROPPATCHをユニットユーザトークンで実行可能なことを確認() throws TokenParseException {
+ try {
+ // 本テスト用セルの作成
+ CellUtils.create(UNIT_USER_CELL, AbstractCase.MASTER_TOKEN_NAME, HttpStatus.SC_CREATED);
+ // アカウント追加
+ createUnitUserAccount();
+ // 認証(ユニットユーザートークン取得)
+ unitUserToken = getUnitUserToken();
+
+ // アカウントにユニット昇格権限付
+ try (CloseableHttpClient client = HttpClientFactory.create(HttpClientFactory.TYPE_ALWAYS_LOCAL)) {
+// BasicHttpEntityEnclosingRequest proppatch = new BasicHttpEntityEnclosingRequest("PROPPATCH", unitUserCellUrl);
+ String ppStr = "\n" +
+ "\n" +
+ " \n" +
+ " \n" +
+ " account1account2\n" +
+ " \n" +
+ " \n" +
+ "\n";
+ HttpEntity entity = new StringEntity(ppStr);
+ RequestBuilder proppatch = RequestBuilder.create("PROPPATCH")
+ .setUri(unitUserCellUrl)
+ .addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + unitUserToken)
+ .addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_XML.getMimeType())
+ .addHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_XML.getMimeType())
+ .setEntity(entity);
+ try (CloseableHttpResponse res = client.execute(null, proppatch.build())) {
+ assertEquals(207, res.getStatusLine().getStatusCode());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } finally {
+
+ // アカウント削除
+ deleteUnitUserAccount();
+ // 本テスト用セルの削除
+ CellUtils.delete(AbstractCase.MASTER_TOKEN_NAME, UNIT_USER_CELL, -1);
+ }
+
+
+ }
+
+ /**
+ * セルレベルPROPPATCHをオーナーの違うユニットユーザトークンでは実行不可なことを確認.
+ * @throws TokenParseException トークンパースエラー
+ */
+ @Test
+ @Ignore // UUT promotion setting API invalidation.
+ public void セルレベルPROPPATCHをオーナーの違うユニットユーザトークンでは実行不可なことを確認() throws TokenParseException {
+ // UnitUserTokenを自作
+ TransCellAccessToken tcat = new TransCellAccessToken(UrlUtils.cellRoot(UNIT_USER_CELL),
+ Setup.OWNER_HMC, UrlUtils.getBaseUrl() + "/", new ArrayList(), null, null);
+
+ String unitUserToken = tcat.toTokenString();
+
+ // アカウントにユニット昇格権限付与
+ DavResourceUtils.setProppatch(Setup.TEST_CELL1, unitUserToken,
+ "cell/proppatch-uluut.txt", HttpStatus.SC_FORBIDDEN);
+ }
+
+ /**
+ * セルレベルPROPPATCHをユニットローカルユニットユーザトークンで実行可能なことを確認.
+ * @throws TokenParseException トークンパースエラー
+ */
+ @Test
+ @Ignore // UUT promotion setting API invalidation.
+ public void セルレベルPROPPATCHをユニットローカルユニットユーザトークンで実行可能なことを確認() throws TokenParseException {
+ // アカウントにユニット昇格権限付与
+ DavResourceUtils.setProppatch(Setup.TEST_CELL1, AbstractCase.MASTER_TOKEN_NAME,
+ "cell/proppatch-uluut.txt", HttpStatus.SC_MULTI_STATUS);
+
+ // パスワード認証でのユニット昇格
+ TResponse res = Http.request("authnUnit/password-uluut.txt")
+ .with("remoteCell", Setup.TEST_CELL1)
+ .with("username", "account1")
+ .with("password", "password1")
+ .returns()
+ .statusCode(HttpStatus.SC_OK);
+
+ JSONObject json = res.bodyAsJson();
+ String uluutString = (String) json.get(OAuth2Helper.Key.ACCESS_TOKEN);
+
+ // アカウントにユニット昇格権限付与
+ DavResourceUtils.setProppatch(Setup.TEST_CELL1, uluutString,
+ "cell/proppatch-uluut.txt", HttpStatus.SC_MULTI_STATUS);
+ }
+
+ /**
+ * セルレベルPROPPATCHをオーナーが違うユニットローカルユニットユーザトークンで実行不可なことを確認.
+ * @throws TokenParseException トークンパースエラー
+ */
+ @Test
+ @Ignore // UUT promotion setting API invalidation.
+ public void セルレベルPROPPATCHをオーナーが違うユニットローカルユニットユーザトークンで実行不可なことを確認() throws TokenParseException {
+ // アカウントにユニット昇格権限付与
+ DavResourceUtils.setProppatch(Setup.TEST_CELL1, AbstractCase.MASTER_TOKEN_NAME,
+ "cell/proppatch-uluut.txt", HttpStatus.SC_MULTI_STATUS);
+
+ // パスワード認証でのユニット昇格
+ TResponse res = Http.request("authnUnit/password-uluut.txt")
+ .with("remoteCell", Setup.TEST_CELL1)
+ .with("username", "account1")
+ .with("password", "password1")
+ .returns()
+ .statusCode(HttpStatus.SC_OK);
+
+ JSONObject json = res.bodyAsJson();
+ String uluutString = (String) json.get(OAuth2Helper.Key.ACCESS_TOKEN);
+
+ // アカウントにユニット昇格権限付与
+ DavResourceUtils.setProppatch(Setup.TEST_CELL2, uluutString,
+ "cell/proppatch-uluut.txt", HttpStatus.SC_FORBIDDEN);
+ }
+
+
+}
diff --git a/src/test/java/io/personium/test/jersey/cell/UnitUserCellTest.java b/src/test/java/io/personium/test/jersey/unit/UnitUserCellTest.java
similarity index 98%
rename from src/test/java/io/personium/test/jersey/cell/UnitUserCellTest.java
rename to src/test/java/io/personium/test/jersey/unit/UnitUserCellTest.java
index 415dca118..9ca0d991c 100644
--- a/src/test/java/io/personium/test/jersey/cell/UnitUserCellTest.java
+++ b/src/test/java/io/personium/test/jersey/unit/UnitUserCellTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.personium.test.jersey.cell;
+package io.personium.test.jersey.unit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -86,6 +86,7 @@ public class UnitUserCellTest extends PersoniumTest {
/** unitUser.issuers in properties. */
private static String issuersBackup = "";
+ private static String urlModeBackup = "";
/**
* Constructor. テスト対象のパッケージをsuperに渡す必要がある
@@ -101,9 +102,12 @@ public UnitUserCellTest() {
@BeforeClass
public static void beforeClass() throws Exception {
// Override issuers in unitconfig.
- issuersBackup = PersoniumUnitConfig.get("io.personium.core.unitUser.issuers");
- PersoniumUnitConfig.set("io.personium.core.unitUser.issuers",
- UriUtils.SCHEME_LOCALUNIT + ":/" + UNIT_USER_CELL + "/");
+ urlModeBackup = PersoniumUnitConfig.get(PersoniumUnitConfig.PATH_BASED_CELL_URL_ENABLED);
+ PersoniumUnitConfig.set(PersoniumUnitConfig.PATH_BASED_CELL_URL_ENABLED,
+ "true");
+ issuersBackup = PersoniumUnitConfig.get(PersoniumUnitConfig.UNIT_USER_ISSUERS);
+ PersoniumUnitConfig.set(PersoniumUnitConfig.UNIT_USER_ISSUERS,
+ UriUtils.SCHEME_LOCALUNIT + ":" + UNIT_USER_CELL + ":/");
// Read role name from AccessContext
Field admin = AccessContext.class.getDeclaredField("ROLE_UNIT_ADMIN");
@@ -123,8 +127,9 @@ public static void beforeClass() throws Exception {
@AfterClass
public static void afterClass() {
// Restore issuers in unitconfig.
- PersoniumUnitConfig.set("io.personium.core.unitUser.issuers",
+ PersoniumUnitConfig.set(PersoniumUnitConfig.UNIT_USER_ISSUERS,
issuersBackup != null ? issuersBackup : ""); // CHECKSTYLE IGNORE
+ PersoniumUnitConfig.set(PersoniumUnitConfig.PATH_BASED_CELL_URL_ENABLED, urlModeBackup);
}
/**
@@ -216,7 +221,7 @@ public static void afterClass() {
// 本テスト用 Unit User Cell の作成
CellUtils.create(UNIT_USER_CELL, AbstractCase.MASTER_TOKEN_NAME, HttpStatus.SC_CREATED);
- // アカウント追加
+ // AddAccount
AccountUtils.create(AbstractCase.MASTER_TOKEN_NAME, UNIT_USER_CELL,
UNIT_USER_ACCOUNT, UNIT_USER_ACCOUNT_PASS, HttpStatus.SC_CREATED);