io.personium
diff --git a/src/main/java/io/personium/core/PersoniumCoreAuthnException.java b/src/main/java/io/personium/core/PersoniumCoreAuthnException.java
index 9ee17607b..03c44edf7 100644
--- a/src/main/java/io/personium/core/PersoniumCoreAuthnException.java
+++ b/src/main/java/io/personium/core/PersoniumCoreAuthnException.java
@@ -38,9 +38,6 @@
/**
* Log message creation class.
*/
-/**
- * @author naoki
- */
@SuppressWarnings("serial")
public final class PersoniumCoreAuthnException extends PersoniumCoreException {
@@ -56,7 +53,7 @@ public final class PersoniumCoreAuthnException extends PersoniumCoreException {
/**
* Client Secret Parsing error.
*/
- public static final PersoniumCoreAuthnException CLIENT_SECRET_PARSE_ERROR =
+ public static final PersoniumCoreAuthnException CLIENT_ASSERTION_PARSE_ERROR =
create("PR400-AN-0003", Error.INVALID_CLIENT);
/**
* Client Secret expiration date check.
@@ -69,7 +66,7 @@ public final class PersoniumCoreAuthnException extends PersoniumCoreException {
public static final PersoniumCoreAuthnException CLIENT_SECRET_DSIG_INVALID =
create("PR400-AN-0005", Error.INVALID_CLIENT);
/**
- * Issuer of Client Secret is not equal to ID.
+ * Issuer of Client Secret does not match client id.
*/
public static final PersoniumCoreAuthnException CLIENT_SECRET_ISSUER_MISMATCH =
create("PR400-AN-0006", Error.INVALID_CLIENT);
@@ -129,12 +126,29 @@ public final class PersoniumCoreAuthnException extends PersoniumCoreException {
*/
public static final PersoniumCoreAuthnException AUTH_HEADER_IS_INVALID =
create("PR400-AN-0018", Error.INVALID_CLIENT);
+ /**
+ * Invalid assertion type parameter.
+ */
+ public static final PersoniumCoreAuthnException INVALID_CLIENT_ASSERTION_TYPE =
+ create("PR400-AN-0022", Error.INVALID_CLIENT);
+ /**
+ * Authenticated Client does not match the refresh token.
+ */
+ public static final PersoniumCoreAuthnException CLIENT_MISMATCH_FOR_REFRESH =
+ create("PR401-AN-0020", Error.INVALID_CLIENT);
+ /**
+ * Client auth required to refresh the token.
+ */
+ public static final PersoniumCoreAuthnException CLIENT_AUTH_REQUIRED =
+ create("PR401-AN-0021", Error.INVALID_CLIENT);
/**
* Password change required.
*/
public static final PersoniumCoreAuthnException PASSWORD_CHANGE_REQUIRED =
create("PR401-AN-0001", Error.UNAUTHORIZED_CLIENT);
+
+
/**
* NetWork related error.
*/
diff --git a/src/main/java/io/personium/core/PersoniumCoreException.java b/src/main/java/io/personium/core/PersoniumCoreException.java
index 91d246443..c2a351ff6 100644
--- a/src/main/java/io/personium/core/PersoniumCoreException.java
+++ b/src/main/java/io/personium/core/PersoniumCoreException.java
@@ -739,6 +739,11 @@ public static class Auth {
* Schema authentication level is insufficient.
*/
public static final PersoniumCoreException INSUFFICIENT_SCHEMA_AUTHZ_LEVEL = create("PR403-AU-0006");
+ /**
+ * Scope is insufficient.
+ */
+ public static final PersoniumCoreException INSUFFICIENT_SCOPE = create("PR403-AU-0007");
+
/**
* Error setting root CA certificate.
*/
@@ -1014,6 +1019,13 @@ public static class Common {
* {0} : Overview of failed processing
*/
public static final PersoniumCoreException FILE_IO_ERROR = create("PR500-CM-0002");
+
+ /**
+ * Unchecked Invalid URL used internally.
+ *
+ * {0} : URL
+ */
+ public static final PersoniumCoreException INVALID_URL = create("PR500-CM-0003");
}
/**
diff --git a/src/main/java/io/personium/core/PersoniumReadDeleteModeManager.java b/src/main/java/io/personium/core/PersoniumReadDeleteModeManager.java
index 6f2a31caa..e11cb2082 100644
--- a/src/main/java/io/personium/core/PersoniumReadDeleteModeManager.java
+++ b/src/main/java/io/personium/core/PersoniumReadDeleteModeManager.java
@@ -42,7 +42,7 @@ private PersoniumReadDeleteModeManager() {
HttpMethod.DELETE,
HttpMethod.OPTIONS,
HttpMethod.HEAD,
- io.personium.common.utils.PersoniumCoreUtils.HttpMethod.PROPFIND,
+ io.personium.common.utils.CommonUtils.HttpMethod.PROPFIND,
"REPORT"
)
);
diff --git a/src/main/java/io/personium/core/PersoniumUnitConfig.java b/src/main/java/io/personium/core/PersoniumUnitConfig.java
index 222edb85f..dad6bfde4 100644
--- a/src/main/java/io/personium/core/PersoniumUnitConfig.java
+++ b/src/main/java/io/personium/core/PersoniumUnitConfig.java
@@ -1,6 +1,7 @@
/**
- * personium.io
- * Copyright 2014-2018 FUJITSU LIMITED
+ * Personium
+ * Copyright 2014-2018 Personium Project
+ * - FUJITSU LIMITED
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,7 +35,7 @@
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
-import io.personium.common.utils.PersoniumCoreUtils;
+import io.personium.common.utils.CommonUtils;
import io.personium.core.auth.AuthUtils;
import io.personium.core.utils.UriUtils;
@@ -188,6 +189,16 @@ public static final class Security {
/** Encrypt the DAV file (true: enabled false: disabled (default)). */
public static final String DAV_ENCRYPT_ENABLED = KEY_ROOT + "security.dav.encrypt.enabled";
+
+ /** Default scope of token for grant_type=password . */
+ public static final String TOKEN_DEFAULT_SCOPE_ROPC = KEY_ROOT + "security.token.defaultScope.ropc";
+
+ /** Default scope of token for grant_type=assertion . */
+ public static final String TOKEN_DEFAULT_SCOPE_ASSERTION = KEY_ROOT + "security.token.defaultScope.assertion";
+
+ /** Default scope of token for grant_type=code . */
+ public static final String TOKEN_DEFAULT_SCOPE_CODE = KEY_ROOT + "security.token.defaultScope.grant_code";
+
}
/**
@@ -538,14 +549,14 @@ private synchronized void doReload() {
}
}
- private static boolean isSpaceSeparatedValueIncluded(String spaceSeparatedValue, String testValue, String unitUrl) {
+ private static boolean isSpaceSeparatedValueIncluded(String spaceSeparatedValue, String testValue) {
if (testValue == null || spaceSeparatedValue == null) {
return false;
}
String[] values = spaceSeparatedValue.split(" ");
for (String val : values) {
// Correspondence when "localunit" is set for issuers.
- String convertedValue = UriUtils.convertSchemeFromLocalUnitToHttp(unitUrl, val);
+ String convertedValue = UriUtils.convertSchemeFromLocalUnitToHttp(val);
if (testValue.equals(convertedValue)) {
return true;
}
@@ -871,7 +882,7 @@ public static String getPluginPath() {
public static String getBaseUrl() {
return UriBuilder.fromPath("/")
.scheme(getUnitScheme())
- .host(PersoniumCoreUtils.getFQDN())
+ .host(CommonUtils.getFQDN())
.port(getUnitPort())
.build()
.toString();
@@ -1473,6 +1484,29 @@ public static boolean isDavEncryptEnabled() {
return Boolean.parseBoolean(get(Security.DAV_ENCRYPT_ENABLED));
}
+ /**
+ *
+ * @return scope string
+ */
+ public static String getTokenDefaultScopeRopc() {
+ return get(Security.TOKEN_DEFAULT_SCOPE_ROPC);
+ }
+ /**
+ *
+ * @return scope string
+ */
+ public static String getTokenDefaultScopeCode() {
+ return get(Security.TOKEN_DEFAULT_SCOPE_CODE);
+ }
+ /**
+ *
+ * @return scope string
+ */
+ public static String getTokenDefaultScopeAssertion() {
+ return get(Security.TOKEN_DEFAULT_SCOPE_ASSERTION);
+ }
+
+
/**
* Get message queue implementation of EventBus.
* @return message queue
@@ -1614,8 +1648,8 @@ public static boolean isHttps() {
* @param unitUrl Unit URL
* @return Included:true
*/
- public static boolean checkUnitUserIssuers(String url, String unitUrl) {
- return isSpaceSeparatedValueIncluded(getUnitUserIssuers(), url, unitUrl);
+ public static boolean checkUnitUserIssuers(String url) {
+ return isSpaceSeparatedValueIncluded(getUnitUserIssuers(), url);
}
/**
diff --git a/src/main/java/io/personium/core/auth/AccessContext.java b/src/main/java/io/personium/core/auth/AccessContext.java
index bf3b27de6..d5b853821 100644
--- a/src/main/java/io/personium/core/auth/AccessContext.java
+++ b/src/main/java/io/personium/core/auth/AccessContext.java
@@ -16,10 +16,15 @@
*/
package io.personium.core.auth;
+import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
+import java.net.URL;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import javax.ws.rs.core.UriInfo;
@@ -27,20 +32,20 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import io.personium.common.auth.token.AbstractLocalAccessToken;
import io.personium.common.auth.token.AbstractOAuth2Token;
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.AccountAccessToken;
-import io.personium.common.auth.token.CellLocalAccessToken;
import io.personium.common.auth.token.IAccessToken;
-import io.personium.common.auth.token.LocalToken;
import io.personium.common.auth.token.PasswordChangeAccessToken;
+import io.personium.common.auth.token.ResidentLocalAccessToken;
import io.personium.common.auth.token.Role;
import io.personium.common.auth.token.TransCellAccessToken;
-import io.personium.common.auth.token.TransCellRefreshToken;
import io.personium.common.auth.token.UnitLocalUnitUserToken;
-import io.personium.common.utils.PersoniumCoreUtils;
+import io.personium.common.auth.token.VisitorLocalAccessToken;
+import io.personium.common.auth.token.VisitorRefreshToken;
+import io.personium.common.utils.CommonUtils;
import io.personium.core.PersoniumCoreAuthzException;
import io.personium.core.PersoniumCoreException;
import io.personium.core.PersoniumCoreLog;
@@ -67,23 +72,23 @@ public class AccessContext {
/** Anonymous access : No Authorization header. */
public static final String TYPE_ANONYMOUS = "anon";
- /** Access with invalid permissions : Authorization header was present, but it was not authenticated. */
+ /** Access with invalid access token : Authorization header was present, but it was not authenticated. */
public static final String TYPE_INVALID = "invalid";
- /** Access with master token : Authorization header content is master token. */
+ /** Access with master token : Authorization header content is unit master token. */
public static final String TYPE_UNIT_MASTER = "unit-master";
- /** Access by basic authentication. */
+ /** Access with basic authentication. */
public static final String TYPE_BASIC = "basic";
- /** Access by account access token. */
- public static final String TYPE_ACCOUNT = "account";
- /** Access by password change access token. */
+ /** Access with Resident Local Access Token. */
+ public static final String TYPE_RESIDENT = "account";
+ /** Access with password change access token. */
public static final String TYPE_PASSWORD_CHANGE = "password-change";
- /** Access by cell local access token. */
- public static final String TYPE_LOCAL = "local";
- /** Access by TransCell Access Token. */
+ /** Access with visitor local access token. */
+ public static final String TYPE_VISITOR = "local";
+ /** Access with Trans Cell Access Token. */
public static final String TYPE_TRANS = "trans";
- /** Access by Unit User Access token. */
+ /** Access with Unit User Access token. */
public static final String TYPE_UNIT_USER = "unit-user";
- /** Access by "Unit User Access token" assigned "UnitAdmin authority". */
+ /** Access with "Unit User Access token" assigned "UnitAdmin authority". */
public static final String TYPE_UNIT_ADMIN = "unit-admin";
/** Access by Unit Local Unit User Token. */
public static final String TYPE_UNIT_LOCAL = "unit-local";
@@ -134,12 +139,19 @@ private enum InvalidReason {
private Cell cell;
/** Access token type. */
private String accessType;
- /** subject. */
+ /** accessing user subject. */
private String subject;
- /** issuer. */
+ /** access token issuer. */
private String issuer;
- /** schema. */
+ /** accessing app schema. */
private String schema;
+ /** scopes granted to the app. */
+ private Set scopes = new HashSet<>();
+ /** CellPrivilege granted for App as scope. */
+ private Set scopePrivileges = new HashSet<>();
+ /** Roles granted for App as scope. */
+ private Set scopeRoles = new HashSet<>();
+
/** confidentialLevel. */
private String confidentialLevel;
/** Roles associated with access account. */
@@ -163,6 +175,7 @@ private AccessContext(String type, Cell cell, String baseUri, UriInfo uriInfo, I
this.baseUri = baseUri;
this.uriInfo = uriInfo;
this.invalidReason = invalidReason;
+
}
/**
@@ -184,40 +197,22 @@ public static AccessContext create(String authzHeaderValue,
if (pCookiePeer == null || 0 == pCookiePeer.length()) {
return new AccessContext(TYPE_ANONYMOUS, cell, baseUri, requestURIInfo);
}
- //Cookie authentication
- //Get decrypted value of cookie value
- if (null == pCookieAuthValue) {
- return new AccessContext(
- TYPE_INVALID, cell, baseUri, requestURIInfo, InvalidReason.cookieAuthError);
- }
+ String nonPortHost = headerHost.split(":")[0];
+
// Cookie related processing requires no port number.
- String decodedCookieValue;
+ String authToken = null;
try {
- String nonPortHost = headerHost.split(":")[0];
- decodedCookieValue = LocalToken.decode(pCookieAuthValue,
- UnitLocalUnitUserToken.getIvBytes(AccessContext.getCookieCryptKey(nonPortHost)));
- } catch (TokenParseException e) {
- return new AccessContext(
- TYPE_INVALID, cell, baseUri, requestURIInfo, InvalidReason.cookieAuthError);
- }
- int separatorIndex = decodedCookieValue.indexOf("\t");
- String peer = decodedCookieValue.substring(0, separatorIndex);
- //Obtain authorizationHeader equivalent token from information in cookie
- String authToken = decodedCookieValue.substring(separatorIndex + 1);
- if (pCookiePeer.equals(peer)) {
- //Generate appropriate AccessContext with recursive call.
+ authToken = AbstractLocalAccessToken.parseCookie(pCookieAuthValue, pCookiePeer,
+ AccessContext.getCookieCryptKey(nonPortHost), true);
return create(OAuth2Helper.Scheme.BEARER + " " + authToken,
requestURIInfo, null, null, cell, baseUri, headerHost, xPersoniumUnitUser);
- } else {
+ } catch (TokenParseException e) {
return new AccessContext(
TYPE_INVALID, cell, baseUri, requestURIInfo, InvalidReason.cookieAuthError);
}
}
- //TODO V1.1 Here is the part that can be cached. You can get it from the cache here.
-
- //First branch depending on the authentication method
-
+ // First branch depending on the authentication method
if (authzHeaderValue.startsWith(OAuth2Helper.Scheme.BASIC)) {
//Basic authentication
return createBasicAuthz(authzHeaderValue, cell, baseUri, requestURIInfo);
@@ -284,6 +279,13 @@ public String getIssuer() {
public String getSchema() {
return schema;
}
+ /**
+ * Get scopes.
+ * @return scopes
+ */
+ public String[] getScope() {
+ return this.scopes.toArray(new String[0]);
+ }
/**
* Get confidentialLevel.
@@ -327,12 +329,11 @@ public String getUnitUserRole() {
/**
* Merge with the parent's ACL information and judge whether access is possible.
- * @param acl ALC set in the resource
+ * @param acl ACL set in the resource
* @param resourcePrivilege Privilege required to access the resource
- * @param cellUrl Cell URL
* @return boolean
*/
- public boolean requirePrivilege(Acl acl, Privilege resourcePrivilege, String cellUrl) {
+ public boolean hasSubjectPrivilegeForAcl(Acl acl, Privilege resourcePrivilege) {
//No access if ACL is not set
if (acl == null || acl.getAceList() == null) {
return false;
@@ -371,7 +372,7 @@ public boolean requirePrivilege(Acl acl, Privilege resourcePrivilege, String cel
}
//Detect setting corresponding to role
- if (role.localCreateUrl(cellUrl).equals(principalHref)) {
+ if (role.localCreateUrl(this.cell.getUrl()).equals(principalHref)) {
//Confirm whether Root is set
if (ace.getGrantedPrivilegeList().contains(CellPrivilege.ROOT.getName())) {
return true;
@@ -392,17 +393,17 @@ public boolean requirePrivilege(Acl acl, Privilege resourcePrivilege, String cel
*/
public boolean isUnitUserToken() {
String type = getType();
- if (TYPE_UNIT_MASTER.equals(type)
- || TYPE_UNIT_ADMIN.equals(type)) {
+ if (TYPE_UNIT_MASTER.equals(type) || TYPE_UNIT_ADMIN.equals(type)) {
return true;
} else if ((TYPE_UNIT_USER.equals(type) || TYPE_UNIT_LOCAL.equals(type))
- && getSubject().equals(getCell().getOwner())) {
+ && getSubject().equals(getCell().getOwnerNormalized())) {
//↑ Unit user, Unit For local unit users, this is valid only when the unit owner name included in the token and the cell owner to be processed match.
return true;
}
return false;
}
+
/**
* Perform access control (only master token, unit user token, unit local unit user token accessible).
* @param resourcePrivilege Required authority
@@ -414,7 +415,7 @@ public boolean isUnitUserToken(Privilege resourcePrivilege) {
return true;
} else if (TYPE_UNIT_ADMIN.equals(type)
|| ((TYPE_UNIT_USER.equals(type) || TYPE_UNIT_LOCAL.equals(type)) //NOPMD - To maintain readability
- && getSubject().equals(getCell().getOwner()))) {
+ && getSubject().equals(getCell().getOwnerNormalized()))) {
// In the case of a UnitUser or UnitLocal, it is effective only when the unit owner name included
// in the processing target cell owner and the token matches.
@@ -444,8 +445,9 @@ public JSONObject getUnitMetadataJson() {
}
/**
- * Access control is performed (Subject can access only token of CELL).
- * @param acceptableAuthScheme Whether it is a call from a resource that does not allow basic authentication
+ * Check that the subject in the TCAT is identical to the issuer.
+ * @param acceptableAuthScheme
+ * Whether it is a call from a resource that does not allow basic authentication
*/
public void checkCellIssueToken(AcceptableAuthScheme acceptableAuthScheme) {
if (TYPE_TRANS.equals(this.getType())
@@ -469,7 +471,7 @@ public void checkCellIssueToken(AcceptableAuthScheme acceptableAuthScheme) {
* @param cellname cell
* @param acceptableAuthScheme Whether it is a call from a resource that does not allow basic authentication
*/
- public void checkMyLocalOrPasswordChangeToken(Cell cellname, AcceptableAuthScheme acceptableAuthScheme) {
+ public void checkResidentLocalOrPasswordChangeToken(AcceptableAuthScheme acceptableAuthScheme) {
//Returning 401 if there is no illegal token or token designation
//Returning 403 for a token other than your own cell local token
if (TYPE_INVALID.equals(this.getType())) {
@@ -477,9 +479,14 @@ public void checkMyLocalOrPasswordChangeToken(Cell cellname, AcceptableAuthSchem
} else if (TYPE_ANONYMOUS.equals(this.getType())
|| TYPE_BASIC.equals(this.getType())) {
throw PersoniumCoreAuthzException.AUTHORIZATION_REQUIRED.realm(getRealm(), acceptableAuthScheme);
- } else if (!TYPE_ACCOUNT.equals(this.getType()) && !TYPE_PASSWORD_CHANGE.equals(this.getType())) {
+ } else if (!TYPE_RESIDENT.equals(this.getType()) && !TYPE_PASSWORD_CHANGE.equals(this.getType())) {
throw PersoniumCoreException.Auth.NECESSARY_PRIVILEGE_LACKING;
}
+
+ // Check that the subject is resident and the app scope include auth priv.
+ if (TYPE_RESIDENT.equals(this.getType()) && !this.hasScopeCellPrivilege(CellPrivilege.AUTH)) {
+ throw PersoniumCoreException.Auth.INSUFFICIENT_SCOPE.params(CellPrivilege.AUTH.getName());
+ }
}
/**
@@ -489,7 +496,8 @@ public void checkMyLocalOrPasswordChangeToken(Cell cellname, AcceptableAuthSchem
* @param acceptableAuthScheme Whether it is a call from a resource that does not allow basic authentication
*/
public void checkSchemaAccess(String settingConfidentialLevel, Box box, AcceptableAuthScheme acceptableAuthScheme) {
- //If you are a master token or unit user, unit local unit user pass through schema authentication.
+ // If accessed with a master, unit user token, or unit local unit user token,
+ // Then pass through schema authentication.
if (this.isUnitUserToken()) {
return;
}
@@ -532,7 +540,7 @@ public void checkSchemaAccess(String settingConfidentialLevel, Box box, Acceptab
*/
public void checkSchemaMatches(Box box) {
if (box != null) {
- String boxSchema = UriUtils.convertSchemeFromLocalUnitToHttp(cell.getUnitUrl(), box.getSchema());
+ String boxSchema = UriUtils.convertSchemeFromLocalUnitToHttp(box.getSchema());
String tokenSchema = getSchema();
// Do not check if box schema is not set.
@@ -548,8 +556,10 @@ public void checkSchemaMatches(Box box) {
}
/**
- * If basic authentication can not be done, it is checked whether basic authentication can be performed or not, and the state of Basic authentication disabled is set in context.
- * In this method, only checking is performed, and whether or not it is actually an authentication error is left to the access right check process of the structure.
+ * If basic authentication can not be done, it is checked whether basic authentication can be performed or not,
+ * and the state of Basic authentication disabled is set in context.
+ * In this method, only checking is performed, and whether or not it is actually an authentication error
+ * is left to the access right check process of the structure.
* @param box Box object (specify null for Cell level)
*/
public void updateBasicAuthenticationStateForResource(Box box) {
@@ -565,7 +575,7 @@ public void updateBasicAuthenticationStateForResource(Box box) {
}
//The main box has a schema but basic authentication is possible
- if (Role.DEFAULT_BOX_NAME.equals(box.getName())) {
+ if (Box.MAIN_BOX_NAME.equals(box.getName())) {
return;
}
@@ -647,7 +657,7 @@ private static AccessContext createBasicAuthz(String authzHeaderValue, Cell cell
return new AccessContext(TYPE_INVALID, null, baseUri, uriInfo, InvalidReason.basicAuthError);
}
- String[] idpw = PersoniumCoreUtils.parseBasicAuthzHeader(authzHeaderValue);
+ String[] idpw = CommonUtils.parseBasicAuthzHeader(authzHeaderValue);
if (idpw == null) {
return new AccessContext(TYPE_INVALID, cell, baseUri, uriInfo, InvalidReason.basicAuthFormat);
}
@@ -680,8 +690,27 @@ private static AccessContext createBasicAuthz(String authzHeaderValue, Cell cell
ret.subject = username;
//Acquire role information
ret.roles = cell.getRoleListForAccount(username);
+ // TODO Make configurable
+ ret.addScope("root");
+
return ret;
}
+ public void addScope(String scopeStr) {
+ this.scopes.add(scopeStr);
+ if (scopeStr.startsWith("https://")||scopeStr.startsWith("http://")) {
+ try {
+ this.scopeRoles.add(new Role(new URL(scopeStr)));
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ CellPrivilege prv = CellPrivilege.get(CellPrivilege.class, scopeStr);
+ if (prv != null) {
+ this.scopePrivileges.add(prv);
+ }
+ }
+
+ }
/**
* Factory method, which creates and returns an object by Bearer authentication based on the value of Cell and Authorization header being accessed.
@@ -736,7 +765,7 @@ private static AccessContext createBearerAuthz(String authzHeaderValue, Cell cel
}
log.debug(tk.getClass().getCanonicalName());
//If it is not an AccessToken, ie a refresh token.
- if (!(tk instanceof IAccessToken) || tk instanceof TransCellRefreshToken) {
+ if (!(tk instanceof IAccessToken) || tk instanceof VisitorRefreshToken) {
//Access by refresh token is not permitted.
return new AccessContext(TYPE_INVALID, cell, baseUri, uriInfo, InvalidReason.refreshToken);
}
@@ -747,8 +776,8 @@ private static AccessContext createBearerAuthz(String authzHeaderValue, Cell cel
}
AccessContext ret = new AccessContext(null, cell, baseUri, uriInfo);
- if (tk instanceof AccountAccessToken) {
- ret.accessType = TYPE_ACCOUNT;
+ if (tk instanceof ResidentLocalAccessToken) {
+ ret.accessType = TYPE_RESIDENT;
//Retrieve role information.
String acct = tk.getSubject();
ret.roles = cell.getRoleListForAccount(acct);
@@ -763,9 +792,9 @@ private static AccessContext createBearerAuthz(String authzHeaderValue, Cell cel
ret.accessType = TYPE_PASSWORD_CHANGE;
ret.subject = cell.getUrl() + "#" + tk.getSubject();
ret.issuer = tk.getIssuer();
- } else if (tk instanceof CellLocalAccessToken) {
- CellLocalAccessToken clat = (CellLocalAccessToken) tk;
- ret.accessType = TYPE_LOCAL;
+ } else if (tk instanceof VisitorLocalAccessToken) {
+ VisitorLocalAccessToken clat = (VisitorLocalAccessToken) tk;
+ ret.accessType = TYPE_VISITOR;
//Acquire roll information and pack it.
ret.roles = clat.getRoles();
ret.subject = tk.getSubject();
@@ -791,8 +820,26 @@ private static AccessContext createBearerAuthz(String authzHeaderValue, Cell cel
} else {
ret.confidentialLevel = OAuth2Helper.SchemaLevel.PUBLIC;
}
-
- // TODO Cache Cell Level
+ if (tk.getScope() != null) {
+ ret.scopes.addAll(Arrays.asList(tk.getScope()));
+ for (String scope : ret.scopes) {
+ if (OAuth2Helper.Scope.OPENID.contentEquals(scope)) {
+ continue;
+ }
+ if (scope.startsWith("https://")||scope.startsWith("http://")) {
+ try {
+ ret.scopeRoles.add(new Role(new URL(scope)));
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ CellPrivilege prv = CellPrivilege.get(CellPrivilege.class, scope);
+ if (prv != null) {
+ ret.scopePrivileges.add(prv);
+ }
+ }
+ }
+ }
return ret;
}
@@ -887,8 +934,8 @@ private static AccessContext createAccessContext(Cell cell, String requestURIHos
String issuer = tca.getIssuer();
if ((tca.getTarget().equals(baseUri) || tca.getTarget().equals(escapedBaseUri))
- && (PersoniumUnitConfig.checkUnitUserIssuers(issuer, baseUri)
- || PersoniumUnitConfig.checkUnitUserIssuers(issuer, escapedBaseUri))) {
+ && (PersoniumUnitConfig.checkUnitUserIssuers(issuer)
+ || PersoniumUnitConfig.checkUnitUserIssuers(issuer))) {
//Processing unit user tokens
ret.accessType = TYPE_UNIT_USER;
ret.subject = tca.getSubject();
@@ -896,12 +943,12 @@ private static AccessContext createAccessContext(Cell cell, String requestURIHos
//Take role information and if you have unit admin roll, promote to unit admin.
List roles = tca.getRoles();
- Role unitAdminRole = new Role(ROLE_UNIT_ADMIN, Box.DEFAULT_BOX_NAME, null, tca.getIssuer());
+ Role unitAdminRole = new Role(ROLE_UNIT_ADMIN, Box.MAIN_BOX_NAME, null, tca.getIssuer());
String unitAdminRoleUrl = unitAdminRole.createUrl();
- Role cellContentsReaderRole = new Role(ROLE_CELL_CONTENTS_READER, Box.DEFAULT_BOX_NAME,
+ Role cellContentsReaderRole = new Role(ROLE_CELL_CONTENTS_READER, Box.MAIN_BOX_NAME,
null, tca.getIssuer());
String cellContentsReaderUrl = cellContentsReaderRole.createUrl();
- Role cellContentsAdminRole = new Role(ROLE_CELL_CONTENTS_ADMIN, Box.DEFAULT_BOX_NAME,
+ Role cellContentsAdminRole = new Role(ROLE_CELL_CONTENTS_ADMIN, Box.MAIN_BOX_NAME,
null, tca.getIssuer());
String cellContentsAdminUrl = cellContentsAdminRole.createUrl();
@@ -944,4 +991,18 @@ private static AccessContext createAccessContext(Cell cell, String requestURIHos
}
}
+ /**
+ * Check if this access context has the cell level privilege.
+ * @param cellPriv
+ * @return
+ */
+ public boolean hasScopeCellPrivilege(CellPrivilege cellPriv) {
+ for (CellPrivilege scopePriv : this.scopePrivileges) {
+ if (scopePriv.includes(cellPriv)) {
+ return true;
+ }
+ }
+ // TODO scope role check
+ return false;
+ }
}
diff --git a/src/main/java/io/personium/core/auth/OAuth2Helper.java b/src/main/java/io/personium/core/auth/OAuth2Helper.java
index ee0cfd01c..6df344a1a 100644
--- a/src/main/java/io/personium/core/auth/OAuth2Helper.java
+++ b/src/main/java/io/personium/core/auth/OAuth2Helper.java
@@ -1,6 +1,7 @@
/**
- * personium.io
- * Copyright 2014 FUJITSU LIMITED
+ * Personium
+ * Copyright 2014-2019 Personium Project
+ * - FUJITSU LIMITED
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,26 +19,21 @@
import javax.xml.namespace.QName;
-import io.personium.common.utils.PersoniumCoreUtils;
+import io.personium.common.utils.CommonUtils;
/**
- * A utility around OAuth 2.
- * The OAuth 2.0 Authorization Protocol
- * http://tools.ietf.org/html/draft-ietf-oauth-v2-27
- * The OAuth 2.0 Authorization Protocol: Bearer Tokens
- * http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-19
- * OAuth SAML Assertion Profiles
- * http://tools.ietf.org/html/draft-ietf-oauth-saml2-bearer-12
+ * A utility around OAuth 2.0.
+ * RFC6749 The OAuth 2.0 Authorization Framework
+ * https://tools.ietf.org/html/rfc6749
+ * RFC6750 The OAuth 2.0 The OAuth 2.0 Authorization Framework: Bearer Token Usage
+ * https://tools.ietf.org/html/rfc6750
+ * RFC7522 SAML 2.0 Profile for OAuth 2.0 Client Authentication and Authorization Grants
+ * https://tools.ietf.org/html/rfc7522
*/
public final class OAuth2Helper {
private OAuth2Helper() {
}
- /**
- * Version of OAuth 2.
- */
- public static final String VERSION = "Draft 27";
-
/**
* URN representing SAML Assertion.
*/
@@ -180,6 +176,7 @@ public static class ResponseType {
public static class Scope {
/** openid. It is used with the openid connect of the oauth2 extension. */
public static final String OPENID = "openid";
+
}
/**
@@ -210,6 +207,18 @@ public static class Key {
* client_secret.
*/
public static final String CLIENT_SECRET = "client_secret";
+ /**
+ * "client_assertion" parameter key defined in RFC7521.
+ * https://tools.ietf.org/html/rfc7521#section-4.2
+ */
+ public static final String CLIENT_ASSERTION = "client_assertion";
+ /**
+ * "client_assertion_type" parameter key defined in RFC7521.
+ * https://tools.ietf.org/html/rfc7521#section-4.2
+ */
+ public static final String CLIENT_ASSERTION_TYPE = "client_assertion_type";
+
+
/**
* state.
*/
@@ -291,10 +300,15 @@ public static class Key {
* p_owner.
*/
public static final String OWNER = "p_owner";
+ /**
+ * p_cookie.
+ */
+ public static final String P_COOKIE = "p_cookie";
/**
* p_owner value.
*/
public static final String TRUE_STR = "true";
+
/**
* refresh_token_expires_in.
*/
@@ -323,12 +337,12 @@ public static class Key {
* ownerRepresentativeAccounts.
*/
public static final QName PROP_KEY_OWNER_REPRESENTIVE_ACCOUNTS =
- new QName(PersoniumCoreUtils.XmlConst.NS_PERSONIUM, "ownerRepresentativeAccounts");
+ new QName(CommonUtils.XmlConst.NS_PERSONIUM, "ownerRepresentativeAccounts");
/**
* ownerRepresentativeAccount.
*/
public static final QName PROP_KEY_OWNER_REPRESENTIVE_ACCOUNT =
- new QName(PersoniumCoreUtils.XmlConst.NS_PERSONIUM, "account");
+ new QName(CommonUtils.XmlConst.NS_PERSONIUM, "account");
}
/**
@@ -354,7 +368,7 @@ public static class SchemaLevel {
* @param value Target value
* @return true:match false:not match
*/
- public static boolean isMatchPermittedValue(String value) {
+ public static boolean isPermittedValue(String value) {
if (value == null
|| NONE.equals(value)
|| PUBLIC.equals(value)
diff --git a/src/main/java/io/personium/core/auth/ScopeArbitrator.java b/src/main/java/io/personium/core/auth/ScopeArbitrator.java
new file mode 100644
index 000000000..561449dda
--- /dev/null
+++ b/src/main/java/io/personium/core/auth/ScopeArbitrator.java
@@ -0,0 +1,119 @@
+package io.personium.core.auth;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import io.personium.common.auth.token.AbstractOAuth2Token;
+import io.personium.core.PersoniumUnitConfig;
+import io.personium.core.model.Box;
+import io.personium.core.model.Cell;
+import io.personium.core.utils.UriUtils;
+
+/**
+ * Class for scope arbitration object.
+ * Create an instance with Cell and Box information and grant_type string.
+ *
+ * With isROPC true:
+ * It is a cell admin mode. So any scope request will be admitted.
+ * if not request is made then default scope will be root.
+ *
+ * With isROPC false:
+ * Normal use cases.
+ * only scopes that are pre-granted to box will be admitted.
+ * i.e. Cell Level Privileges and Roles
+ * if no box exists then no scope will be granted.
+ *
+ * not implemented yet.
+ */
+public class ScopeArbitrator {
+ Cell cell;
+ Box box;
+ boolean isRopc;
+ String grantType;
+ Privilege unitMaxScopePrivilege;
+ Set requestedScopes = new HashSet<>();
+ List permittedScopes = new ArrayList();
+
+ static final Set VALID_NON_URL_SCOPES = new HashSet<>(Arrays.asList(new String[] {
+ OAuth2Helper.Scope.OPENID
+ }));
+ public ScopeArbitrator(Cell cell, Box box, String grantType) {
+ this.cell = cell;
+ this.box = box;
+ this.grantType = grantType;
+ String unitMaxScopeStr = null;
+ if (OAuth2Helper.GrantType.PASSWORD.equals(this.grantType)) {
+ unitMaxScopeStr = PersoniumUnitConfig.getTokenDefaultScopeRopc();
+ } else if (OAuth2Helper.GrantType.AUTHORIZATION_CODE.equals(this.grantType)) {
+ unitMaxScopeStr = PersoniumUnitConfig.getTokenDefaultScopeCode();
+ } else if (OAuth2Helper.GrantType.SAML2_BEARER.equals(this.grantType)) {
+ unitMaxScopeStr = PersoniumUnitConfig.getTokenDefaultScopeAssertion();
+ } else {
+ unitMaxScopeStr = PersoniumUnitConfig.getTokenDefaultScopeRopc();
+ }
+ this.unitMaxScopePrivilege = Privilege.get(CellPrivilege.class, unitMaxScopeStr);
+ }
+ public ScopeArbitrator requestString(String requestScopes) {
+ return this.request(AbstractOAuth2Token.Scope.parse(requestScopes));
+ }
+ public ScopeArbitrator request(String[] requestScopes) {
+ if (requestScopes != null) {
+ this.requestedScopes = new HashSet<>(Arrays.asList(requestScopes));
+ }
+ // remove empty entry
+ this.requestedScopes.remove("");
+ this.arbitrate();
+ return this;
+ }
+ private void arbitrate() {
+ if (this.requestedScopes.size() == 0 && this.unitMaxScopePrivilege != null) {
+ this.requestedScopes.add(this.unitMaxScopePrivilege.getName());
+ }
+ for (String scope : this.requestedScopes) {
+ if (this.check(scope)) {
+ this.permittedScopes.add(scope);
+ }
+ }
+ }
+ public String[] getResults() {
+ return this.permittedScopes.toArray(new String[0]);
+ }
+ private boolean check(String scope) {
+ //
+ if (VALID_NON_URL_SCOPES.contains(scope)) {
+ return true;
+ }
+ String resolvedScope = UriUtils.resolveLocalUnit(scope);
+ // If it looks like a role because it is a http URL.
+ if (resolvedScope.startsWith("http://") || resolvedScope.startsWith("https://")) {
+ // check if it is really a role or not
+ if (isRole(resolvedScope)) {
+ return true;
+ }
+ return false;
+ }
+
+ // If not, it should probably be Cell Privilege.
+ // make sure.
+ CellPrivilege cp = Privilege.get(CellPrivilege.class, scope);
+ if (cp == null) {
+ return false;
+ }
+ // Now Cell Level privilege can come here.
+ // if ROPC then allow any valid scopes.
+ if (this.unitMaxScopePrivilege != null && this.unitMaxScopePrivilege.includes(cp)) {
+ return true;
+ }
+ // if not then reject all .. (Tentatively)
+ // TODO implement Box configuration to allow Cell Level privilege, and refer to that
+ // setting.
+ return false;
+ }
+ private boolean isRole(String scope) {
+ String id = this.cell.roleResourceUrlToId(scope, PersoniumUnitConfig.getBaseUrl());
+ return id != null;
+ }
+}
diff --git a/src/main/java/io/personium/core/auth/hash/Sha256HashPasswordImpl.java b/src/main/java/io/personium/core/auth/hash/Sha256HashPasswordImpl.java
index 22114db1d..9165ec446 100644
--- a/src/main/java/io/personium/core/auth/hash/Sha256HashPasswordImpl.java
+++ b/src/main/java/io/personium/core/auth/hash/Sha256HashPasswordImpl.java
@@ -22,7 +22,7 @@
import org.apache.commons.lang.CharEncoding;
-import io.personium.common.utils.PersoniumCoreUtils;
+import io.personium.common.utils.CommonUtils;
import io.personium.core.PersoniumUnitConfig;
import io.personium.core.model.ctl.Account;
import io.personium.core.odata.OEntityWrapper;
@@ -59,7 +59,7 @@ public String createHashPassword(String passwd) {
MessageDigest md = MessageDigest.getInstance(HASH_ALGORITHM_NAME);
byte[] digestBytes = md.digest(str2hash.getBytes(CharEncoding.UTF_8));
//Although its data efficiency is better, this implementation is made for compatibility with DC 0.
- return PersoniumCoreUtils.byteArray2HexString(digestBytes);
+ return CommonUtils.byteArray2HexString(digestBytes);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (UnsupportedEncodingException e) {
diff --git a/src/main/java/io/personium/core/bar/BarFile.java b/src/main/java/io/personium/core/bar/BarFile.java
index 0fdeaf63b..1817ded98 100644
--- a/src/main/java/io/personium/core/bar/BarFile.java
+++ b/src/main/java/io/personium/core/bar/BarFile.java
@@ -38,7 +38,7 @@
import org.apache.commons.io.Charsets;
import org.apache.wink.webdav.model.Multistatus;
-import io.personium.common.utils.PersoniumCoreUtils;
+import io.personium.common.utils.CommonUtils;
import io.personium.core.PersoniumCoreException;
/**
@@ -47,7 +47,7 @@
public class BarFile implements Closeable {
/** Content-Type of bar file. */
- public static final String CONTENT_TYPE = PersoniumCoreUtils.ContentType.CONTENT_TYPE_BAR;
+ public static final String CONTENT_TYPE = CommonUtils.ContentType.CONTENT_TYPE_BAR;
/** Directory name : meta. */
private static final String META_DIR = "00_meta";
diff --git a/src/main/java/io/personium/core/bar/BarFileContentsInstallVisitor.java b/src/main/java/io/personium/core/bar/BarFileContentsInstallVisitor.java
index 862cb034a..71d5763ea 100644
--- a/src/main/java/io/personium/core/bar/BarFileContentsInstallVisitor.java
+++ b/src/main/java/io/personium/core/bar/BarFileContentsInstallVisitor.java
@@ -70,7 +70,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import io.personium.common.es.util.PersoniumUUID;
-import io.personium.common.utils.PersoniumCoreUtils;
+import io.personium.common.utils.CommonUtils;
import io.personium.core.PersoniumCoreException;
import io.personium.core.PersoniumCoreMessageUtils;
import io.personium.core.PersoniumUnitConfig;
@@ -1022,7 +1022,7 @@ private void registWebDavFile(String entryName, Path pathInZip) {
if (aclElement != null) {
StringBuffer sbAclXml = new StringBuffer();
sbAclXml.append("");
- sbAclXml.append(PersoniumCoreUtils.nodeToString(aclElement));
+ sbAclXml.append(CommonUtils.nodeToString(aclElement));
Reader aclXml = new StringReader(sbAclXml.toString());
fileCmp.acl(aclXml);
}
@@ -1051,7 +1051,7 @@ private Reader getProppatchXml(List propElements) {
sbPropXml.append("");
sbPropXml.append("");
for (Element element : propElements) {
- sbPropXml.append(PersoniumCoreUtils.nodeToString(element));
+ sbPropXml.append(CommonUtils.nodeToString(element));
}
sbPropXml.append("");
sbPropXml.append("");
diff --git a/src/main/java/io/personium/core/bar/BarFileInstallRunner.java b/src/main/java/io/personium/core/bar/BarFileInstallRunner.java
index efc179a98..945c8b218 100644
--- a/src/main/java/io/personium/core/bar/BarFileInstallRunner.java
+++ b/src/main/java/io/personium/core/bar/BarFileInstallRunner.java
@@ -51,8 +51,8 @@
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
-import io.personium.common.utils.PersoniumCoreUtils;
-import io.personium.common.utils.PersoniumCoreUtils.HttpMethod;
+import io.personium.common.utils.CommonUtils;
+import io.personium.common.utils.CommonUtils.HttpMethod;
import io.personium.core.PersoniumCoreException;
import io.personium.core.PersoniumCoreMessageUtils;
import io.personium.core.bar.jackson.IJSONMappedObjects;
@@ -740,7 +740,7 @@ private void registBoxAclAndProppatch(Box targetBox, Element aclElement,
if (aclElement != null) {
StringBuffer sbAclXml = new StringBuffer();
sbAclXml.append("");
- sbAclXml.append(PersoniumCoreUtils.nodeToString(aclElement));
+ sbAclXml.append(CommonUtils.nodeToString(aclElement));
Reader aclXml = new StringReader(sbAclXml.toString());
boxCmp.acl(aclXml);
}
@@ -769,7 +769,7 @@ private Reader getProppatchXml(List propElements) {
sbPropXml.append("");
sbPropXml.append("");
for (Element element : propElements) {
- sbPropXml.append(PersoniumCoreUtils.nodeToString(element));
+ sbPropXml.append(CommonUtils.nodeToString(element));
}
sbPropXml.append("");
sbPropXml.append("");
@@ -825,7 +825,7 @@ private void createCollection(String collectionUrl,
if (aclElement != null) {
StringBuffer sbAclXml = new StringBuffer();
sbAclXml.append("");
- sbAclXml.append(PersoniumCoreUtils.nodeToString(aclElement));
+ sbAclXml.append(CommonUtils.nodeToString(aclElement));
Reader aclXml = new StringReader(sbAclXml.toString());
collectionCmp.acl(aclXml);
}
diff --git a/src/main/java/io/personium/core/bar/BarFileInstaller.java b/src/main/java/io/personium/core/bar/BarFileInstaller.java
index 3dc413629..1528f5fa6 100644
--- a/src/main/java/io/personium/core/bar/BarFileInstaller.java
+++ b/src/main/java/io/personium/core/bar/BarFileInstaller.java
@@ -1,6 +1,6 @@
/**
- * personium.io
- * Copyright 2014 FUJITSU LIMITED
+ * Personium
+ * Copyright 2014-2019 FUJITSU LIMITED
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,7 +53,6 @@
import io.personium.common.utils.PersoniumThread;
import io.personium.core.PersoniumCoreException;
import io.personium.core.PersoniumUnitConfig;
-import io.personium.core.auth.AccessContext;
import io.personium.core.auth.CellPrivilege;
import io.personium.core.bar.jackson.JSONManifest;
import io.personium.core.model.Box;
@@ -239,13 +238,11 @@ private void removeBarFile(File barFile) {
*/
private void checkPreConditions(Map headers) {
//[403] Access control
- AccessContext accessContext = this.oDataEntityResource.getAccessContext();
ODataResource odataResource = this.oDataEntityResource.getOdataResource();
- odataResource.checkAccessContext(accessContext, CellPrivilege.BOX_BAR_INSTALL);
+ odataResource.checkAccessContext(CellPrivilege.BOX_BAR_INSTALL);
//[400] Request header format check
checkHeaders(headers);
-
}
/**
@@ -311,7 +308,7 @@ public void sync(FileDescriptor fd) throws SyncFailedException {
private File storeTemporaryBarFile(InputStream inStream) {
//If there is no directory to store the bar file, it creates it.
- String unitUserName = BarFileUtils.getUnitUserName(this.cell.getOwner());
+ String unitUserName = BarFileUtils.getUnitUserName(this.cell.getOwnerNormalized());
File barFileDir = new File(new File(barTempDir, unitUserName), "bar");
if (!barFileDir.exists() && !barFileDir.mkdirs()) {
String message = "unable create directory: " + barFileDir.getAbsolutePath();
diff --git a/src/main/java/io/personium/core/bar/BarFileReadRunner.java b/src/main/java/io/personium/core/bar/BarFileReadRunner.java
index b1041b740..b36dbddac 100644
--- a/src/main/java/io/personium/core/bar/BarFileReadRunner.java
+++ b/src/main/java/io/personium/core/bar/BarFileReadRunner.java
@@ -82,8 +82,8 @@
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
import io.personium.common.es.util.PersoniumUUID;
-import io.personium.common.utils.PersoniumCoreUtils;
-import io.personium.common.utils.PersoniumCoreUtils.HttpMethod;
+import io.personium.common.utils.CommonUtils;
+import io.personium.common.utils.CommonUtils.HttpMethod;
import io.personium.core.PersoniumCoreException;
import io.personium.core.PersoniumCoreMessageUtils;
import io.personium.core.PersoniumUnitConfig;
@@ -876,7 +876,7 @@ protected boolean registWebDavFile(String entryName, InputStream inputStream,
if (aclElement != null) {
StringBuffer sbAclXml = new StringBuffer();
sbAclXml.append("");
- sbAclXml.append(PersoniumCoreUtils.nodeToString(aclElement));
+ sbAclXml.append(CommonUtils.nodeToString(aclElement));
Reader aclXml = new StringReader(sbAclXml.toString());
fileCmp.acl(aclXml);
}
@@ -2111,7 +2111,7 @@ private void createCollection(String collectionUrl,
if (aclElement != null) {
StringBuffer sbAclXml = new StringBuffer();
sbAclXml.append("");
- sbAclXml.append(PersoniumCoreUtils.nodeToString(aclElement));
+ sbAclXml.append(CommonUtils.nodeToString(aclElement));
Reader aclXml = new StringReader(sbAclXml.toString());
collectionCmp.acl(aclXml);
}
@@ -2137,7 +2137,7 @@ private void registBoxAclAndProppatch(Box targetBox, Element aclElement,
if (aclElement != null) {
StringBuffer sbAclXml = new StringBuffer();
sbAclXml.append("");
- sbAclXml.append(PersoniumCoreUtils.nodeToString(aclElement));
+ sbAclXml.append(CommonUtils.nodeToString(aclElement));
Reader aclXml = new StringReader(sbAclXml.toString());
boxCmp.acl(aclXml);
}
@@ -2458,7 +2458,7 @@ private Reader getProppatchXml(List propElements) {
sbPropXml.append("");
sbPropXml.append("");
for (Element element : propElements) {
- sbPropXml.append(PersoniumCoreUtils.nodeToString(element));
+ sbPropXml.append(CommonUtils.nodeToString(element));
}
sbPropXml.append("");
sbPropXml.append("");
diff --git a/src/main/java/io/personium/core/eventlog/ArchiveLogCollection.java b/src/main/java/io/personium/core/eventlog/ArchiveLogCollection.java
index 472697c56..550888d47 100644
--- a/src/main/java/io/personium/core/eventlog/ArchiveLogCollection.java
+++ b/src/main/java/io/personium/core/eventlog/ArchiveLogCollection.java
@@ -70,7 +70,7 @@ public ArchiveLogCollection(Cell cell, UriInfo uriInfo) {
urlSb.append(uriInfo.getPath());
this.url = urlSb.toString();
- StringBuilder archiveDirName = EventUtils.getEventLogDir(cell.getId(), cell.getOwner()).append("archive");
+ StringBuilder archiveDirName = EventUtils.getEventLogDir(cell.getId(), cell.getOwnerNormalized()).append("archive");
this.directoryPath = archiveDirName.toString();
}
diff --git a/src/main/java/io/personium/core/jersey/filter/PersoniumCoreContainerFilter.java b/src/main/java/io/personium/core/jersey/filter/PersoniumCoreContainerFilter.java
index 31749b481..161f634d4 100644
--- a/src/main/java/io/personium/core/jersey/filter/PersoniumCoreContainerFilter.java
+++ b/src/main/java/io/personium/core/jersey/filter/PersoniumCoreContainerFilter.java
@@ -39,8 +39,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.personium.common.utils.PersoniumCoreUtils;
-import io.personium.common.utils.PersoniumCoreUtils.HttpHeaders;
+import io.personium.common.utils.CommonUtils;
+import io.personium.common.utils.CommonUtils.HttpHeaders;
import io.personium.core.PersoniumCoreException;
import io.personium.core.PersoniumReadDeleteModeManager;
import io.personium.core.PersoniumUnitConfig;
@@ -120,7 +120,7 @@ public void filter(ContainerRequestContext requestContext, ContainerResponseCont
private void overrideMethod(ContainerRequestContext requestContext) {
if (HttpMethod.POST.equalsIgnoreCase(requestContext.getMethod())) {
String overrideMethod = requestContext.getHeaders().getFirst(
- PersoniumCoreUtils.HttpHeaders.X_HTTP_METHOD_OVERRIDE);
+ CommonUtils.HttpHeaders.X_HTTP_METHOD_OVERRIDE);
if (overrideMethod != null && !overrideMethod.isEmpty()) {
requestContext.setMethod(overrideMethod);
}
@@ -128,7 +128,7 @@ private void overrideMethod(ContainerRequestContext requestContext) {
}
private void overrideHeaders(ContainerRequestContext requestContext) {
- List overrideHeaderList = requestContext.getHeaders().get(PersoniumCoreUtils.HttpHeaders.X_OVERRIDE);
+ List overrideHeaderList = requestContext.getHeaders().get(CommonUtils.HttpHeaders.X_OVERRIDE);
if (overrideHeaderList == null) {
return;
}
@@ -155,9 +155,9 @@ private void overrideHeaders(ContainerRequestContext requestContext) {
private void overrideUri(ContainerRequestContext requestContext) {
MultivaluedMap headers = requestContext.getHeaders();
- String xForwardedProto = headers.getFirst(PersoniumCoreUtils.HttpHeaders.X_FORWARDED_PROTO);
- String xForwardedHost = headers.getFirst(PersoniumCoreUtils.HttpHeaders.X_FORWARDED_HOST);
- String xForwardedPath = headers.getFirst(PersoniumCoreUtils.HttpHeaders.X_FORWARDED_PATH);
+ String xForwardedProto = headers.getFirst(CommonUtils.HttpHeaders.X_FORWARDED_PROTO);
+ String xForwardedHost = headers.getFirst(CommonUtils.HttpHeaders.X_FORWARDED_HOST);
+ String xForwardedPath = headers.getFirst(CommonUtils.HttpHeaders.X_FORWARDED_PATH);
UriInfo uriInfo = requestContext.getUriInfo();
UriBuilder baseUriBuilder = uriInfo.getBaseUriBuilder();
@@ -195,12 +195,12 @@ private void checkOptionsMethod(String method, MultivaluedMap he
HttpMethod.PUT,
HttpMethod.DELETE,
HttpMethod.HEAD,
- io.personium.common.utils.PersoniumCoreUtils.HttpMethod.MERGE,
- io.personium.common.utils.PersoniumCoreUtils.HttpMethod.MKCOL,
- io.personium.common.utils.PersoniumCoreUtils.HttpMethod.MOVE,
- io.personium.common.utils.PersoniumCoreUtils.HttpMethod.PROPFIND,
- io.personium.common.utils.PersoniumCoreUtils.HttpMethod.PROPPATCH,
- io.personium.common.utils.PersoniumCoreUtils.HttpMethod.ACL
+ io.personium.common.utils.CommonUtils.HttpMethod.MERGE,
+ io.personium.common.utils.CommonUtils.HttpMethod.MKCOL,
+ io.personium.common.utils.CommonUtils.HttpMethod.MOVE,
+ io.personium.common.utils.CommonUtils.HttpMethod.PROPFIND,
+ io.personium.common.utils.CommonUtils.HttpMethod.PROPPATCH,
+ io.personium.common.utils.CommonUtils.HttpMethod.ACL
).build();
//Do not pass control to the servlet by issuing an exception
diff --git a/src/main/java/io/personium/core/model/Box.java b/src/main/java/io/personium/core/model/Box.java
index add269f07..131e5113d 100644
--- a/src/main/java/io/personium/core/model/Box.java
+++ b/src/main/java/io/personium/core/model/Box.java
@@ -93,7 +93,7 @@ private static List> createSchemaAnnotation(final String name)
/**
* main box name.
*/
- public static final String DEFAULT_BOX_NAME = "__";
+ public static final String MAIN_BOX_NAME = "__";
/**
* Constructor.
@@ -104,7 +104,7 @@ public Box(final Cell cell, final OEntity entity) {
this.cell = cell;
if (entity == null) {
// Process for the MAIN BOX
- this.name = Box.DEFAULT_BOX_NAME;
+ this.name = Box.MAIN_BOX_NAME;
// Schema URL of MAIN BOX is the URL of its own cell
this.schema = cell.getUrl();
// Internal ID of MAIN BOX will be together with the ID of the cell.
diff --git a/src/main/java/io/personium/core/model/BoxUrlRsCmp.java b/src/main/java/io/personium/core/model/BoxUrlRsCmp.java
index 17dd63447..04389e135 100644
--- a/src/main/java/io/personium/core/model/BoxUrlRsCmp.java
+++ b/src/main/java/io/personium/core/model/BoxUrlRsCmp.java
@@ -43,9 +43,11 @@ public BoxUrlRsCmp(final CellRsCmp cellRsCmp, final DavCmp davCmp,
* {@inheritDoc}
*/
@Override
- public void checkAccessContext(AccessContext ac, Privilege privilege) {
+ public void checkAccessContext(Privilege privilege) {
AcceptableAuthScheme allowedAuthScheme = getAcceptableAuthScheme();
+ AccessContext ac = this.getAccessContext();
+
// For unit user token, do not check
if (ac.isUnitUserToken(privilege)) {
return;
@@ -63,7 +65,7 @@ public void checkAccessContext(AccessContext ac, Privilege privilege) {
ac.updateBasicAuthenticationStateForResource(null);
// Check access control.
- if (!this.hasPrivilege(ac, privilege)) {
+ if (!this.hasSubjectPrivilege(privilege)) {
// If the token is INVALID or Privilege is set to all it is necessary to grant access.
// For this reason, check the validity of the token at this timing.
if (AccessContext.TYPE_INVALID.equals(ac.getType())) {
diff --git a/src/main/java/io/personium/core/model/Cell.java b/src/main/java/io/personium/core/model/Cell.java
index 3dc7fa1fc..a10a8e108 100644
--- a/src/main/java/io/personium/core/model/Cell.java
+++ b/src/main/java/io/personium/core/model/Cell.java
@@ -16,191 +16,377 @@
*/
package io.personium.core.model;
+import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.core4j.Enumerable;
+import org.odata4j.core.OEntity;
+import org.odata4j.core.OEntityKey;
import org.odata4j.edm.EdmEntityType;
import org.odata4j.edm.EdmProperty;
import org.odata4j.edm.EdmSimpleType;
+import org.odata4j.expression.BoolCommonExpression;
+import org.odata4j.producer.EntitiesResponse;
+import org.odata4j.producer.EntityResponse;
+import org.odata4j.producer.InlineCount;
+import org.odata4j.producer.ODataProducer;
+import org.odata4j.producer.QueryInfo;
+import org.odata4j.producer.resources.OptionsQueryParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import io.personium.common.auth.token.IExtRoleContainingToken;
import io.personium.common.auth.token.Role;
+import io.personium.core.PersoniumCoreException;
+import io.personium.core.PersoniumUnitConfig;
+import io.personium.core.auth.AuthUtils;
+import io.personium.core.auth.ScopeArbitrator;
import io.personium.core.event.EventBus;
+import io.personium.core.model.ctl.Account;
import io.personium.core.model.ctl.Common;
+import io.personium.core.model.ctl.ExtCell;
+import io.personium.core.model.ctl.ExtRole;
+import io.personium.core.model.ctl.ReceivedMessage;
+import io.personium.core.model.ctl.Relation;
+import io.personium.core.model.ctl.Rule;
+import io.personium.core.model.ctl.SentMessage;
+import io.personium.core.model.impl.es.cache.BoxCache;
+import io.personium.core.model.impl.es.odata.CellCtlODataProducer;
+import io.personium.core.model.jaxb.Acl;
import io.personium.core.odata.OEntityWrapper;
+import io.personium.core.utils.UriUtils;
+import net.spy.memcached.internal.CheckedOperationTimeoutException;
/**
* Model Class for Cell.
*/
-public interface Cell {
+public abstract class Cell {
+ /** logger. */
+ static Logger log = LoggerFactory.getLogger(Cell.class);
+
/** Edm.Entity Type Name. */
- String EDM_TYPE_NAME = "Cell";
+ public static String EDM_TYPE_NAME = "Cell";
/** Status normal. */
- String STATUS_NORMAL = "normal";
+ public static String STATUS_NORMAL = "normal";
/** Status import error. */
- String STATUS_IMPORT_ERROR = "import failed";
+ public static String STATUS_IMPORT_ERROR = "import failed";
/** Error file name. */
- String IMPORT_ERROR_FILE_NAME = "import.error";
+ public static String IMPORT_ERROR_FILE_NAME = "import.error";
/** Definition field of Name property. */
- EdmProperty.Builder P_NAME = EdmProperty.newBuilder("Name").setType(EdmSimpleType.STRING)
+ public static EdmProperty.Builder P_NAME = EdmProperty.newBuilder("Name").setType(EdmSimpleType.STRING)
.setNullable(false).setAnnotations(Common.P_FORMAT_CELL_NAME);
/** Property List. */
- List PROPS = Collections.unmodifiableList(Arrays.asList(
+ public static List PROPS = Collections.unmodifiableList(Arrays.asList(
new EdmProperty.Builder[] {P_NAME, Common.P_PUBLISHED, Common.P_UPDATED}
));
/** Key List. */
- List KEYS = Collections.unmodifiableList(Arrays.asList(
+ public static List KEYS = Collections.unmodifiableList(Arrays.asList(
new String[] {P_NAME.getName()}
));;
/** EntityType Builder of the Cell. */
- EdmEntityType.Builder EDM_TYPE_BUILDER = EdmEntityType.newBuilder().setNamespace(Common.EDM_NS_UNIT_CTL)
+ public static EdmEntityType.Builder EDM_TYPE_BUILDER = EdmEntityType.newBuilder().setNamespace(Common.EDM_NS_UNIT_CTL)
.setName(EDM_TYPE_NAME).addProperties(Enumerable.create(PROPS).toList()).addKeys(KEYS);
+ protected String id;
+ protected String name;
+ protected String url; // Note: path base
+ protected String owner;
+ protected Long published;
+
/**
- * returns Cell name.
- * @return Cell name
+ * returns the Cell name.
+ * @return Cell Name
*/
- String getName();
+ public String getName() {
+ return name;
+ }
/**
- * returns internal ID string.
- * @return internal ID string
+ * Returns the internal ID of this Cell.
+ * @return internal identity string
*/
- String getId();
+ public String getId() {
+ return this.id;
+ }
+
/**
* returns URL string for this cell.
* Return PathBaseURL or FQDNBaseURL depending on property setting.
* @return URL string
*/
- String getUrl();
+ public String getUrl() {
+ if (PersoniumUnitConfig.isPathBasedCellUrlEnabled()) {
+ return this.url;
+ } else {
+ return getFqdnBaseUrl();
+ }
+ }
/**
* returns Cell base URL string for this cell.
* Cell base url : "https://{cellname}.{domain}/".
* @return Cell base URL string
*/
- String getFqdnBaseUrl();
+ public String getFqdnBaseUrl() {
+ try {
+ return UriUtils.convertPathBaseToFqdnBase(url);
+ } catch (URISyntaxException e) {
+ // Usually it does not occur.
+ throw PersoniumCoreException.Server.UNKNOWN_ERROR.reason(e);
+ }
+ }
+
+
/**
* returns Cell base URL string for this cell.
* Cell base url : "https://{domain}/{cellname}/".
* @return Cell base URL string
*/
- String getPathBaseUrl();
+ public String getPathBaseUrl() {
+ return url;
+ }
/**
* returns Unit URL string for this cell.
* @return Unit URL string
*/
- String getUnitUrl();
+ public String getUnitUrl() {
+ return PersoniumUnitConfig.getBaseUrl();
+ }
+ /**
+ * Returns the normalized URI of the owner Unit User of this Cell.
+ * @return normalized owner url.
+ */
+ public String getOwnerNormalized() {
+ return UriUtils.convertSchemeFromLocalUnitToHttp(this.owner);
+ }
/**
- * It gets the URI of the Cell of the Owner Unit User.
- * @return Cell name
+ * Returns the raw URI of the owner Unit User of this Cell.
+ * @return raw owner url.
*/
- String getOwner();
+ public String getOwnerRaw() {
+ return this.owner;
+ }
/**
- * It gets the prefix without Unit User name of the Cell.
+ * Returns the prefix without Unit User name of the Cell.
* @return .
*/
- String getDataBundleNameWithOutPrefix();
+ public abstract String getDataBundleNameWithOutPrefix();
/**
- * It gets the Unit User name of the Cell.
+ * Returns the Unit User name of the Cell.
* @return Unit User name
*/
- String getDataBundleName();
+ public abstract String getDataBundleName();
/**
- * It gets the EventBus of the Cell.
+ * Returns the EventBus of the Cell.
* @return EventBus
*/
- EventBus getEventBus();
+ public EventBus getEventBus() {
+ return new EventBus(this);
+ }
/**
- * It gets the Cell of creation time.
+ * Return the creation time of Cell.
* @return time stamp of this cell creation.
*/
- long getPublished();
-
+ public long getPublished() {
+ return this.published;
+ }
/**
* Data and control objects under (Box, Account, etc.) if there is no return true..
* The default box may be.
* @return It is true if there is no data and control objects under
* (Box, Account, etc.).
*/
- boolean isEmpty();
+ public boolean isEmpty() {
+ CellCtlODataProducer producer = new CellCtlODataProducer(this);
+ // check no box exists.
+ QueryInfo queryInfo = new QueryInfo(InlineCount.ALLPAGES, null, null, null, null, null, null, null, null);
+ if (producer.getEntitiesCount(Box.EDM_TYPE_NAME, queryInfo).getCount() > 0) {
+ return false;
+ }
+
+ // check that Main Box is empty
+ Box defaultBox = this.getBoxForName(Box.MAIN_BOX_NAME);
+ BoxCmp defaultBoxCmp = ModelFactory.boxCmp(defaultBox);
+ if (!defaultBoxCmp.isEmpty()) {
+ return false;
+ }
+
+ // check that no Cell Control Object exists
+ //In order to improve the TODO performance, change the type so as to check the value of c: (uuid of the cell) in the Type traversal
+ if (producer.getEntitiesCount(Account.EDM_TYPE_NAME, queryInfo).getCount() > 0
+ || producer.getEntitiesCount(Role.EDM_TYPE_NAME, queryInfo).getCount() > 0
+ || producer.getEntitiesCount(ExtCell.EDM_TYPE_NAME, queryInfo).getCount() > 0
+ || producer.getEntitiesCount(ExtRole.EDM_TYPE_NAME, queryInfo).getCount() > 0
+ || producer.getEntitiesCount(Relation.EDM_TYPE_NAME, queryInfo).getCount() > 0
+ || producer.getEntitiesCount(SentMessage.EDM_TYPE_NAME, queryInfo).getCount() > 0
+ || producer.getEntitiesCount(ReceivedMessage.EDM_TYPE_NAME, queryInfo).getCount() > 0
+ || producer.getEntitiesCount(Rule.EDM_TYPE_NAME, queryInfo).getCount() > 0) {
+ return false;
+ }
+ // TODO check EventLog
+ return true;
+ }
/**
* To delete all the data and control objects in the underlying
* (Box, Account, etc.).
*/
- void makeEmpty();
+ public abstract void makeEmpty();
/**
* delete this cell.
* @param recursive set true if you want to delete recursively
* @param unitUserName to use for deletion operation
*/
- void delete(boolean recursive, String unitUserName);
+ public abstract void delete(boolean recursive, String unitUserName);
/**
* Specify the Box name to get the Box.
* @param boxName Box name
* @return Box
*/
- Box getBoxForName(String boxName);
+ public Box getBoxForName(String boxName) {
+ if (Box.MAIN_BOX_NAME.equals(boxName)) {
+ return new Box(this, null);
+ }
+
+ //Check the format of the Box name specified in URl. In case of invalid Because none of Box exists, return null
+ if (!validatePropertyRegEx(boxName, Common.PATTERN_NAME)) {
+ return null;
+ }
+ //Attempt to acquire the cached Box.
+ Box cachedBox = BoxCache.get(boxName, this);
+ if (cachedBox != null) {
+ return cachedBox;
+ }
+
+ Box loadedBox = null;
+ try {
+ ODataProducer op = ModelFactory.ODataCtl.cellCtl(this);
+ EntityResponse er = op.getEntity(Box.EDM_TYPE_NAME, OEntityKey.create(boxName), null);
+ loadedBox = new Box(this, er.getEntity());
+ BoxCache.cache(loadedBox);
+ return loadedBox;
+ } catch (RuntimeException e) {
+ if (e.getCause() instanceof CheckedOperationTimeoutException) {
+ return loadedBox;
+ } else {
+ return null;
+ }
+ }
+ }
+ /**
+ * Check the value of property item with regular expression.
+ * @param propValue
+ * Property value
+ * @param dcFormat
+ * Value of dcFormat
+ * @return In case of format error, return false
+ */
+ protected static boolean validatePropertyRegEx(String propValue, String dcFormat) {
+ //Perform format check
+ Pattern pattern = Pattern.compile(dcFormat);
+ Matcher matcher = pattern.matcher(propValue);
+ if (!matcher.matches()) {
+ return false;
+ }
+ return true;
+ }
/**
* Specify the Box schema to get the Box.
* @param boxSchema box schema uri
* @return Box
*/
- Box getBoxForSchema(String boxSchema);
-
+ public Box getBoxForSchema(String boxSchema) {
+ //Retrieving the schema name list (including aliases)
+ List boxSchemas = UriUtils.getUrlVariations(boxSchema);
+
+ ODataProducer op = ModelFactory.ODataCtl.cellCtl(this);
+ for (int i = 0; i < boxSchemas.size(); i++) {
+ BoolCommonExpression filter = OptionsQueryParser.parseFilter("Schema eq '" + boxSchemas.get(i) + "'");
+ QueryInfo qi = QueryInfo.newBuilder().setFilter(filter).build();
+ try {
+ EntitiesResponse er = op.getEntities(Box.EDM_TYPE_NAME, qi);
+ List entList = er.getEntities();
+ if (entList.size() == 1) {
+ return new Box(this, entList.get(0));
+ }
+ continue;
+ } catch (RuntimeException e) {
+ return null;
+ }
+ }
+ return null;
+ }
+
+
+ public ScopeArbitrator getScopeArbitrator(String clientId, String grantType) {
+ Box box = this.getBoxForSchema(clientId);
+ return new ScopeArbitrator(this, box, grantType);
+ }
/**
* It gets the Accounts to specify the Account name.
* @param username Account name
* @return Account
*/
- OEntityWrapper getAccount(String username);
-
+ public OEntityWrapper getAccount(final String username) {
+ ODataProducer op = ModelFactory.ODataCtl.cellCtl(this);
+ OEntityKey key = OEntityKey.create(username);
+ OEntityWrapper oew = null;
+ try {
+ EntityResponse resp = op.getEntity("Account", key, null);
+ oew = (OEntityWrapper) resp.getEntity();
+ } catch (PersoniumCoreException dce) {
+ log.debug(dce.getMessage());
+ }
+ return oew;
+ }
/**
* @param oew account
* @param password password
* @return true if authentication is successful.
*/
- boolean authenticateAccount(OEntityWrapper oew, String password);
-
+ public boolean authenticateAccount(final OEntityWrapper oew, final String password) {
+ return AuthUtils.isMatchePassword(oew, password);
+ }
/**
* @param username access account id
* @return List of Roles
*/
- List getRoleListForAccount(String username);
+ public abstract List getRoleListForAccount(String username);
/**
* Returns a list of roles should be given in this cell.
* @param token Transformer cell access token
* @return Role List
*/
- List getRoleListHere(IExtRoleContainingToken token);
+ public abstract List getRoleListHere(IExtRoleContainingToken token);
/**
* convert role internal id to role resource URL.
* @param roleId internal id of a role.
* @return URL string
*/
- String roleIdToRoleResourceUrl(String roleId);
+ public abstract String roleIdToRoleResourceUrl(String roleId);
/**
* convert role resource url to its internal id.
@@ -208,5 +394,14 @@ public interface Cell {
* @param baseUrl Base Url
* @return internal id of the given role
*/
- String roleResourceUrlToId(String roleUrl, String baseUrl);
+ public abstract String roleResourceUrlToId(String roleUrl, String baseUrl);
+
+ /**
+ * @return Cell Level ACL
+ */
+ public Acl getAcl() {
+ CellCmp cc = ModelFactory.cellCmp(this);
+ return cc.getAcl();
+ }
+
}
diff --git a/src/main/java/io/personium/core/model/CellRsCmp.java b/src/main/java/io/personium/core/model/CellRsCmp.java
index 591b0135a..d09d998ae 100644
--- a/src/main/java/io/personium/core/model/CellRsCmp.java
+++ b/src/main/java/io/personium/core/model/CellRsCmp.java
@@ -1,6 +1,6 @@
/**
- * personium.io
- * Copyright 2014-2018 FUJITSU LIMITED
+ * Personium
+ * Copyright 2014-2019 FUJITSU LIMITED
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,6 +42,7 @@
import io.personium.core.PersoniumCoreException;
import io.personium.core.PersoniumUnitConfig;
import io.personium.core.auth.AccessContext;
+import io.personium.core.auth.CellPrivilege;
import io.personium.core.auth.OAuth2Helper.AcceptableAuthScheme;
import io.personium.core.auth.Privilege;
import io.personium.core.utils.HttpClientFactory;
@@ -128,6 +129,7 @@ public Box getBox() {
/**
* @return AccessContext
*/
+ @Override
public AccessContext getAccessContext() {
return this.accessContext;
}
@@ -138,11 +140,13 @@ public AccessContext getAccessContext() {
* @param privilege Privilege of ACL (read or write)
* @return boolean
*/
- public boolean hasPrivilege(AccessContext ac, Privilege privilege) {
+ @Override
+ public boolean hasSubjectPrivilege(Privilege privilege) {
- //If davCmp does not exist (resource that does not exist is specified) skip ACL check for that resource
+ // If davCmp does not exist (resource that does not exist is specified)
+ // skip ACL check for that resource
if (this.davCmp != null
- && this.getAccessContext().requirePrivilege(this.davCmp.getAcl(), privilege, this.getCell().getUrl())) {
+ && this.getAccessContext().hasSubjectPrivilegeForAcl(this.davCmp.getAcl(), privilege)) {
return true;
}
return false;
@@ -153,8 +157,10 @@ public boolean hasPrivilege(AccessContext ac, Privilege privilege) {
* @param ac Access context
* @param privilege Required privilege
*/
- public void checkAccessContext(AccessContext ac, Privilege privilege) {
- // Check UnitUser token.
+ @Override
+ public void checkAccessContext(Privilege privilege) {
+ AccessContext ac = this.getAccessContext();
+ // If UnitUser token, then OK.
if (ac.isUnitUserToken(privilege)) {
return;
}
@@ -163,9 +169,10 @@ public void checkAccessContext(AccessContext ac, Privilege privilege) {
this.accessContext.updateBasicAuthenticationStateForResource(null);
//Access right check
- if (!this.hasPrivilege(ac, privilege)) {
+ if (!this.hasSubjectPrivilege(privilege)) {
//Check the validity of the token
- //Even if the token is INVALID, if the ACL setting and Privilege is set to all, it is necessary to permit access, so check at this timing
+ // Even if the token is INVALID, if the ACL setting and Privilege is set to all,
+ // it is necessary to permit access, so check at this timing
if (AccessContext.TYPE_INVALID.equals(ac.getType())) {
ac.throwInvalidTokenException(getAcceptableAuthScheme());
} else if (AccessContext.TYPE_ANONYMOUS.equals(ac.getType())) {
@@ -174,6 +181,11 @@ public void checkAccessContext(AccessContext ac, Privilege privilege) {
}
throw PersoniumCoreException.Auth.NECESSARY_PRIVILEGE_LACKING;
}
+
+ if (privilege instanceof CellPrivilege
+ && !this.accessContext.hasScopeCellPrivilege((CellPrivilege)privilege)) {
+ throw PersoniumCoreException.Auth.INSUFFICIENT_SCOPE.params(privilege.getName());
+ }
}
/**
@@ -217,7 +229,7 @@ public HttpResponse requestGetRelayHtml() {
}
// Convert personium-localunit and personium-localcell.
- relayHtmlUrl = UriUtils.convertSchemeFromLocalUnitToHttp(cell.getUnitUrl(), relayHtmlUrl);
+ relayHtmlUrl = UriUtils.convertSchemeFromLocalUnitToHttp(relayHtmlUrl);
relayHtmlUrl = UriUtils.convertSchemeFromLocalCellToHttp(cell.getUrl(), relayHtmlUrl);
// Validate relayHtmlUrl.
@@ -245,7 +257,7 @@ public HttpResponse requestGetAuthorizationHtml() {
}
// Convert personium-localunit and personium-localcell.
- authorizationHtmlUrl = UriUtils.convertSchemeFromLocalUnitToHttp(cell.getUnitUrl(), authorizationHtmlUrl);
+ authorizationHtmlUrl = UriUtils.convertSchemeFromLocalUnitToHttp(authorizationHtmlUrl);
authorizationHtmlUrl = UriUtils.convertSchemeFromLocalCellToHttp(cell.getUrl(), authorizationHtmlUrl);
// Validate relayHtmlUrl.
@@ -274,8 +286,7 @@ public HttpResponse requestGetAuthorizationPasswordChangeHtml() {
}
// Convert personium-localunit and personium-localcell.
- authorizationPasswordHtmlUrl = UriUtils.convertSchemeFromLocalUnitToHttp(cell.getUnitUrl(),
- authorizationPasswordHtmlUrl);
+ authorizationPasswordHtmlUrl = UriUtils.convertSchemeFromLocalUnitToHttp(authorizationPasswordHtmlUrl);
authorizationPasswordHtmlUrl = UriUtils.convertSchemeFromLocalCellToHttp(cell.getUrl(),
authorizationPasswordHtmlUrl);
@@ -356,6 +367,23 @@ public List getAccountsNotRecordingAuthHistory() {
return Arrays.asList(accounts);
}
+ /**
+ * Check if the target account records authentication history.
+ * @param accountId account ID
+ * @param accountName account name
+ * @return "true" is records authentication history
+ */
+ public boolean isRecordingAuthHistory(String accountId, String accountName) {
+ if (StringUtils.isEmpty(accountId) || StringUtils.isEmpty(accountName)) {
+ return false;
+ }
+ List ineligibleAccountList = this.getAccountsNotRecordingAuthHistory();
+ if (ineligibleAccountList == null) {
+ return true;
+ }
+ return !ineligibleAccountList.contains(accountName);
+ }
+
/**
* Obtain Auth Scheme that can be used for authentication.
* Autret Scheme that can be used for @return authentication
diff --git a/src/main/java/io/personium/core/model/DavRsCmp.java b/src/main/java/io/personium/core/model/DavRsCmp.java
index ad6e0e70b..30db420b8 100644
--- a/src/main/java/io/personium/core/model/DavRsCmp.java
+++ b/src/main/java/io/personium/core/model/DavRsCmp.java
@@ -57,8 +57,7 @@
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import io.personium.common.auth.token.Role;
-import io.personium.common.utils.PersoniumCoreUtils;
+import io.personium.common.utils.CommonUtils;
import io.personium.core.PersoniumCoreAuthzException;
import io.personium.core.PersoniumCoreException;
import io.personium.core.auth.AccessContext;
@@ -235,7 +234,7 @@ public final Response doPropfind(final Reader requestBodyXml, final String depth
// ACL config output is allowed by Unit User or when ACL Privilege is configured.
boolean canAclRead = false;
if (this.getAccessContext().isUnitUserToken(requiredForReadAcl)
- || this.hasPrivilege(this.getAccessContext(), requiredForReadAcl)) {
+ || this.hasSubjectPrivilege(requiredForReadAcl)) {
canAclRead = true;
}
@@ -381,8 +380,8 @@ public String getConfidentialLevel() {
* @param privilege ACL Privilege (read/write/bind/unbind)
* @return boolean
*/
- public boolean hasPrivilege(AccessContext ac, Privilege privilege) {
- return hasPrivilege(ac, privilege, privilege);
+ public boolean hasSubjectPrivilege(Privilege privilege) {
+ return hasSubjectPrivilege( privilege, privilege);
}
/**
@@ -392,16 +391,17 @@ public boolean hasPrivilege(AccessContext ac, Privilege privilege) {
* @param parentPrivilege parent ACL Privilege (read/write/bind/unbind) If it is null, it does not refer to the parent's authority.
* @return boolean
*/
- public boolean hasPrivilege(AccessContext ac, Privilege privilege, Privilege parentPrivilege) {
+ public boolean hasSubjectPrivilege(Privilege privilege, Privilege parentPrivilege) {
// skip ACL check if davCmp does not exist.
// (nonexistent resource is specified)
if (privilege != null && this.davCmp != null
- && this.getAccessContext().requirePrivilege(this.davCmp.getAcl(), privilege, this.getCell().getUrl())) {
+ && this.getAccessContext().hasSubjectPrivilegeForAcl(this.davCmp.getAcl(), privilege)) {
return true;
}
// check parent (recursively)
- if (parentPrivilege != null && this.parent != null && this.parent.hasPrivilege(ac, parentPrivilege)) {
+ if (parentPrivilege != null && this.parent != null
+ && this.parent.hasSubjectPrivilege(parentPrivilege)) {
return true;
}
@@ -415,16 +415,16 @@ public boolean hasPrivilege(AccessContext ac, Privilege privilege, Privilege par
@OPTIONS
public Response options() {
// AccessControl
- this.checkAccessContext(this.getAccessContext(), BoxPrivilege.READ);
+ this.checkAccessContext(BoxPrivilege.READ);
return ResourceUtils.responseBuilderForOptions(
HttpMethod.GET,
HttpMethod.PUT,
HttpMethod.DELETE,
- io.personium.common.utils.PersoniumCoreUtils.HttpMethod.MKCOL,
- io.personium.common.utils.PersoniumCoreUtils.HttpMethod.PROPFIND,
- io.personium.common.utils.PersoniumCoreUtils.HttpMethod.PROPPATCH,
- io.personium.common.utils.PersoniumCoreUtils.HttpMethod.ACL
+ io.personium.common.utils.CommonUtils.HttpMethod.MKCOL,
+ io.personium.common.utils.CommonUtils.HttpMethod.PROPFIND,
+ io.personium.common.utils.CommonUtils.HttpMethod.PROPPATCH,
+ io.personium.common.utils.CommonUtils.HttpMethod.ACL
).build();
}
@@ -434,8 +434,8 @@ public Response options() {
* @param ac AccessContext
* @param privilege Privilege to check if it is given
*/
- public void checkAccessContext(final AccessContext ac, Privilege privilege) {
- checkAccessContext(ac, privilege, privilege);
+ public void checkAccessContext(Privilege privilege) {
+ checkAccessContext(privilege, privilege);
}
/**
@@ -445,7 +445,8 @@ public void checkAccessContext(final AccessContext ac, Privilege privilege) {
* @param privilege Privilege to check if it is given
* @param parentPrivilege parent ACL Privilege
*/
- public void checkAccessContext(final AccessContext ac, Privilege privilege, Privilege parentPrivilege) {
+ public void checkAccessContext(Privilege privilege, Privilege parentPrivilege) {
+ AccessContext ac = this.getAccessContext();
// if accessed with valid UnitUserToken then fine.
if (ac.isUnitUserToken(privilege)) {
return;
@@ -466,7 +467,7 @@ public void checkAccessContext(final AccessContext ac, Privilege privilege, Priv
ac.updateBasicAuthenticationStateForResource(this.getBox());
// check Access Privilege
- if (!this.hasPrivilege(ac, privilege, parentPrivilege)) {
+ if (!this.hasSubjectPrivilege(privilege, parentPrivilege)) {
// check token validity
// check here because access should be allowed when Privilege "all" is configured
// even if the token is invalid
@@ -488,7 +489,7 @@ public AcceptableAuthScheme getAcceptableAuthScheme() {
// check if this resource if under a box with Schema URL
String boxSchema = this.getBox().getSchema();
// only Bearer scheme is allowed if Box Schema URL is defined
- if (boxSchema != null && boxSchema.length() > 0 && !Role.DEFAULT_BOX_NAME.equals(this.getBox().getName())) {
+ if (boxSchema != null && boxSchema.length() > 0 && !Box.MAIN_BOX_NAME.equals(this.getBox().getName())) {
allowedAuthScheme = AcceptableAuthScheme.BEARER;
}
return allowedAuthScheme;
@@ -591,8 +592,8 @@ static final org.apache.wink.webdav.model.Response createDavResponse(final Strin
Resourcetype colRt = of.createResourcetype();
colRt.setCollection(of.createCollection());
List listElement = colRt.getAny();
- QName qname = new QName(PersoniumCoreUtils.XmlConst.NS_PERSONIUM, PersoniumCoreUtils.XmlConst.ODATA,
- PersoniumCoreUtils.XmlConst.NS_PREFIX_PERSONIUM);
+ QName qname = new QName(CommonUtils.XmlConst.NS_PERSONIUM, CommonUtils.XmlConst.ODATA,
+ CommonUtils.XmlConst.NS_PREFIX_PERSONIUM);
Element element = WebDAVModelHelper.createElement(qname);
listElement.add(element);
ret.setPropertyOk(colRt);
@@ -602,8 +603,8 @@ static final org.apache.wink.webdav.model.Response createDavResponse(final Strin
Resourcetype colRt = of.createResourcetype();
colRt.setCollection(of.createCollection());
List listElement = colRt.getAny();
- QName qname = new QName(PersoniumCoreUtils.XmlConst.NS_PERSONIUM, PersoniumCoreUtils.XmlConst.SERVICE,
- PersoniumCoreUtils.XmlConst.NS_PREFIX_PERSONIUM);
+ QName qname = new QName(CommonUtils.XmlConst.NS_PERSONIUM, CommonUtils.XmlConst.SERVICE,
+ CommonUtils.XmlConst.NS_PREFIX_PERSONIUM);
Element element = WebDAVModelHelper.createElement(qname);
listElement.add(element);
ret.setPropertyOk(colRt);
@@ -613,8 +614,8 @@ static final org.apache.wink.webdav.model.Response createDavResponse(final Strin
Resourcetype colRt = of.createResourcetype();
colRt.setCollection(of.createCollection());
List listElement = colRt.getAny();
- QName qname = new QName(PersoniumCoreUtils.XmlConst.NS_PERSONIUM, PersoniumCoreUtils.XmlConst.STREAM,
- PersoniumCoreUtils.XmlConst.NS_PREFIX_PERSONIUM);
+ QName qname = new QName(CommonUtils.XmlConst.NS_PERSONIUM, CommonUtils.XmlConst.STREAM,
+ CommonUtils.XmlConst.NS_PREFIX_PERSONIUM);
Element element = WebDAVModelHelper.createElement(qname);
listElement.add(element);
ret.setPropertyOk(colRt);
@@ -626,8 +627,8 @@ static final org.apache.wink.webdav.model.Response createDavResponse(final Strin
ret.setPropertyOk(colRt);
// Add cellstatus.
- QName qname = new QName(PersoniumCoreUtils.XmlConst.NS_PERSONIUM, PersoniumCoreUtils.XmlConst.CELL_STATUS,
- PersoniumCoreUtils.XmlConst.NS_PREFIX_PERSONIUM);
+ QName qname = new QName(CommonUtils.XmlConst.NS_PERSONIUM, CommonUtils.XmlConst.CELL_STATUS,
+ CommonUtils.XmlConst.NS_PREFIX_PERSONIUM);
Element element = WebDAVModelHelper.createElement(qname);
element.setTextContent(dCmp.getCellStatus());
ret.setPropertyOk(element);
diff --git a/src/main/java/io/personium/core/model/ModelFactory.java b/src/main/java/io/personium/core/model/ModelFactory.java
index 4896911ea..73ab255db 100644
--- a/src/main/java/io/personium/core/model/ModelFactory.java
+++ b/src/main/java/io/personium/core/model/ModelFactory.java
@@ -26,7 +26,6 @@
import io.personium.core.model.impl.fs.BoxCmpFsImpl;
import io.personium.core.model.impl.fs.CellCmpFsImpl;
import io.personium.core.model.impl.fs.CellSnapshotCellCmpFsImpl;
-import io.personium.core.odata.PersoniumODataProducer;
/**
* Factory class of model object.
@@ -105,20 +104,20 @@ public static CellSnapshotCellCmp cellSnapshotCellCmp(final Cell cell) {
*/
public static class ODataCtl {
/**
- * Returns the ODataProducer handling the Unit management entity.
+ * Returns the ODataProducer handling the Unit control objects.
* @param ac access context
- * @return Unit ODataProducer handling management entities
+ * @return UnitCtlODataProducer
*/
- public static PersoniumODataProducer unitCtl(AccessContext ac) {
+ public static UnitCtlODataProducer unitCtl(AccessContext ac) {
return new UnitCtlODataProducer(ac);
}
/**
- * Returns the ODataProducer handling the Cell management entity.
+ * Returns the ODataProducer handling the Cell control objects.
* @param cell Cell's Cell
- * @return ODataProducer handling Cell management entities
+ * @return CellCtlODataProducer
*/
- public static PersoniumODataProducer cellCtl(final Cell cell) {
+ public static CellCtlODataProducer cellCtl(final Cell cell) {
return new CellCtlODataProducer(cell);
}
@@ -126,9 +125,9 @@ public static PersoniumODataProducer cellCtl(final Cell cell) {
* Return ODataProducer for producing OData about message.
* @param cell target cell object
* @param davRsCmp DavRsCmp
- * @return PersoniumODataProducer MessageODataProducer
+ * @return MessageODataProducer MessageODataProducer
*/
- public static PersoniumODataProducer message(final Cell cell, final DavRsCmp davRsCmp) {
+ public static MessageODataProducer message(final Cell cell, final DavRsCmp davRsCmp) {
return new MessageODataProducer(cell, davRsCmp);
}
@@ -136,9 +135,9 @@ public static PersoniumODataProducer message(final Cell cell, final DavRsCmp dav
* Return ODataProducer of user data schema.
* @param cell Cell
* @param davCmp DavCmp
- * @return ODataProducer
+ * @return UserSchemaODataProducer
*/
- public static PersoniumODataProducer userSchema(final Cell cell, final DavCmp davCmp) {
+ public static UserSchemaODataProducer userSchema(final Cell cell, final DavCmp davCmp) {
return new UserSchemaODataProducer(cell, davCmp);
}
@@ -146,9 +145,9 @@ public static PersoniumODataProducer userSchema(final Cell cell, final DavCmp da
* Return ODataProducer of user data.
* @param cell Cell
* @param davCmp DavCmp
- * @return ODataProducer
+ * @return UserDataODataProducer
*/
- public static PersoniumODataProducer userData(final Cell cell, final DavCmp davCmp) {
+ public static UserDataODataProducer userData(final Cell cell, final DavCmp davCmp) {
return new UserDataODataProducer(cell, davCmp);
}
diff --git a/src/main/java/io/personium/core/model/ctl/Common.java b/src/main/java/io/personium/core/model/ctl/Common.java
index 4db287c6b..13afb8843 100644
--- a/src/main/java/io/personium/core/model/ctl/Common.java
+++ b/src/main/java/io/personium/core/model/ctl/Common.java
@@ -25,7 +25,7 @@
import org.odata4j.edm.EdmProperty;
import org.odata4j.edm.EdmSimpleType;
-import io.personium.common.utils.PersoniumCoreUtils;
+import io.personium.common.utils.CommonUtils;
/**
* Constant values commonly used in Edm.
@@ -174,8 +174,8 @@ private Common() {
/**
* DC namespace.
*/
- public static final PrefixedNamespace P_NAMESPACE = new PrefixedNamespace(PersoniumCoreUtils.XmlConst.NS_PERSONIUM,
- PersoniumCoreUtils.XmlConst.NS_PREFIX_PERSONIUM);
+ public static final PrefixedNamespace P_NAMESPACE = new PrefixedNamespace(CommonUtils.XmlConst.NS_PERSONIUM,
+ CommonUtils.XmlConst.NS_PREFIX_PERSONIUM);
/**
* Name property.
diff --git a/src/main/java/io/personium/core/model/impl/es/CellEsImpl.java b/src/main/java/io/personium/core/model/impl/es/CellEsImpl.java
index c88f74fb0..6d0ffb39a 100644
--- a/src/main/java/io/personium/core/model/impl/es/CellEsImpl.java
+++ b/src/main/java/io/personium/core/model/impl/es/CellEsImpl.java
@@ -17,25 +17,19 @@
package io.personium.core.model.impl.es;
import java.net.MalformedURLException;
-import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import org.odata4j.core.OEntity;
import org.odata4j.core.OEntityKey;
import org.odata4j.core.OProperty;
-import org.odata4j.expression.BoolCommonExpression;
import org.odata4j.producer.EntitiesResponse;
-import org.odata4j.producer.EntityResponse;
import org.odata4j.producer.InlineCount;
import org.odata4j.producer.ODataProducer;
import org.odata4j.producer.QueryInfo;
-import org.odata4j.producer.resources.OptionsQueryParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -50,11 +44,8 @@
import io.personium.core.PersoniumCoreLog;
import io.personium.core.PersoniumUnitConfig;
import io.personium.core.auth.AccessContext;
-import io.personium.core.auth.AuthUtils;
-import io.personium.core.event.EventBus;
import io.personium.core.eventlog.EventUtils;
import io.personium.core.model.Box;
-import io.personium.core.model.BoxCmp;
import io.personium.core.model.Cell;
import io.personium.core.model.CellCmp;
import io.personium.core.model.CellSnapshotCellCmp;
@@ -63,16 +54,12 @@
import io.personium.core.model.ctl.Common;
import io.personium.core.model.ctl.ExtCell;
import io.personium.core.model.ctl.ExtRole;
-import io.personium.core.model.ctl.ReceivedMessage;
import io.personium.core.model.ctl.Relation;
-import io.personium.core.model.ctl.Rule;
-import io.personium.core.model.ctl.SentMessage;
import io.personium.core.model.file.BinaryDataAccessException;
import io.personium.core.model.impl.es.accessor.CellAccessor;
import io.personium.core.model.impl.es.accessor.CellDataAccessor;
import io.personium.core.model.impl.es.accessor.EntitySetAccessor;
import io.personium.core.model.impl.es.accessor.ODataLinkAccessor;
-import io.personium.core.model.impl.es.cache.BoxCache;
import io.personium.core.model.impl.es.cache.CellCache;
import io.personium.core.model.impl.es.doc.CellDocHandler;
import io.personium.core.model.impl.es.doc.OEntityDocHandler;
@@ -86,18 +73,13 @@
/**
* Cell object implemented using ElasticSearch.
*/
-public class CellEsImpl implements Cell {
+public class CellEsImpl extends Cell {
/** logger. */
static Logger log = LoggerFactory.getLogger(CellEsImpl.class);
/** Es search result output upper limit. */
private static final int TOP_NUM = PersoniumUnitConfig.getEsTopNum();
- private String id;
- private String name;
- private String url; // Note: path base
- private String owner;
- private Long published;
private Map json;
/**
@@ -136,7 +118,6 @@ public static Cell loadFromName(String cellName) {
CellEsImpl cell = (CellEsImpl) findCell("s.Name.untouched", cellName);
if (cell != null) {
cell.url = PersoniumUnitConfig.getBaseUrl() + cell.name + "/";
- cell.owner = UriUtils.convertSchemeFromLocalUnitToHttp(cell.getUnitUrl(), cell.owner);
}
return cell;
}
@@ -204,90 +185,6 @@ private static Cell findCell(String queryKey, String queryValue) {
return ret;
}
- /**
- * Check the value of property item with regular expression.
- * @param propValue
- * Property value
- * @param dcFormat
- * Value of dcFormat
- * @return In case of format error, return false
- */
- private static boolean validatePropertyRegEx(String propValue, String dcFormat) {
- //Perform format check
- Pattern pattern = Pattern.compile(dcFormat);
- Matcher matcher = pattern.matcher(propValue);
- if (!matcher.matches()) {
- return false;
- }
- return true;
- }
-
- /**
- * Get the Cell name.
- * @return Cell Name
- */
- @Override
- public String getName() {
- return name;
- }
-
- /**
- * Returns the internal ID of this Cell.
- * @return internal identity string
- */
- @Override
- public String getId() {
- return this.id;
- }
-
- /**
- * Returns the URL of this Cell.
- * @return URL string
- */
- @Override
- public String getUrl() {
- if (PersoniumUnitConfig.isPathBasedCellUrlEnabled()) {
- return this.url;
- } else {
- return getFqdnBaseUrl();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getFqdnBaseUrl() {
- try {
- return UriUtils.convertPathBaseToFqdnBase(url);
- } catch (URISyntaxException e) {
- // Usually it does not occur.
- throw PersoniumCoreException.Server.UNKNOWN_ERROR;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getPathBaseUrl() {
- return url;
- }
-
- /**
- * Returns the Unit URL of this Cell.
- * @return unitUrl string
- */
- @Override
- public String getUnitUrl() {
- return PersoniumUnitConfig.getBaseUrl();
- }
-
- @Override
- public String getOwner() {
- return this.owner;
- }
-
@Override
public String getDataBundleNameWithOutPrefix() {
String unitUserName;
@@ -305,52 +202,6 @@ public String getDataBundleName() {
return unitUserName;
}
- @Override
- public EventBus getEventBus() {
- return new EventBus(this);
- }
-
- /**
- * Return the creation time of Cell.
- * @return Cell creation time
- */
- @Override
- public long getPublished() {
- return this.published;
- }
-
- @Override
- public boolean isEmpty() {
- CellCtlODataProducer producer = new CellCtlODataProducer(this);
- // check no box exists.
- QueryInfo queryInfo = new QueryInfo(InlineCount.ALLPAGES, null, null, null, null, null, null, null, null);
- if (producer.getEntitiesCount(Box.EDM_TYPE_NAME, queryInfo).getCount() > 0) {
- return false;
- }
-
- // check that Main Box is empty
- Box defaultBox = this.getBoxForName(Box.DEFAULT_BOX_NAME);
- BoxCmp defaultBoxCmp = ModelFactory.boxCmp(defaultBox);
- if (!defaultBoxCmp.isEmpty()) {
- return false;
- }
-
- // check that no Cell Control Object exists
- //In order to improve the TODO performance, change the type so as to check the value of c: (uuid of the cell) in the Type traversal
- if (producer.getEntitiesCount(Account.EDM_TYPE_NAME, queryInfo).getCount() > 0
- || producer.getEntitiesCount(Role.EDM_TYPE_NAME, queryInfo).getCount() > 0
- || producer.getEntitiesCount(ExtCell.EDM_TYPE_NAME, queryInfo).getCount() > 0
- || producer.getEntitiesCount(ExtRole.EDM_TYPE_NAME, queryInfo).getCount() > 0
- || producer.getEntitiesCount(Relation.EDM_TYPE_NAME, queryInfo).getCount() > 0
- || producer.getEntitiesCount(SentMessage.EDM_TYPE_NAME, queryInfo).getCount() > 0
- || producer.getEntitiesCount(ReceivedMessage.EDM_TYPE_NAME, queryInfo).getCount() > 0
- || producer.getEntitiesCount(Rule.EDM_TYPE_NAME, queryInfo).getCount() > 0) {
- return false;
- }
- // TODO check EventLog
- return true;
- }
-
/**
* {@inheritDoc}
*/
@@ -374,7 +225,7 @@ public void makeEmpty() {
// Delete event log file.
try {
- EventUtils.deleteEventLog(this.getId(), this.getOwner());
+ EventUtils.deleteEventLog(this.getId(), this.getOwnerNormalized());
} catch (BinaryDataAccessException e) {
// If the deletion fails, output a log and continue processing.
log.warn("Delete EventLog Failed." + cellInfoLog, e);
@@ -428,81 +279,6 @@ public void run() {
}
});
thread.start();
-
- }
-
- @Override
- public Box getBoxForName(String boxName) {
- if (Box.DEFAULT_BOX_NAME.equals(boxName)) {
- return new Box(this, null);
- }
-
- //Check the format of the Box name specified in URl. In case of invalid Because none of Box exists, return null
- if (!validatePropertyRegEx(boxName, Common.PATTERN_NAME)) {
- return null;
- }
- //Attempt to acquire the cached Box.
- Box cachedBox = BoxCache.get(boxName, this);
- if (cachedBox != null) {
- return cachedBox;
- }
-
- Box loadedBox = null;
- try {
- ODataProducer op = ModelFactory.ODataCtl.cellCtl(this);
- EntityResponse er = op.getEntity(Box.EDM_TYPE_NAME, OEntityKey.create(boxName), null);
- loadedBox = new Box(this, er.getEntity());
- BoxCache.cache(loadedBox);
- return loadedBox;
- } catch (RuntimeException e) {
- if (e.getCause() instanceof CheckedOperationTimeoutException) {
- return loadedBox;
- } else {
- return null;
- }
- }
- }
-
- @Override
- public Box getBoxForSchema(String boxSchema) {
- //Retrieving the schema name list (including aliases)
- List boxSchemas = UriUtils.getUrlVariations(this.getUnitUrl(), boxSchema);
-
- ODataProducer op = ModelFactory.ODataCtl.cellCtl(this);
- for (int i = 0; i < boxSchemas.size(); i++) {
- BoolCommonExpression filter = OptionsQueryParser.parseFilter("Schema eq '" + boxSchemas.get(i) + "'");
- QueryInfo qi = QueryInfo.newBuilder().setFilter(filter).build();
- try {
- EntitiesResponse er = op.getEntities(Box.EDM_TYPE_NAME, qi);
- List entList = er.getEntities();
- if (entList.size() == 1) {
- return new Box(this, entList.get(0));
- }
- continue;
- } catch (RuntimeException e) {
- return null;
- }
- }
- return null;
- }
-
- @Override
- public OEntityWrapper getAccount(final String username) {
- ODataProducer op = ModelFactory.ODataCtl.cellCtl(this);
- OEntityKey key = OEntityKey.create(username);
- OEntityWrapper oew = null;
- try {
- EntityResponse resp = op.getEntity("Account", key, null);
- oew = (OEntityWrapper) resp.getEntity();
- } catch (PersoniumCoreException dce) {
- log.debug(dce.getMessage());
- }
- return oew;
- }
-
- @Override
- public boolean authenticateAccount(final OEntityWrapper oew, final String password) {
- return AuthUtils.isMatchePassword(oew, password);
}
@SuppressWarnings("unchecked")
@@ -656,7 +432,7 @@ public String roleResourceUrlToId(String roleUrl, String baseUrl) {
}
//It is not permitted to designate the cell URL portion of the role resource different from the cell URL of the ACL setting target
- if (!(this.getUrl().equals(role.getBaseUrl()))) {
+ if (!UriUtils.equalIgnoringPort(this.getUrl(), role.getBaseUrl())) {
PersoniumCoreLog.Dav.ROLE_NOT_FOUND.params("Cell different").writeLog();
throw PersoniumCoreException.Dav.ROLE_NOT_FOUND;
}
@@ -668,7 +444,7 @@ public String roleResourceUrlToId(String roleUrl, String baseUrl) {
Map query = QueryMapFactory.filteredQuery(null, QueryMapFactory.mustQuery(queries));
List