You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by gi...@apache.org on 2016/01/19 16:43:57 UTC
syncope git commit: [SYNCOPE-719] Auxiliary classes can be managed
dyamically during self creation/update
Repository: syncope
Updated Branches:
refs/heads/master 53afc1308 -> 43c4d8ea8
[SYNCOPE-719] Auxiliary classes can be managed dyamically during self creation/update
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/43c4d8ea
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/43c4d8ea
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/43c4d8ea
Branch: refs/heads/master
Commit: 43c4d8ea89c4f97b193451e506bc876d6c5c99be
Parents: 53afc13
Author: giacomolm <gi...@hotmail.it>
Authored: Tue Jan 19 16:36:22 2016 +0100
Committer: giacomolm <gi...@hotmail.it>
Committed: Tue Jan 19 16:36:34 2016 +0100
----------------------------------------------------------------------
.../enduser/SyncopeEnduserApplication.java | 22 ++
.../client/enduser/adapters/UserTOAdapter.java | 8 +-
.../client/enduser/model/UserTORequest.java | 19 +-
.../enduser/resources/SchemaResource.java | 14 +-
.../resources/SyncopeAnyClassTypeResource.java | 86 +++++
.../resources/SyncopeAnyTypeResource.java | 82 +++++
.../resources/META-INF/resources/app/index.html | 2 +
.../app/js/controllers/UserController.js | 351 ++++++++++++-------
.../resources/app/js/directives/auxClasses.js | 60 ++++
.../app/js/directives/dynamicPlainAttributes.js | 42 +--
.../resources/app/js/services/anyService.js | 53 +++
.../resources/app/js/services/schemaService.js | 6 +-
.../resources/app/views/auxClasses.html | 10 +
.../resources/app/views/user-groups.html | 4 +
14 files changed, 595 insertions(+), 164 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/43c4d8ea/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
index 17a92ed..902a276 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java
@@ -34,6 +34,8 @@ import org.apache.syncope.client.enduser.resources.LoginResource;
import org.apache.syncope.client.enduser.resources.LogoutResource;
import org.apache.syncope.client.enduser.resources.SchemaResource;
import org.apache.syncope.client.enduser.resources.SecurityQuestionResource;
+import org.apache.syncope.client.enduser.resources.SyncopeAnyClassTypeResource;
+import org.apache.syncope.client.enduser.resources.SyncopeAnyTypeResource;
import org.apache.syncope.client.enduser.resources.SyncopeGroupResource;
import org.apache.syncope.client.enduser.resources.SyncopeResourceResource;
import org.apache.syncope.client.enduser.resources.UserSelfCreateResource;
@@ -267,6 +269,26 @@ public class SyncopeEnduserApplication extends WebApplication implements Seriali
}
});
+ mountResource("/api/auxiliaryClasses", new ResourceReference("auxClasses") {
+
+ private static final long serialVersionUID = -128426276529456602L;
+
+ @Override
+ public IResource getResource() {
+ return new SyncopeAnyClassTypeResource();
+ }
+ });
+
+ mountResource("/api/anyTypes", new ResourceReference("anyType") {
+
+ private static final long serialVersionUID = -128426276529456602L;
+
+ @Override
+ public IResource getResource() {
+ return new SyncopeAnyTypeResource();
+ }
+ });
+
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/43c4d8ea/client/enduser/src/main/java/org/apache/syncope/client/enduser/adapters/UserTOAdapter.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/adapters/UserTOAdapter.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/adapters/UserTOAdapter.java
index 22aa139..5585a41 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/adapters/UserTOAdapter.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/adapters/UserTOAdapter.java
@@ -58,6 +58,8 @@ public class UserTOAdapter {
userTO.getResources().addAll(userTORequest.getResources());
// add memberships
userTO.getMemberships().addAll(userTORequest.getMemberships());
+ // add auxiliary classes
+ userTO.getAuxClasses().addAll(userTORequest.getAuxClasses());
return userTO;
}
@@ -74,11 +76,13 @@ public class UserTOAdapter {
userTORequest.getPlainAttrs().putAll(userTO.getPlainAttrMap());
userTORequest.getDerAttrs().putAll(userTO.getDerAttrMap());
userTORequest.getVirAttrs().putAll(userTO.getVirAttrMap());
-
+
userTORequest.getResources().addAll(userTO.getResources());
-
+
userTORequest.getMemberships().addAll(userTO.getMemberships());
+ userTORequest.getAuxClasses().addAll(userTO.getAuxClasses());
+
return userTORequest;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/43c4d8ea/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/UserTORequest.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/UserTORequest.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/UserTORequest.java
index be841a4..0af6a76 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/UserTORequest.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/UserTORequest.java
@@ -52,9 +52,11 @@ public class UserTORequest implements Serializable {
private Map<String, AttrTO> virAttrs = new HashMap<>();
private Set<String> resources = new HashSet<>();
-
+
private List<MembershipTO> memberships = new ArrayList<>();
+ private List<String> auxClasses = new ArrayList<>();
+
public UserTORequest() {
}
@@ -137,7 +139,7 @@ public class UserTORequest implements Serializable {
public void setResources(final Set<String> resources) {
this.resources = resources;
}
-
+
public List<MembershipTO> getMemberships() {
return memberships;
}
@@ -146,6 +148,14 @@ public class UserTORequest implements Serializable {
this.memberships = memberships;
}
+ public List<String> getAuxClasses() {
+ return this.auxClasses;
+ }
+
+ public void setAuxClasses(final List<String> auxClasses) {
+ this.auxClasses = auxClasses;
+ }
+
public UserTORequest key(final Long value) {
this.key = value;
return this;
@@ -196,6 +206,11 @@ public class UserTORequest implements Serializable {
return this;
}
+ public UserTORequest auxClasses(final List<String> value) {
+ this.auxClasses = value;
+ return this;
+ }
+
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
http://git-wip-us.apache.org/repos/asf/syncope/blob/43c4d8ea/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
index 12ce2f1..4783b79 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
@@ -19,6 +19,7 @@
package org.apache.syncope.client.enduser.resources;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Response;
@@ -72,15 +73,22 @@ public class SchemaResource extends AbstractBaseResource {
final AnyTypeTO anyTypeUserTO = anyTypeService.read(AnyTypeKind.USER.name());
+ List<String> classes = new ArrayList<>();
+ String parameter = attributes.getParameters().get("anyTypeClass").toString();
+ if (parameter != null) {
+ classes.add(parameter);
+ } else {
+ classes = anyTypeUserTO.getClasses();
+ }
final List<PlainSchemaTO> plainSchemas = schemaService.list(
new SchemaQuery.Builder().type(SchemaType.PLAIN).
- anyTypeClasses(anyTypeUserTO.getClasses()).build());
+ anyTypeClasses(classes).build());
final List<DerSchemaTO> derSchemas = schemaService.list(
new SchemaQuery.Builder().type(SchemaType.DERIVED).
- anyTypeClasses(anyTypeUserTO.getClasses()).build());
+ anyTypeClasses(classes).build());
final List<VirSchemaTO> virSchemas = schemaService.list(
new SchemaQuery.Builder().type(SchemaType.VIRTUAL).
- anyTypeClasses(anyTypeUserTO.getClasses()).build());
+ anyTypeClasses(classes).build());
response.setWriteCallback(new AbstractResource.WriteCallback() {
http://git-wip-us.apache.org/repos/asf/syncope/blob/43c4d8ea/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyClassTypeResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyClassTypeResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyClassTypeResource.java
new file mode 100644
index 0000000..c2c3efc
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyClassTypeResource.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.syncope.client.enduser.resources;
+
+import java.io.IOException;
+import java.util.List;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.client.enduser.SyncopeEnduserSession;
+import org.apache.syncope.client.enduser.adapters.GroupTOAdapter;
+import org.apache.syncope.common.lib.to.AnyTypeClassTO;
+import org.apache.syncope.common.rest.api.service.AnyTypeClassService;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.wicket.request.resource.AbstractResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SyncopeAnyClassTypeResource extends AbstractBaseResource {
+
+ private static final long serialVersionUID = 7475706378304995200L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(SyncopeAnyClassTypeResource.class);
+
+ private final AnyTypeClassService anyTypeClassService;
+
+ private final GroupTOAdapter groupTOAdapter;
+
+ public SyncopeAnyClassTypeResource() {
+ groupTOAdapter = new GroupTOAdapter();
+ anyTypeClassService = SyncopeEnduserSession.get().getService(AnyTypeClassService.class);
+ }
+
+ @Override
+ protected ResourceResponse newResourceResponse(final Attributes attributes) {
+
+ LOG.debug("Get all available auxiliary classes");
+
+ ResourceResponse response = new ResourceResponse();
+
+ try {
+
+ HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
+ if (!xsrfCheck(request)) {
+ LOG.error("XSRF TOKEN does not match");
+ response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
+ return response;
+ }
+
+ final List<AnyTypeClassTO> anyTypeClassTOs = anyTypeClassService.list();
+
+ response.setWriteCallback(new AbstractResource.WriteCallback() {
+
+ @Override
+ public void writeData(final Attributes attributes) throws IOException {
+ attributes.getResponse().write(POJOHelper.serialize(anyTypeClassTOs));
+ }
+ });
+ response.setStatusCode(Response.Status.OK.getStatusCode());
+ } catch (Exception e) {
+ LOG.error("Error retrieving available auxiliary classes", e);
+ response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
+ .append("ErrorMessage{{ ")
+ .append(e.getMessage())
+ .append(" }}")
+ .toString());
+ }
+ return response;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/43c4d8ea/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyTypeResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyTypeResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyTypeResource.java
new file mode 100644
index 0000000..7d2bcde
--- /dev/null
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SyncopeAnyTypeResource.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.syncope.client.enduser.resources;
+
+import java.io.IOException;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.client.enduser.SyncopeEnduserSession;
+import org.apache.syncope.common.lib.to.AnyTypeTO;
+import org.apache.syncope.common.rest.api.service.AnyTypeService;
+import org.apache.syncope.core.misc.serialization.POJOHelper;
+import org.apache.wicket.request.resource.AbstractResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SyncopeAnyTypeResource extends AbstractBaseResource {
+
+ private static final long serialVersionUID = 7475706378304995200L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(SyncopeAnyTypeResource.class);
+
+ private final AnyTypeService anyTypeService;
+
+ public SyncopeAnyTypeResource() {
+ anyTypeService = SyncopeEnduserSession.get().getService(AnyTypeService.class);
+ }
+
+ @Override
+ protected ResourceResponse newResourceResponse(final Attributes attributes) {
+
+ LOG.debug("Get all available auxiliary classes");
+
+ ResourceResponse response = new ResourceResponse();
+
+ try {
+
+ HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest();
+ if (!xsrfCheck(request)) {
+ LOG.error("XSRF TOKEN does not match");
+ response.setError(Response.Status.BAD_REQUEST.getStatusCode(), "XSRF TOKEN does not match");
+ return response;
+ }
+
+ String kind = attributes.getParameters().get(0).toString();
+ final AnyTypeTO anyTypeTO = anyTypeService.read(kind);
+
+ response.setWriteCallback(new AbstractResource.WriteCallback() {
+
+ @Override
+ public void writeData(final Attributes attributes) throws IOException {
+ attributes.getResponse().write(POJOHelper.serialize(anyTypeTO));
+ }
+ });
+ response.setStatusCode(Response.Status.OK.getStatusCode());
+ } catch (Exception e) {
+ LOG.error("Error retrieving available any type details", e);
+ response.setError(Response.Status.BAD_REQUEST.getStatusCode(), new StringBuilder()
+ .append("ErrorMessage{{ ")
+ .append(e.getMessage())
+ .append(" }}")
+ .toString());
+ }
+ return response;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/43c4d8ea/client/enduser/src/main/resources/META-INF/resources/app/index.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/index.html b/client/enduser/src/main/resources/META-INF/resources/app/index.html
index b888051..6ab3b31 100644
--- a/client/enduser/src/main/resources/META-INF/resources/app/index.html
+++ b/client/enduser/src/main/resources/META-INF/resources/app/index.html
@@ -86,6 +86,7 @@ under the License.
<script src="js/services/infoService.js"></script>
<script src="js/services/resourceService.js"></script>
<script src="js/services/groupService.js"></script>
+ <script src="js/services/anyService.js"></script>
<script src="js/services/captchaService.js"></script>
<!--controllers-->
<script src="js/controllers/HomeController.js"></script>
@@ -105,6 +106,7 @@ under the License.
<script src="js/directives/captcha.js"></script>
<script src="js/directives/resources.js"></script>
<script src="js/directives/groups.js"></script>
+ <script src="js/directives/auxClasses.js"></script>
<!--filters-->
<script src="js/filters/propsFilter.js"></script>
http://git-wip-us.apache.org/repos/asf/syncope/blob/43c4d8ea/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js
index 1d35bc6..0390b7a 100644
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/controllers/UserController.js
@@ -21,9 +21,9 @@
angular.module("self").controller("UserController", ['$scope', '$rootScope', '$location', '$compile', 'AuthService',
'UserSelfService', 'SchemaService', 'RealmService', 'ResourceService', 'SecurityQuestionService', 'CaptchaService',
- 'GroupService',
+ 'GroupService', 'AnyService',
function ($scope, $rootScope, $location, $compile, AuthService, UserSelfService, SchemaService, RealmService,
- ResourceService, SecurityQuestionService, CaptchaService, GroupService) {
+ ResourceService, SecurityQuestionService, CaptchaService, GroupService, AnyService) {
$scope.user = {};
$scope.confirmPassword = {
@@ -48,104 +48,111 @@ angular.module("self").controller("UserController", ['$scope', '$rootScope', '$l
virSchemas: [],
resources: [],
groups: [],
+ auxClasses: [],
+ anyUserType: [],
errorMessage: '',
attributeTable: {},
virtualAttributeTable: {},
selectedResources: [],
- selectedGroups: []
+ selectedGroups: [],
+ selectedAuxClasses: []
};
- var initSchemas = function () {
+ var initUserSchemas = function (anyTypeClass) {
// initialization is done here synchronously to have all schema fields populated correctly
- SchemaService.getUserSchemas().then(function (schemas) {
- $scope.dynamicForm.plainSchemas = schemas.plainSchemas;
- $scope.dynamicForm.derSchemas = schemas.derSchemas;
- $scope.dynamicForm.virSchemas = schemas.virSchemas;
+ SchemaService.getUserSchemas(anyTypeClass).then(function (schemas) {
+ //initializing user schemas values
+ initSchemaValues(schemas);
+ }, function (response) {
+ var errorMessage;
+ // parse error response
+ if (response !== undefined) {
+ errorMessage = response.split("ErrorMessage{{")[1];
+ errorMessage = errorMessage.split("}}")[0];
+ }
+ console.log("Error retrieving user schemas: ", errorMessage);
+ });
+ };
- // initialize plain attributes
- for (var i = 0; i < schemas.plainSchemas.length; i++) {
+ var initSchemaValues = function (schemas) {
+ // initialize plain attributes
+ for (var i = 0; i < schemas.plainSchemas.length; i++) {
- var plainSchemaKey = schemas.plainSchemas[i].key;
+ var plainSchemaKey = schemas.plainSchemas[i].key;
- if (!$scope.user.plainAttrs[plainSchemaKey]) {
+ if (!$scope.user.plainAttrs[plainSchemaKey]) {
- $scope.user.plainAttrs[plainSchemaKey] = {
- schema: plainSchemaKey,
- values: [],
- readonly: schemas.plainSchemas[i].readonly
- };
+ $scope.user.plainAttrs[plainSchemaKey] = {
+ schema: plainSchemaKey,
+ values: [],
+ readonly: schemas.plainSchemas[i].readonly
+ };
- // initialize multivalue schema and support table: create mode, only first value
- if (schemas.plainSchemas[i].multivalue) {
- $scope.dynamicForm.attributeTable[schemas.plainSchemas[i].key] = {
- fields: [schemas.plainSchemas[i].key + "_" + 0]
- };
- }
- } else if (schemas.plainSchemas[i].multivalue) {
- // initialize multivalue schema and support table: update mode, all provided values
+ // initialize multivalue schema and support table: create mode, only first value
+ if (schemas.plainSchemas[i].multivalue) {
$scope.dynamicForm.attributeTable[schemas.plainSchemas[i].key] = {
fields: [schemas.plainSchemas[i].key + "_" + 0]
};
- // add other values
- for (var j = 1; j < $scope.user.plainAttrs[plainSchemaKey].values.length; j++) {
- $scope.dynamicForm.attributeTable[schemas.plainSchemas[i].key].fields.push(schemas.plainSchemas[i].key + "_" + j);
- }
+ }
+ } else if (schemas.plainSchemas[i].multivalue) {
+ // initialize multivalue schema and support table: update mode, all provided values
+ $scope.dynamicForm.attributeTable[schemas.plainSchemas[i].key] = {
+ fields: [schemas.plainSchemas[i].key + "_" + 0]
+ };
+ // add other values
+ for (var j = 1; j < $scope.user.plainAttrs[plainSchemaKey].values.length; j++) {
+ $scope.dynamicForm.attributeTable[schemas.plainSchemas[i].key].fields.push(schemas.plainSchemas[i].key + "_" + j);
}
}
+ }
- // initialize derived attributes
- for (var i = 0; i < schemas.derSchemas.length; i++) {
+ // initialize derived attributes
+ for (var i = 0; i < schemas.derSchemas.length; i++) {
- var derSchemaKey = schemas.derSchemas[i].key;
+ var derSchemaKey = schemas.derSchemas[i].key;
- if (!$scope.user.derAttrs[derSchemaKey]) {
+ if (!$scope.user.derAttrs[derSchemaKey]) {
- $scope.user.derAttrs[derSchemaKey] = {
- schema: derSchemaKey,
- values: [],
- readonly: true
- };
+ $scope.user.derAttrs[derSchemaKey] = {
+ schema: derSchemaKey,
+ values: [],
+ readonly: true
+ };
- }
}
+ }
- // initialize virtual attributes
- for (var i = 0; i < schemas.virSchemas.length; i++) {
+ // initialize virtual attributes
+ for (var i = 0; i < schemas.virSchemas.length; i++) {
- var virSchemaKey = schemas.virSchemas[i].key;
+ var virSchemaKey = schemas.virSchemas[i].key;
- if (!$scope.user.virAttrs[virSchemaKey]) {
+ if (!$scope.user.virAttrs[virSchemaKey]) {
- $scope.user.virAttrs[virSchemaKey] = {
- schema: virSchemaKey,
- values: [],
- readonly: schemas.virSchemas[i].readonly
- };
- // initialize multivalue schema and support table: create mode, only first value
- $scope.dynamicForm.virtualAttributeTable[schemas.virSchemas[i].key] = {
- fields: [schemas.virSchemas[i].key + "_" + 0]
- };
- } else {
- // initialize multivalue schema and support table: update mode, all provided values
- $scope.dynamicForm.virtualAttributeTable[schemas.virSchemas[i].key] = {
- fields: [schemas.virSchemas[i].key + "_" + 0]
- };
- // add other values
- for (var j = 1; j < $scope.user.virAttrs[virSchemaKey].values.length; j++) {
- $scope.dynamicForm.virtualAttributeTable[schemas.virSchemas[i].key].fields.push(schemas.virSchemas[i].key + "_" + j);
- }
+ $scope.user.virAttrs[virSchemaKey] = {
+ schema: virSchemaKey,
+ values: [],
+ readonly: schemas.virSchemas[i].readonly
+ };
+ // initialize multivalue schema and support table: create mode, only first value
+ $scope.dynamicForm.virtualAttributeTable[schemas.virSchemas[i].key] = {
+ fields: [schemas.virSchemas[i].key + "_" + 0]
+ };
+ } else {
+ // initialize multivalue schema and support table: update mode, all provided values
+ $scope.dynamicForm.virtualAttributeTable[schemas.virSchemas[i].key] = {
+ fields: [schemas.virSchemas[i].key + "_" + 0]
+ };
+ // add other values
+ for (var j = 1; j < $scope.user.virAttrs[virSchemaKey].values.length; j++) {
+ $scope.dynamicForm.virtualAttributeTable[schemas.virSchemas[i].key].fields.push(schemas.virSchemas[i].key + "_" + j);
}
}
-
- }, function (response) {
- var errorMessage;
- // parse error response
- if (response !== undefined) {
- errorMessage = response.split("ErrorMessage{{")[1];
- errorMessage = errorMessage.split("}}")[0];
- }
- console.log("Error retrieving user schemas: ", errorMessage);
- });
+ }
+ //appending new schemas
+ $scope.dynamicForm.plainSchemas = $scope.dynamicForm.plainSchemas.concat(schemas.plainSchemas);
+ $scope.dynamicForm.derSchemas = $scope.dynamicForm.derSchemas.concat(schemas.derSchemas);
+ $scope.dynamicForm.virSchemas = $scope.dynamicForm.virSchemas.concat(schemas.virSchemas);
};
var initSecurityQuestions = function () {
@@ -188,6 +195,26 @@ angular.module("self").controller("UserController", ['$scope', '$rootScope', '$l
});
};
+ var initAuxClasses = function () {
+
+ //fetching default user classes, that should remain in any case
+ AnyService.getAnyType("USER").then(function (response) {
+ $scope.dynamicForm.anyUserType = response.classes;
+ AnyService.getAuxClasses().then(function (response) {
+ for (var i = 0; i < response.length; i++) {
+ //we should only add schemas that aren't in the anyUserType
+ if ($scope.dynamicForm.anyUserType.indexOf(response[i].key) == -1) {
+ $scope.dynamicForm.auxClasses.push(response[i].key);
+ }
+ }
+ }, function (e) {
+ $scope.showError("An error occur during retrieving auxiliary classes " + e, $scope.notification)
+ });
+ }, function (e) {
+ $scope.showError("An error occur during retrieving auxiliary classes " + e, $scope.notification)
+ });
+ };
+
var readUser = function () {
UserSelfService.read().then(function (response) {
$scope.user = response;
@@ -203,11 +230,48 @@ angular.module("self").controller("UserController", ['$scope', '$rootScope', '$l
"groupName": $scope.user.memberships[index]["groupName"]
});
}
- }, function () {
- console.log("Error");
+ //initialize already assigned auxiliary classes
+ $scope.dynamicForm.selectedAuxClasses = $scope.user.auxClasses;
+ //we need to initialize axiliar attribute schemas
+ for (var index in $scope.user.auxClasses) {
+ $scope.$emit("auxClassAdded", $scope.user.auxClasses[index]);
+ }
+ }, function (e) {
+ console.log("Error during user read ", e);
});
};
+ var removeUserSchemas = function (anyTypeClass) {
+
+ //removing plain schemas
+ for (var i = 0; i < $scope.dynamicForm.plainSchemas.length; i++) {
+ if ($scope.dynamicForm.plainSchemas[i].anyTypeClass == anyTypeClass) {
+ //cleaning both form and user model
+ delete $scope.user.plainAttrs[$scope.dynamicForm.plainSchemas[i].key];
+ $scope.dynamicForm.plainSchemas.splice(i, 1);
+ i--;
+ }
+ }
+ //removing derived schemas
+ for (var i = 0; i < $scope.dynamicForm.derSchemas.length; i++) {
+ if ($scope.dynamicForm.derSchemas[i].anyTypeClass == anyTypeClass) {
+ //cleaning both form and user model
+ delete $scope.user.derAttrs[$scope.dynamicForm.derSchemas[i].key];
+ $scope.dynamicForm.derSchemas.splice(i, 1);
+ i--;
+ }
+ }
+ //removing virtual schemas
+ for (var i = 0; i < $scope.dynamicForm.virSchemas.length; i++) {
+ if ($scope.dynamicForm.virSchemas[i].anyTypeClass == anyTypeClass) {
+ //cleaning both form and user model
+ delete $scope.user.virAttrs[$scope.dynamicForm.virSchemas[i].key];
+ $scope.dynamicForm.virSchemas.splice(i, 1);
+ i--;
+ }
+ }
+ };
+
if ($scope.createMode) {
$scope.user = {
@@ -219,10 +283,15 @@ angular.module("self").controller("UserController", ['$scope', '$rootScope', '$l
plainAttrs: {},
derAttrs: {},
virAttrs: {},
- resources: []
+ resources: [],
+ auxClasses: []
};
// retrieve user realm or all available realms
initUserRealm();
+ // initialize auxiliary schemas in case of pre-existing classes
+ for (var index in $scope.dynamicForm.selectedAuxClasses) {
+ initUserSchemas($scope.dynamicForm.selectedAuxClasses[index]);
+ }
} else {
// read user from syncope core
readUser();
@@ -231,12 +300,26 @@ angular.module("self").controller("UserController", ['$scope', '$rootScope', '$l
initRealms();
//retrieve security available questions
initSecurityQuestions();
+ //initialize available auxiliary classes
+ initAuxClasses();
// initialize user attributes starting from any object schemas
- initSchemas();
+ initUserSchemas();
// initialize available resources
initResources();
//initialize available groups
initGroups();
+
+ //Event management
+ $scope.$on('auxClassAdded', function (event, auxClass) {
+ if (auxClass)
+ initUserSchemas(auxClass);
+ });
+
+ $scope.$on('auxClassRemoved', function (event, auxClass) {
+ if (auxClass)
+ removeUserSchemas(auxClass);
+ });
+
};
$scope.saveUser = function (user) {
@@ -298,63 +381,63 @@ angular.module("self").controller("UserController", ['$scope', '$rootScope', '$l
$scope.showError("Error: " + (errorMessage || response), $scope.notification);
return;
});
- },
- $scope.retrieveSecurityQuestion = function (user) {
- if ($rootScope.pwdResetRequiringSecurityQuestions) {
- if (user && user.username && user.username.length) {
- return SecurityQuestionService.
- getSecurityQuestionByUser(user.username).then(function (data) {
- $scope.userSecurityQuestion = data.content;
- }, function (response) {
- var errorMessage;
- // parse error response
- if (response !== undefined) {
- errorMessage = response.split("ErrorMessage{{")[1];
- errorMessage = errorMessage.split("}}")[0];
- $scope.userSecurityQuestion = "";
- }
- $scope.showError("Error retrieving user security question: " + errorMessage, $scope.notification);
- });
- }
- else {
- $scope.userSecurityQuestion = "";
- }
- }
- },
- $scope.resetPassword = function (user) {
- if (user && user.username) {
- $scope.retrieveSecurityQuestion(user);
- CaptchaService.validate($scope.captchaInput).then(function (response) {
- if (!(response === 'true')) {
- $scope.showError("Captcha inserted is not valid, please digit the correct captcha", $scope.notification);
- return;
- }
- UserSelfService.passwordReset(user).then(function (data) {
- $scope.showSuccess(data, $scope.notification);
- $location.path('/self');
- }, function (response) {
- var errorMessage;
- // parse error response
- if (response !== undefined) {
- errorMessage = response.split("ErrorMessage{{")[1];
- errorMessage = errorMessage.split("}}")[0];
- $scope.showError("An error occured during password reset: " + errorMessage, $scope.notification);
- //we need to refresh captcha after a valid request
- $scope.$broadcast("refreshCaptcha");
- }
- });
- }, function (response) {
- var errorMessage;
- // parse error response
- if (response !== undefined) {
- errorMessage = response.split("ErrorMessage{{")[1];
- errorMessage = errorMessage.split("}}")[0];
- }
- $scope.showError("Error: " + (errorMessage || response), $scope.notification);
- return;
- });
- } else {
- $scope.showError("You should use a valid and non-empty username", $scope.notification);
- }
- };
+ };
+ $scope.retrieveSecurityQuestion = function (user) {
+ if ($rootScope.pwdResetRequiringSecurityQuestions) {
+ if (user && user.username && user.username.length) {
+ return SecurityQuestionService.
+ getSecurityQuestionByUser(user.username).then(function (data) {
+ $scope.userSecurityQuestion = data.content;
+ }, function (response) {
+ var errorMessage;
+ // parse error response
+ if (response !== undefined) {
+ errorMessage = response.split("ErrorMessage{{")[1];
+ errorMessage = errorMessage.split("}}")[0];
+ $scope.userSecurityQuestion = "";
+ }
+ $scope.showError("Error retrieving user security question: " + errorMessage, $scope.notification);
+ });
+ }
+ else {
+ $scope.userSecurityQuestion = "";
+ }
+ }
+ };
+ $scope.resetPassword = function (user) {
+ if (user && user.username) {
+ $scope.retrieveSecurityQuestion(user);
+ CaptchaService.validate($scope.captchaInput).then(function (response) {
+ if (!(response === 'true')) {
+ $scope.showError("Captcha inserted is not valid, please digit the correct captcha", $scope.notification);
+ return;
+ }
+ UserSelfService.passwordReset(user).then(function (data) {
+ $scope.showSuccess(data, $scope.notification);
+ $location.path('/self');
+ }, function (response) {
+ var errorMessage;
+ // parse error response
+ if (response !== undefined) {
+ errorMessage = response.split("ErrorMessage{{")[1];
+ errorMessage = errorMessage.split("}}")[0];
+ $scope.showError("An error occured during password reset: " + errorMessage, $scope.notification);
+ //we need to refresh captcha after a valid request
+ $scope.$broadcast("refreshCaptcha");
+ }
+ });
+ }, function (response) {
+ var errorMessage;
+ // parse error response
+ if (response !== undefined) {
+ errorMessage = response.split("ErrorMessage{{")[1];
+ errorMessage = errorMessage.split("}}")[0];
+ }
+ $scope.showError("Error: " + (errorMessage || response), $scope.notification);
+ return;
+ });
+ } else {
+ $scope.showError("You should use a valid and non-empty username", $scope.notification);
+ }
+ };
}]);
http://git-wip-us.apache.org/repos/asf/syncope/blob/43c4d8ea/client/enduser/src/main/resources/META-INF/resources/app/js/directives/auxClasses.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/auxClasses.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/auxClasses.js
new file mode 100644
index 0000000..99a6c1e
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/auxClasses.js
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+'use strict';
+
+angular.module('self')
+ .directive('auxiliary', function () {
+ return {
+ restrict: 'E',
+ templateUrl: 'views/auxClasses.html',
+ scope: {
+ dynamicForm: "=form",
+ user: "="
+ },
+ controller: function ($scope, $filter) {
+
+ $scope.init = function () {
+ if (!$scope.user.auxClasses) {
+ $scope.user.auxClasses = new Array();
+ }
+ $scope.auxClassDisabled = false;
+ };
+
+ $scope.addAuxClass = function (item, model) {
+ var auxClass = item;
+ $scope.user.auxClasses.push(auxClass);
+ $scope.$emit("auxClassAdded", auxClass);
+ };
+
+ $scope.removeAuxClass = function (item, model) {
+ var auxClassIndex = $scope.getIndex(item);
+ $scope.user.auxClasses.splice(auxClassIndex, 1);
+ $scope.$emit("auxClassRemoved", item);
+ };
+
+ $scope.getIndex = function (selectedAuxClass) {
+ var auxClassIndex = $scope.user.auxClasses.map(function (auxClassName) {
+ return auxClassName;
+ }).indexOf(selectedAuxClass);
+ return auxClassIndex;
+ };
+
+ }
+ };
+ });
http://git-wip-us.apache.org/repos/asf/syncope/blob/43c4d8ea/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttributes.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttributes.js b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttributes.js
index 672f024..4d11a49 100644
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttributes.js
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/directives/dynamicPlainAttributes.js
@@ -20,26 +20,26 @@
angular.module('self')
.directive('dynamicPlainAttributes', function (SchemaService) {
- return {
- restrict: 'E',
- templateUrl: 'views/dynamicPlainAttributes.html',
- scope: {
- dynamicForm: "=form",
- user: "="
- },
- controller: function ($scope) {
+ return {
+ restrict: 'E',
+ templateUrl: 'views/dynamicPlainAttributes.html',
+ scope: {
+ dynamicForm: "=form",
+ user: "="
+ },
+ controller: function ($scope) {
- $scope.addAttributeField = function (plainSchemaKey) {
- console.log("Add PLAIN value: ", plainSchemaKey + "_" + ($scope.dynamicForm.attributeTable[plainSchemaKey].fields.length));
- $scope.dynamicForm.attributeTable[plainSchemaKey].fields.push(plainSchemaKey + "_" + ($scope.dynamicForm.attributeTable[plainSchemaKey].fields.length));
- };
+ $scope.addAttributeField = function (plainSchemaKey) {
+ console.log("Add PLAIN value: ", plainSchemaKey + "_" + ($scope.dynamicForm.attributeTable[plainSchemaKey].fields.length));
+ $scope.dynamicForm.attributeTable[plainSchemaKey].fields.push(plainSchemaKey + "_" + ($scope.dynamicForm.attributeTable[plainSchemaKey].fields.length));
+ };
- $scope.removeAttributeField = function (plainSchemaKey, index) {
- console.log("Remove PLAIN value: " + plainSchemaKey + " attribute index: " + index);
- $scope.dynamicForm.attributeTable[plainSchemaKey].fields.splice(index, 1);
- // clean user model
- $scope.user.plainAttrs[plainSchemaKey].values.splice(index, 1);
- };
- }
- };
- });
+ $scope.removeAttributeField = function (plainSchemaKey, index) {
+ console.log("Remove PLAIN value: " + plainSchemaKey + " attribute index: " + index);
+ $scope.dynamicForm.attributeTable[plainSchemaKey].fields.splice(index, 1);
+ // clean user model
+ $scope.user.plainAttrs[plainSchemaKey].values.splice(index, 1);
+ };
+ }
+ };
+ });
http://git-wip-us.apache.org/repos/asf/syncope/blob/43c4d8ea/client/enduser/src/main/resources/META-INF/resources/app/js/services/anyService.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/services/anyService.js b/client/enduser/src/main/resources/META-INF/resources/app/js/services/anyService.js
new file mode 100644
index 0000000..f62841c
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/services/anyService.js
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+'use strict';
+
+angular.module('self')
+ .factory('AnyService', ['$resource', '$q', '$http',
+ function ($auxClass, $q, $http) {
+
+ var any = {};
+
+ any.getAuxClasses = function () {
+ return $http.get("/syncope-enduser/api/auxiliaryClasses")
+ .then(function (response) {
+ console.log("auxiliaryClasses API response: ", response);
+ return response.data;
+ }, function (response) {
+ console.log("Something went wrong during auxiliaryClasses retrieval, exit with status: ", response);
+ return $q.reject(response.data || response.statusText);
+ });
+ };
+
+ any.getAnyType = function (kind) {
+ return $http.get("/syncope-enduser/api/anyTypes/" + encodeURI(kind))
+ .then(function (response) {
+ console.log("anyType user API response: ", response);
+ return response.data;
+ }, function (response) {
+ console.log("Something went wrong during anyType user API retrieval, exit with status: ", response);
+ return $q.reject(response.data || response.statusText);
+ });
+ };
+
+ return any;
+ }]);
+
+
http://git-wip-us.apache.org/repos/asf/syncope/blob/43c4d8ea/client/enduser/src/main/resources/META-INF/resources/app/js/services/schemaService.js
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/js/services/schemaService.js b/client/enduser/src/main/resources/META-INF/resources/app/js/services/schemaService.js
index be9f510..faec8c2 100644
--- a/client/enduser/src/main/resources/META-INF/resources/app/js/services/schemaService.js
+++ b/client/enduser/src/main/resources/META-INF/resources/app/js/services/schemaService.js
@@ -25,9 +25,11 @@ angular.module('self')
var schemaService = {};
- schemaService.getUserSchemas = function () {
+ schemaService.getUserSchemas = function (anyTypeClass) {
- return $http.get("/syncope-enduser/api/schemas")
+ var classParam = anyTypeClass ? "?anyTypeClass=" + encodeURI(anyTypeClass) : "";
+
+ return $http.get("/syncope-enduser/api/schemas" + classParam)
.then(function (response) {
console.log("schemaAPI response: ", response);
return response.data;
http://git-wip-us.apache.org/repos/asf/syncope/blob/43c4d8ea/client/enduser/src/main/resources/META-INF/resources/app/views/auxClasses.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/auxClasses.html b/client/enduser/src/main/resources/META-INF/resources/app/views/auxClasses.html
new file mode 100644
index 0000000..1c3bcd6
--- /dev/null
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/auxClasses.html
@@ -0,0 +1,10 @@
+<div ng-init='init()'>
+ <ui-select on-select="addAuxClass($item, $model)" on-remove="removeAuxClass($item, $model)" multiple
+ ng-model="dynamicForm.selectedAuxClasses" theme="select2" class="attribute-ui-select"
+ ng-disabled="{{auxClassDisabled}}">
+ <ui-select-match placeholder="Click to select auxiliary class...">{{$item}}</ui-select-match>
+ <ui-select-choices repeat="auxClass in dynamicForm.auxClasses">
+ <div ng-bind-html="auxClass | highlight: $select.search"></div>
+ </ui-select-choices>
+ </ui-select>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/43c4d8ea/client/enduser/src/main/resources/META-INF/resources/app/views/user-groups.html
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/resources/META-INF/resources/app/views/user-groups.html b/client/enduser/src/main/resources/META-INF/resources/app/views/user-groups.html
index 26ca1ce..591b68c 100644
--- a/client/enduser/src/main/resources/META-INF/resources/app/views/user-groups.html
+++ b/client/enduser/src/main/resources/META-INF/resources/app/views/user-groups.html
@@ -31,6 +31,10 @@ under the License.
<label>Groups</label><br/>
<groups form="dynamicForm" user="user"></groups>
</div>
+<div id="attribute" class="form-group row upper-select">
+ <label>Auxilary Classes</label><br/>
+ <auxiliary form="dynamicForm" user="user"></auxiliary>
+</div>
<div id="attribute" class="form-group row">
<navigation-buttons ng-show="createMode" next="create.plainSchemas" previous="create.credentials"></navigation-buttons>
<navigation-buttons ng-show="!createMode" next="update.plainSchemas" previous="update.credentials"></navigation-buttons>