[SYNCOPE-152] Implementations for /ServiceProviderConfig /ResourceTypes and /Schemas - still static
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/f04ab6c2 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/f04ab6c2 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/f04ab6c2 Branch: refs/heads/master Commit: f04ab6c26e99ae0a5fe19915e303fa965fcd6332 Parents: 5697a5f Author: Francesco Chicchiriccò <ilgro...@apache.org> Authored: Tue Oct 31 15:10:24 2017 +0100 Committer: Francesco Chicchiriccò <ilgro...@apache.org> Committed: Tue Oct 31 15:16:53 2017 +0100 ---------------------------------------------------------------------- ext/scimv2/logic/pom.xml | 62 ++ .../apache/syncope/core/logic/RootLogic.java | 143 +++ .../syncope/core/logic/init/SCIMLoader.java | 106 ++ .../logic/src/main/resources/schemas.json | 960 +++++++++++++++++++ .../src/main/resources/scimv2-logic.properties | 21 + ext/scimv2/pom.xml | 1 + .../scimv2/api/data/AuthenticationScheme.java | 82 ++ .../api/data/BulkConfigurationOption.java | 51 + .../scimv2/api/data/ConfigurationOption.java | 39 + .../api/data/FilterConfigurationOption.java | 43 + .../ext/scimv2/api/data/ListResponse.java | 4 +- .../syncope/ext/scimv2/api/data/Member.java | 6 +- .../syncope/ext/scimv2/api/data/Meta.java | 13 +- .../ext/scimv2/api/data/ResourceType.java | 97 ++ .../ext/scimv2/api/data/SchemaExtension.java | 49 + .../scimv2/api/data/ServiceProviderConfig.java | 97 ++ .../ext/scimv2/api/service/GroupService.java | 2 +- .../ext/scimv2/api/service/RootService.java | 24 +- .../ext/scimv2/api/service/UserService.java | 2 +- .../syncope/ext/scimv2/api/type/Resource.java | 41 + .../ext/scimv2/api/type/ResourceType.java | 37 - ext/scimv2/scim-rest-cxf/pom.xml | 7 +- .../syncope/ext/scimv2/cxf/AddETagFilter.java | 55 ++ .../scimv2/cxf/service/AbstractSCIMService.java | 22 +- .../scimv2/cxf/service/GroupServiceImpl.java | 4 +- .../ext/scimv2/cxf/service/RootServiceImpl.java | 39 +- .../ext/scimv2/cxf/service/UserServiceImpl.java | 4 +- .../src/main/resources/restSCIMv2CXFContext.xml | 3 + .../main/resources/all/scimv2-logic.properties | 21 + .../org/apache/syncope/fit/SCIMDetector.java | 13 +- .../org/apache/syncope/fit/core/SCIMITCase.java | 89 +- fit/core-reference/src/test/resources/rebel.xml | 2 + 32 files changed, 2033 insertions(+), 106 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/logic/pom.xml ---------------------------------------------------------------------- diff --git a/ext/scimv2/logic/pom.xml b/ext/scimv2/logic/pom.xml new file mode 100644 index 0000000..abc90b1 --- /dev/null +++ b/ext/scimv2/logic/pom.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.syncope.ext</groupId> + <artifactId>syncope-ext-scimv2</artifactId> + <version>2.1.0-SNAPSHOT</version> + </parent> + + <name>Apache Syncope Ext: SCIMv2 Logic</name> + <description>Apache Syncope Ext: SCIMv2 Logic</description> + <groupId>org.apache.syncope.ext.scimv2</groupId> + <artifactId>syncope-ext-scimv2-logic</artifactId> + <packaging>jar</packaging> + + <properties> + <rootpom.basedir>${basedir}/../../..</rootpom.basedir> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.syncope.core</groupId> + <artifactId>syncope-core-logic</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.syncope.ext.scimv2</groupId> + <artifactId>syncope-ext-scimv2-scim-rest-api</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + </plugin> + </plugins> + </build> +</project> http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/RootLogic.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/RootLogic.java b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/RootLogic.java new file mode 100644 index 0000000..75d0ecf --- /dev/null +++ b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/RootLogic.java @@ -0,0 +1,143 @@ +/* + * 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.core.logic; + +import java.lang.reflect.Method; +import java.net.URI; +import java.util.Arrays; +import java.util.List; +import javax.ws.rs.NotFoundException; +import javax.ws.rs.core.UriBuilder; +import org.apache.syncope.common.lib.AbstractBaseBean; +import org.apache.syncope.core.logic.init.SCIMLoader; +import org.apache.syncope.ext.scimv2.api.data.AuthenticationScheme; +import org.apache.syncope.ext.scimv2.api.data.BulkConfigurationOption; +import org.apache.syncope.ext.scimv2.api.data.ConfigurationOption; +import org.apache.syncope.ext.scimv2.api.data.FilterConfigurationOption; +import org.apache.syncope.ext.scimv2.api.data.Meta; +import org.apache.syncope.ext.scimv2.api.data.ResourceType; +import org.apache.syncope.ext.scimv2.api.data.SchemaExtension; +import org.apache.syncope.ext.scimv2.api.data.ServiceProviderConfig; +import org.apache.syncope.ext.scimv2.api.type.Resource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +@Component +public class RootLogic extends AbstractLogic<AbstractBaseBean> { + + private static final Object MONITOR = new Object(); + + private static ServiceProviderConfig SERVICE_PROVIDER_CONFIG; + + private static ResourceType USER; + + private static ResourceType GROUP; + + @Autowired + private SCIMLoader loader; + + @PreAuthorize("isAuthenticated()") + public ServiceProviderConfig serviceProviderConfig() { + synchronized (MONITOR) { + if (SERVICE_PROVIDER_CONFIG == null) { + SERVICE_PROVIDER_CONFIG = new ServiceProviderConfig( + new ConfigurationOption(true), + new BulkConfigurationOption( + true, loader.getBulkMaxOperations(), loader.getBulkMaxPayloadSize()), + new FilterConfigurationOption(true, loader.getFilterMaxResults()), + new ConfigurationOption(true), + new ConfigurationOption(true), + new ConfigurationOption(true)); + SERVICE_PROVIDER_CONFIG.getAuthenticationSchemes().add(new AuthenticationScheme( + "JSON Web Token", + "Apache Syncope JWT authentication", + URI.create("http://www.rfc-editor.org/info/rfc6750"), + URI.create("https://syncope.apache.org/docs/" + + "reference-guide.html#rest-authentication-and-authorization"), + "oauthbearertoken", + true)); + SERVICE_PROVIDER_CONFIG.getAuthenticationSchemes().add(new AuthenticationScheme( + "HTTP Basic", + "Apache Syncope HTTP Basic authentication", + URI.create("http://www.rfc-editor.org/info/rfc2617"), + URI.create("https://syncope.apache.org/docs/" + + "reference-guide.html#rest-authentication-and-authorization"), + "httpbasic", + false)); + } + } + return SERVICE_PROVIDER_CONFIG; + } + + @PreAuthorize("isAuthenticated()") + public List<ResourceType> resourceTypes(final UriBuilder uriBuilder) { + synchronized (MONITOR) { + if (USER == null) { + USER = new ResourceType("User", "User", "/Users", "User Account", Resource.User.schema(), + new Meta(Resource.ResourceType, + null, null, null, uriBuilder.path("User").build().toASCIIString())); + USER.getSchemaExtensions().add(new SchemaExtension(Resource.EnterpriseUser.schema(), true)); + } + if (GROUP == null) { + GROUP = new ResourceType("Group", "Group", "/Groups", "Group", Resource.Group.schema(), + new Meta(Resource.ResourceType, + null, null, null, uriBuilder.path("Group").build().toASCIIString())); + } + } + + return Arrays.asList(USER, GROUP); + } + + @PreAuthorize("isAuthenticated()") + public ResourceType resourceType(final UriBuilder uriBuilder, final String type) { + if (Resource.User.name().equals(type)) { + resourceTypes(uriBuilder); + return USER; + } else if (Resource.Group.name().equals(type)) { + resourceTypes(uriBuilder); + return GROUP; + } else { + throw new IllegalArgumentException("Unsupported resource type: " + type); + } + } + + @PreAuthorize("isAuthenticated()") + public String schemas() { + return loader.getSchemas(); + } + + @PreAuthorize("isAuthenticated()") + public String schema(final String schema) { + String found = loader.getSchema(schema); + if (found == null) { + throw new NotFoundException("Schema " + schema); + } + + return found; + } + + @Override + protected AbstractBaseBean resolveReference(final Method method, final Object... args) + throws UnresolvedReferenceException { + + throw new UnresolvedReferenceException(); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/init/SCIMLoader.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/init/SCIMLoader.java b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/init/SCIMLoader.java new file mode 100644 index 0000000..894ba24 --- /dev/null +++ b/ext/scimv2/logic/src/main/java/org/apache/syncope/core/logic/init/SCIMLoader.java @@ -0,0 +1,106 @@ +/* + * 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.core.logic.init; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.syncope.common.lib.PropertyUtils; +import org.apache.syncope.core.persistence.api.SyncopeLoader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class SCIMLoader implements SyncopeLoader { + + private static final Logger LOG = LoggerFactory.getLogger(SCIMLoader.class); + + private static final String SCIMV2_LOGIC_PROPERTIES = "scimv2-logic.properties"; + + private static final String SCHEMAS = "schemas.json"; + + private int bulkMaxOperations = 0; + + private int bulkMaxPayloadSize = 0; + + private int filterMaxResults = 0; + + private String schemas; + + private final Map<String, String> schemaMap = new HashMap<>(); + + @Override + public Integer getPriority() { + return 1000; + } + + @Override + public void load() { + Pair<Properties, String> init = PropertyUtils.read(getClass(), SCIMV2_LOGIC_PROPERTIES, "conf.directory"); + Properties props = init.getLeft(); + + bulkMaxOperations = Integer.valueOf(props.getProperty("bulk.maxOperations")); + bulkMaxPayloadSize = Integer.valueOf(props.getProperty("bulk.maxPayloadSize")); + filterMaxResults = Integer.valueOf(props.getProperty("filter.maxResults")); + + try { + ObjectMapper mapper = new ObjectMapper(); + JsonNode tree = mapper.readTree(getClass().getResourceAsStream("/" + SCHEMAS)); + if (!tree.isArray()) { + throw new IOException("JSON node is not a tree"); + } + + ArrayNode schemaArray = (ArrayNode) tree; + schemas = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(tree); + + for (JsonNode schema : schemaArray) { + schemaMap.put(schema.get("id").asText(), mapper.writeValueAsString(schema)); + } + } catch (IOException e) { + LOG.error("Could not parse the default schema definitions", e); + } + } + + public int getBulkMaxOperations() { + return bulkMaxOperations; + } + + public int getBulkMaxPayloadSize() { + return bulkMaxPayloadSize; + } + + public int getFilterMaxResults() { + return filterMaxResults; + } + + public String getSchemas() { + return schemas; + } + + public String getSchema(final String schema) { + return schemaMap.get(schema); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/logic/src/main/resources/schemas.json ---------------------------------------------------------------------- diff --git a/ext/scimv2/logic/src/main/resources/schemas.json b/ext/scimv2/logic/src/main/resources/schemas.json new file mode 100644 index 0000000..2b9558b --- /dev/null +++ b/ext/scimv2/logic/src/main/resources/schemas.json @@ -0,0 +1,960 @@ +[ + { + "id": "urn:ietf:params:scim:schemas:core:2.0:User", + "name": "User", + "description": "User Account", + "attributes": [ + { + "name": "userName", + "type": "string", + "multiValued": false, + "description": "Unique identifier for the User, typically used by the user to directly authenticate to the service provider. Each User MUST include a non-empty userName value. This identifier MUST be unique across the service provider's entire set of Users. REQUIRED.", + "required": true, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "server" + }, + { + "name": "name", + "type": "complex", + "multiValued": false, + "description": "The components of the user's real name. Providers MAY return just the full name as a single string in the formatted sub-attribute, or they MAY return just the individual component attributes using the other sub-attributes, or they MAY return both. If both variants are returned, they SHOULD be describing the same name, with the formatted name indicating how the component attributes should be combined.", + "required": false, + "subAttributes": [ + { + "name": "formatted", + "type": "string", + "multiValued": false, + "description": "The full name, including all middle names, titles, and suffixes as appropriate, formatted for display 'Ms. Barbara J Jensen, III').", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "familyName", + "type": "string", + "multiValued": false, + "description": "The family name of the User, or last name in most Western languages (e.g., 'Jensen' given the full name 'Ms. Barbara J Jensen, III').", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "givenName", + "type": "string", + "multiValued": false, + "description": "The given name of the User, or first name in most Western languages (e.g., 'Barbara' given the full name 'Ms. Barbara J Jensen, III').", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "middleName", + "type": "string", + "multiValued": false, + "description": "The middle name(s) of the User (e.g., 'Jane' given the full name 'Ms. Barbara J Jensen, III').", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "honorificPrefix", + "type": "string", + "multiValued": false, + "description": "The honorific prefix(es) of the User, or title in most Western languages (e.g., 'Ms.' given the full name 'Ms. Barbara J Jensen, III').", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "honorificSuffix", + "type": "string", + "multiValued": false, + "description": "The honorific suffix(es) of the User, or suffix in most Western languages (e.g., 'III' given the full name 'Ms. Barbara J Jensen, III').", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + } + ], + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "displayName", + "type": "string", + "multiValued": false, + "description": "The name of the User, suitable for display to end-users. The name SHOULD be the full name of the User being described, if known.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "nickName", + "type": "string", + "multiValued": false, + "description": "The casual way to address the user in real life, e.g., 'Bob' or 'Bobby' instead of 'Robert'. This attribute SHOULD NOT be used to represent a User's username (e.g., 'bjensen' or 'mpepperidge').", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "profileUrl", + "type": "reference", + "referenceTypes": ["external"], + "multiValued": false, + "description": "A fully qualified URL pointing to a page representing the User's online profile.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "title", + "type": "string", + "multiValued": false, + "description": "The user's title, such as \"Vice President.\"", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "userType", + "type": "string", + "multiValued": false, + "description": "Used to identify the relationship between the organization and the user. Typical values used might be 'Contractor', 'Employee', 'Intern', 'Temp', 'External', and 'Unknown', but any value may be used.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "preferredLanguage", + "type": "string", + "multiValued": false, + "description": "Indicates the User's preferred written or spoken language. Generally used for selecting a localized user interface; e.g., 'en_US' specifies the language English and country US.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "locale", + "type": "string", + "multiValued": false, + "description": "Used to indicate the User's default location for purposes of localizing items such as currency, date time format, or numerical representations.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "timezone", + "type": "string", + "multiValued": false, + "description": "The User's time zone in the 'Olson' time zone database format, e.g., 'America/Los_Angeles'.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "active", + "type": "boolean", + "multiValued": false, + "description": "A Boolean value indicating the User's administrative status.", + "required": false, + "mutability": "readWrite", + "returned": "default" + }, + { + "name": "password", + "type": "string", + "multiValued": false, + "description": "The User's cleartext password. This attribute is intended to be used as a means to specify an initial password when creating a new User or to reset an existing User's password.", + "required": false, + "caseExact": false, + "mutability": "writeOnly", + "returned": "never", + "uniqueness": "none" + }, + { + "name": "emails", + "type": "complex", + "multiValued": true, + "description": "Email addresses for the user. The value SHOULD be canonicalized by the service provider, e.g., 'bjen...@example.com' instead of 'bjen...@example.com'. Canonical type values of 'work', 'home', and 'other'.", + "required": false, + "subAttributes": [ + { + "name": "value", + "type": "string", + "multiValued": false, + "description": "Email addresses for the user. The value SHOULD be canonicalized by the service provider, e.g., 'bjen...@example.com' instead of 'bjen...@example.com'. Canonical type values of 'work', 'home', and 'other'.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "display", + "type": "string", + "multiValued": false, + "description": "A human-readable name, primarily used for display purposes. READ-ONLY.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "type", + "type": "string", + "multiValued": false, + "description": "A label indicating the attribute's function, e.g., 'work' or 'home'.", + "required": false, + "caseExact": false, + "canonicalValues": [ + "work", + "home", + "other" + ], + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "primary", + "type": "boolean", + "multiValued": false, + "description": "A Boolean value indicating the 'primary' or preferred attribute value for this attribute, e.g., the preferred mailing address or primary email address. The primary attribute value 'true' MUST appear no more than once.", + "required": false, + "mutability": "readWrite", + "returned": "default" + } + ], + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "phoneNumbers", + "type": "complex", + "multiValued": true, + "description": "Phone numbers for the User. The value SHOULD be canonicalized by the service provider according to the format specified in RFC 3966, e.g., 'tel:+1-201-555-0123'. Canonical type values of 'work', 'home', 'mobile', 'fax', 'pager', and 'other'.", + "required": false, + "subAttributes": [ + { + "name": "value", + "type": "string", + "multiValued": false, + "description": "Phone number of the User.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "display", + "type": "string", + "multiValued": false, + "description": "A human-readable name, primarily used for display purposes. READ-ONLY.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "type", + "type": "string", + "multiValued": false, + "description": "A label indicating the attribute's function, e.g., 'work', 'home', 'mobile'.", + "required": false, + "caseExact": false, + "canonicalValues": [ + "work", + "home", + "mobile", + "fax", + "pager", + "other" + ], + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "primary", + "type": "boolean", + "multiValued": false, + "description": "A Boolean value indicating the 'primary' or preferred attribute value for this attribute, e.g., the preferred phone number or primary phone number. The primary attribute value 'true' MUST appear no more than once.", + "required": false, + "mutability": "readWrite", + "returned": "default" + } + ], + "mutability": "readWrite", + "returned": "default" + }, + { + "name": "ims", + "type": "complex", + "multiValued": true, + "description": "Instant messaging addresses for the User.", + "required": false, + "subAttributes": [ + { + "name": "value", + "type": "string", + "multiValued": false, + "description": "Instant messaging address for the User.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "display", + "type": "string", + "multiValued": false, + "description": "A human-readable name, primarily used for display purposes. READ-ONLY.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "type", + "type": "string", + "multiValued": false, + "description": "A label indicating the attribute's function, e.g., 'aim', 'gtalk', 'xmpp'.", + "required": false, + "caseExact": false, + "canonicalValues": [ + "aim", + "gtalk", + "icq", + "xmpp", + "msn", + "skype", + "qq", + "yahoo" + ], + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "primary", + "type": "boolean", + "multiValued": false, + "description": "A Boolean value indicating the 'primary' or preferred attribute value for this attribute, e.g., the preferred messenger or primary messenger. The primary attribute value 'true' MUST appear no more than once.", + "required": false, + "mutability": "readWrite", + "returned": "default" + } + ], + "mutability": "readWrite", + "returned": "default" + }, + { + "name": "photos", + "type": "complex", + "multiValued": true, + "description": "URLs of photos of the User.", + "required": false, + "subAttributes": [ + { + "name": "value", + "type": "reference", + "referenceTypes": ["external"], + "multiValued": false, + "description": "URL of a photo of the User.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "display", + "type": "string", + "multiValued": false, + "description": "A human-readable name, primarily used for display purposes. READ-ONLY.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "type", + "type": "string", + "multiValued": false, + "description": "A label indicating the attribute's function, i.e., 'photo' or 'thumbnail'.", + "required": false, + "caseExact": false, + "canonicalValues": [ + "photo", + "thumbnail" + ], + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "primary", + "type": "boolean", + "multiValued": false, + "description": "A Boolean value indicating the 'primary' or preferred attribute value for this attribute, e.g., the preferred photo or thumbnail. The primary attribute value 'true' MUST appear no more than once.", + "required": false, + "mutability": "readWrite", + "returned": "default" + } + ], + "mutability": "readWrite", + "returned": "default" + }, + { + "name": "addresses", + "type": "complex", + "multiValued": true, + "description": "A physical mailing address for this User. Canonical type values of 'work', 'home', and 'other'. This attribute is a complex type with the following sub-attributes.", + "required": false, + "subAttributes": [ + { + "name": "formatted", + "type": "string", + "multiValued": false, + "description": "The full mailing address, formatted for display or use with a mailing label. This attribute MAY contain newlines.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "streetAddress", + "type": "string", + "multiValued": false, + "description": "The full street address component, which may include house number, street name, P.O. box, and multi-line extended street address information. This attribute MAY contain newlines.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "locality", + "type": "string", + "multiValued": false, + "description": "The city or locality component.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "region", + "type": "string", + "multiValued": false, + "description": "The state or region component.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "postalCode", + "type": "string", + "multiValued": false, + "description": "The zip code or postal code component.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "country", + "type": "string", + "multiValued": false, + "description": "The country name component.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "type", + "type": "string", + "multiValued": false, + "description": "A label indicating the attribute's function, e.g., 'work' or 'home'.", + "required": false, + "caseExact": false, + "canonicalValues": [ + "work", + "home", + "other" + ], + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + } + ], + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "groups", + "type": "complex", + "multiValued": true, + "description": "A list of groups to which the user belongs, either through direct membership, through nested groups, or dynamically calculated.", + "required": false, + "subAttributes": [ + { + "name": "value", + "type": "string", + "multiValued": false, + "description": "The identifier of the User's group.", + "required": false, + "caseExact": false, + "mutability": "readOnly", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "$ref", + "type": "reference", + "referenceTypes": [ + "User", + "Group" + ], + "multiValued": false, + "description": "The URI of the corresponding 'Group' resource to which the user belongs.", + "required": false, + "caseExact": false, + "mutability": "readOnly", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "display", + "type": "string", + "multiValued": false, + "description": "A human-readable name, primarily used for display purposes. READ-ONLY.", + "required": false, + "caseExact": false, + "mutability": "readOnly", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "type", + "type": "string", + "multiValued": false, + "description": "A label indicating the attribute's function, e.g., 'direct' or 'indirect'.", + "required": false, + "caseExact": false, + "canonicalValues": [ + "direct", + "indirect" + ], + "mutability": "readOnly", + "returned": "default", + "uniqueness": "none" + } + ], + "mutability": "readOnly", + "returned": "default" + }, + { + "name": "entitlements", + "type": "complex", + "multiValued": true, + "description": "A list of entitlements for the User that represent a thing the User has.", + "required": false, + "subAttributes": [ + { + "name": "value", + "type": "string", + "multiValued": false, + "description": "The value of an entitlement.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "display", + "type": "string", + "multiValued": false, + "description": "A human-readable name, primarily used for display purposes. READ-ONLY.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "type", + "type": "string", + "multiValued": false, + "description": "A label indicating the attribute's function.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "primary", + "type": "boolean", + "multiValued": false, + "description": "A Boolean value indicating the 'primary' or preferred attribute value for this attribute. The primary attribute value 'true' MUST appear no more than once.", + "required": false, + "mutability": "readWrite", + "returned": "default" + } + ], + "mutability": "readWrite", + "returned": "default" + }, + { + "name": "roles", + "type": "complex", + "multiValued": true, + "description": "A list of roles for the User that collectively represent who the User is, e.g., 'Student', 'Faculty'.", + "required": false, + "subAttributes": [ + { + "name": "value", + "type": "string", + "multiValued": false, + "description": "The value of a role.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "display", + "type": "string", + "multiValued": false, + "description": "A human-readable name, primarily used for display purposes. READ-ONLY.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "type", + "type": "string", + "multiValued": false, + "description": "A label indicating the attribute's function.", + "required": false, + "caseExact": false, + "canonicalValues": [], + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "primary", + "type": "boolean", + "multiValued": false, + "description": "A Boolean value indicating the 'primary' or preferred attribute value for this attribute. The primary attribute value 'true' MUST appear no more than once.", + "required": false, + "mutability": "readWrite", + "returned": "default" + } + ], + "mutability": "readWrite", + "returned": "default" + }, + { + "name": "x509Certificates", + "type": "complex", + "multiValued": true, + "description": "A list of certificates issued to the User.", + "required": false, + "caseExact": false, + "subAttributes": [ + { + "name": "value", + "type": "binary", + "multiValued": false, + "description": "The value of an X.509 certificate.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "display", + "type": "string", + "multiValued": false, + "description": "A human-readable name, primarily used for display purposes. READ-ONLY.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "type", + "type": "string", + "multiValued": false, + "description": "A label indicating the attribute's function.", + "required": false, + "caseExact": false, + "canonicalValues": [], + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "primary", + "type": "boolean", + "multiValued": false, + "description": "A Boolean value indicating the 'primary' or preferred attribute value for this attribute. The primary attribute value 'true' MUST appear no more than once.", + "required": false, + "mutability": "readWrite", + "returned": "default" + } + ], + "mutability": "readWrite", + "returned": "default" + } + ], + "meta": { + "resourceType": "Schema", + "location": + "/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:User" + } + }, + { + "id": "urn:ietf:params:scim:schemas:core:2.0:Group", + "name": "Group", + "description": "Group", + "attributes": [ + { + "name": "displayName", + "type": "string", + "multiValued": false, + "description": "A human-readable name for the Group. REQUIRED.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "members", + "type": "complex", + "multiValued": true, + "description": "A list of members of the Group.", + "required": false, + "subAttributes": [ + { + "name": "value", + "type": "string", + "multiValued": false, + "description": "Identifier of the member of this Group.", + "required": false, + "caseExact": false, + "mutability": "immutable", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "$ref", + "type": "reference", + "referenceTypes": [ + "User", + "Group" + ], + "multiValued": false, + "description": "The URI corresponding to a SCIM resource that is a member of this Group.", + "required": false, + "caseExact": false, + "mutability": "immutable", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "type", + "type": "string", + "multiValued": false, + "description": "A label indicating the type of resource, e.g., 'User' or 'Group'.", + "required": false, + "caseExact": false, + "canonicalValues": [ + "User", + "Group" + ], + "mutability": "immutable", + "returned": "default", + "uniqueness": "none" + } + ], + "mutability": "readWrite", + "returned": "default" + } + ], + "meta": { + "resourceType": "Schema", + "location": + "/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:Group" + } + }, + { + "id": "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User", + "name": "EnterpriseUser", + "description": "Enterprise User", + "attributes": [ + { + "name": "employeeNumber", + "type": "string", + "multiValued": false, + "description": "Numeric or alphanumeric identifier assigned to a person, typically based on order of hire or association with an organization.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "costCenter", + "type": "string", + "multiValued": false, + "description": "Identifies the name of a cost center.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "organization", + "type": "string", + "multiValued": false, + "description": "Identifies the name of an organization.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "division", + "type": "string", + "multiValued": false, + "description": "Identifies the name of a division.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "department", + "type": "string", + "multiValued": false, + "description": "Identifies the name of a department.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "manager", + "type": "complex", + "multiValued": false, + "description": "The User's manager. A complex type that optionally allows service providers to represent organizational hierarchy by referencing the 'id' attribute of another User.", + "required": false, + "subAttributes": [ + { + "name": "value", + "type": "string", + "multiValued": false, + "description": "The id of the SCIM resource representing the User's manager. REQUIRED.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "$ref", + "type": "reference", + "referenceTypes": [ + "User" + ], + "multiValued": false, + "description": "The URI of the SCIM resource representing the User's manager. REQUIRED.", + "required": false, + "caseExact": false, + "mutability": "readWrite", + "returned": "default", + "uniqueness": "none" + }, + { + "name": "displayName", + "type": "string", + "multiValued": false, + "description": "The displayName of the User's manager. OPTIONAL and READ-ONLY.", + "required": false, + "caseExact": false, + "mutability": "readOnly", + "returned": "default", + "uniqueness": "none" + } + ], + "mutability": "readWrite", + "returned": "default" + } + ], + "meta": { + "resourceType": "Schema", + "location": "/v2/Schemas/urn:ietf:params:scim:schemas:extension:enterprise:2.0:User" + } + } +] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/logic/src/main/resources/scimv2-logic.properties ---------------------------------------------------------------------- diff --git a/ext/scimv2/logic/src/main/resources/scimv2-logic.properties b/ext/scimv2/logic/src/main/resources/scimv2-logic.properties new file mode 100644 index 0000000..2d85a37 --- /dev/null +++ b/ext/scimv2/logic/src/main/resources/scimv2-logic.properties @@ -0,0 +1,21 @@ +# 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. +conf.directory=${conf.directory} + +bulk.maxOperations=1000 +bulk.maxPayloadSize=1048576 +filter.maxResults=200 http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/pom.xml ---------------------------------------------------------------------- diff --git a/ext/scimv2/pom.xml b/ext/scimv2/pom.xml index 105853e..bc62e00 100644 --- a/ext/scimv2/pom.xml +++ b/ext/scimv2/pom.xml @@ -40,6 +40,7 @@ under the License. <modules> <module>scim-rest-api</module> <module>scim-rest-cxf</module> + <module>logic</module> </modules> </project> http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/AuthenticationScheme.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/AuthenticationScheme.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/AuthenticationScheme.java new file mode 100644 index 0000000..10e3f77 --- /dev/null +++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/AuthenticationScheme.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.ext.scimv2.api.data; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.net.URI; + +public class AuthenticationScheme extends SCIMBean { + + private static final long serialVersionUID = -1326661422976856869L; + + private final String name; + + private final String description; + + private final URI specUri; + + private final URI documentationUri; + + private final String type; + + private final boolean primary; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public AuthenticationScheme( + @JsonProperty("name") final String name, + @JsonProperty("description") final String description, + @JsonProperty("specUri") final URI specUri, + @JsonProperty("documentationUri") final URI documentationUri, + @JsonProperty("type") final String type, + @JsonProperty("primary") final boolean primary) { + + this.name = name; + this.description = description; + this.specUri = specUri; + this.documentationUri = documentationUri; + this.type = type; + this.primary = primary; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public URI getSpecUri() { + return specUri; + } + + public URI getDocumentationUri() { + return documentationUri; + } + + public String getType() { + return type; + } + + public boolean isPrimary() { + return primary; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/BulkConfigurationOption.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/BulkConfigurationOption.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/BulkConfigurationOption.java new file mode 100644 index 0000000..b81b652 --- /dev/null +++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/BulkConfigurationOption.java @@ -0,0 +1,51 @@ +/* + * 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.ext.scimv2.api.data; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class BulkConfigurationOption extends ConfigurationOption { + + private static final long serialVersionUID = 8218541842239260269L; + + private final int maxOperations; + + private final int maxPayloadSize; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public BulkConfigurationOption( + @JsonProperty("supported") final boolean supported, + @JsonProperty("maxOperations") final int maxOperations, + @JsonProperty("maxPayloadSize") final int maxPayloadSize) { + + super(supported); + this.maxOperations = maxOperations; + this.maxPayloadSize = maxPayloadSize; + } + + public int getMaxOperations() { + return maxOperations; + } + + public int getMaxPayloadSize() { + return maxPayloadSize; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ConfigurationOption.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ConfigurationOption.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ConfigurationOption.java new file mode 100644 index 0000000..821cae4 --- /dev/null +++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ConfigurationOption.java @@ -0,0 +1,39 @@ +/* + * 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.ext.scimv2.api.data; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ConfigurationOption extends SCIMBean { + + private static final long serialVersionUID = 5165678196717776426L; + + private final boolean supported; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public ConfigurationOption(@JsonProperty("supported") final boolean supported) { + this.supported = supported; + } + + public boolean isSupported() { + return supported; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/FilterConfigurationOption.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/FilterConfigurationOption.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/FilterConfigurationOption.java new file mode 100644 index 0000000..3eda87e --- /dev/null +++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/FilterConfigurationOption.java @@ -0,0 +1,43 @@ +/* + * 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.ext.scimv2.api.data; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class FilterConfigurationOption extends ConfigurationOption { + + private static final long serialVersionUID = 8218541842239260269L; + + private final int maxResults; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public FilterConfigurationOption( + @JsonProperty("supported") final boolean supported, + @JsonProperty("maxResults") final int maxResults) { + + super(supported); + this.maxResults = maxResults; + } + + public int getMaxResults() { + return maxResults; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java index 6983631..d20f50a 100644 --- a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java +++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ListResponse.java @@ -23,13 +23,13 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.apache.syncope.ext.scimv2.api.type.ResourceType; +import org.apache.syncope.ext.scimv2.api.type.Resource; public class ListResponse<R extends SCIMResource> extends SCIMBean { private static final long serialVersionUID = -776611610457583160L; - private final List<String> schemas = Arrays.asList(ResourceType.ListResponse.getSchema()); + private final List<String> schemas = Arrays.asList(Resource.ListResponse.schema()); private final int totalResults; http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java index 73c25eb..aa2f5dd 100644 --- a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java +++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Member.java @@ -21,7 +21,7 @@ package org.apache.syncope.ext.scimv2.api.data; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import org.apache.syncope.ext.scimv2.api.type.ResourceType; +import org.apache.syncope.ext.scimv2.api.type.Resource; @JsonPropertyOrder({ "value", "$ref", "display", "type" }) public class Member extends Reference { @@ -29,13 +29,13 @@ public class Member extends Reference { private static final long serialVersionUID = 75245960461062907L; @JsonIgnore - private final ResourceType type; + private final Resource type; public Member( @JsonProperty("value") final String value, @JsonProperty("$ref") final String ref, @JsonProperty("display") final String display, - @JsonProperty("type") final ResourceType type) { + @JsonProperty("type") final Resource type) { super(value, ref, display); this.type = type; http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java index 7ecb4af..661ec86 100644 --- a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java +++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/Meta.java @@ -21,16 +21,15 @@ package org.apache.syncope.ext.scimv2.api.data; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import java.io.Serializable; import java.util.Date; import javax.ws.rs.core.EntityTag; -import org.apache.syncope.ext.scimv2.api.type.ResourceType; +import org.apache.syncope.ext.scimv2.api.type.Resource; -public class Meta implements Serializable { +public class Meta extends SCIMBean { private static final long serialVersionUID = 8976451652101091915L; - private final ResourceType resourceType; + private final Resource resourceType; private final Date created; @@ -43,7 +42,7 @@ public class Meta implements Serializable { @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) public Meta( - @JsonProperty("resourceType") final ResourceType resourceType, + @JsonProperty("resourceType") final Resource resourceType, @JsonProperty("created") final Date created, @JsonProperty("lastModified") final Date lastModified, @JsonProperty("version") final String version, @@ -52,11 +51,11 @@ public class Meta implements Serializable { this.resourceType = resourceType; this.created = created; this.lastModified = lastModified; - this.version = new EntityTag(version); + this.version = version == null ? null : new EntityTag(version, true); this.location = location; } - public ResourceType getResourceType() { + public Resource getResourceType() { return resourceType; } http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ResourceType.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ResourceType.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ResourceType.java new file mode 100644 index 0000000..19dceac --- /dev/null +++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ResourceType.java @@ -0,0 +1,97 @@ +/* + * 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.ext.scimv2.api.data; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.apache.syncope.ext.scimv2.api.type.Resource; + +public class ResourceType extends SCIMBean { + + private static final long serialVersionUID = -6559584102333757279L; + + private final List<String> schemas = Arrays.asList(Resource.ResourceType.schema()); + + private final String id; + + private final String name; + + private final String endpoint; + + private final String description; + + private final String schema; + + private final List<SchemaExtension> schemaExtensions = new ArrayList<>(); + + private final Meta meta; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public ResourceType( + @JsonProperty("id") final String id, + @JsonProperty("name") final String name, + @JsonProperty("endpoint") final String endpoint, + @JsonProperty("description") final String description, + @JsonProperty("schema") final String schema, + @JsonProperty("meta") final Meta meta) { + + this.id = id; + this.name = name; + this.endpoint = endpoint; + this.description = description; + this.schema = schema; + this.meta = meta; + } + + public List<String> getSchemas() { + return schemas; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public String getEndpoint() { + return endpoint; + } + + public String getDescription() { + return description; + } + + public String getSchema() { + return schema; + } + + public List<SchemaExtension> getSchemaExtensions() { + return schemaExtensions; + } + + public Meta getMeta() { + return meta; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SchemaExtension.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SchemaExtension.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SchemaExtension.java new file mode 100644 index 0000000..fb2fe2e --- /dev/null +++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/SchemaExtension.java @@ -0,0 +1,49 @@ +/* + * 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.ext.scimv2.api.data; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class SchemaExtension extends SCIMBean { + + private static final long serialVersionUID = -2891887818183122384L; + + private final String schema; + + private final boolean required; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public SchemaExtension( + @JsonProperty("schema") final String schema, + @JsonProperty("required") final boolean required) { + + this.schema = schema; + this.required = required; + } + + public String getSchema() { + return schema; + } + + public boolean isRequired() { + return required; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ServiceProviderConfig.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ServiceProviderConfig.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ServiceProviderConfig.java new file mode 100644 index 0000000..3014a6c --- /dev/null +++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/data/ServiceProviderConfig.java @@ -0,0 +1,97 @@ +/* + * 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.ext.scimv2.api.data; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.apache.syncope.ext.scimv2.api.type.Resource; + +public class ServiceProviderConfig extends SCIMBean { + + private static final long serialVersionUID = 1027738509789460252L; + + private final List<String> schemas = Arrays.asList(Resource.ServiceProviderConfig.schema()); + + private final ConfigurationOption patch; + + private final BulkConfigurationOption bulk; + + private final FilterConfigurationOption filter; + + private final ConfigurationOption changePassword; + + private final ConfigurationOption sort; + + private final ConfigurationOption etag; + + private final List<AuthenticationScheme> authenticationSchemes = new ArrayList<>(); + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + public ServiceProviderConfig( + @JsonProperty("patch") final ConfigurationOption patch, + @JsonProperty("bulk") final BulkConfigurationOption bulk, + @JsonProperty("filter") final FilterConfigurationOption filter, + @JsonProperty("changePassword") final ConfigurationOption changePassword, + @JsonProperty("sort") final ConfigurationOption sort, + @JsonProperty("etag") final ConfigurationOption etag) { + + this.patch = patch; + this.bulk = bulk; + this.filter = filter; + this.changePassword = changePassword; + this.sort = sort; + this.etag = etag; + } + + public List<String> getSchemas() { + return schemas; + } + + public ConfigurationOption getPatch() { + return patch; + } + + public BulkConfigurationOption getBulk() { + return bulk; + } + + public FilterConfigurationOption getFilter() { + return filter; + } + + public ConfigurationOption getChangePassword() { + return changePassword; + } + + public ConfigurationOption getSort() { + return sort; + } + + public ConfigurationOption getEtag() { + return etag; + } + + public List<AuthenticationScheme> getAuthenticationSchemes() { + return authenticationSchemes; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java index c1bb82f..8881ec8 100644 --- a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java +++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/GroupService.java @@ -32,7 +32,7 @@ import org.apache.cxf.jaxrs.ext.PATCH; import org.apache.syncope.ext.scimv2.api.SCIMConstants; import org.apache.syncope.ext.scimv2.api.data.SCIMGroup; -@Path("Groups") +@Path("v2/Groups") public interface GroupService extends SCIMService<SCIMGroup> { @POST http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java index 8de7a0a..6e9b201 100644 --- a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java +++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/RootService.java @@ -18,28 +18,42 @@ */ package org.apache.syncope.ext.scimv2.api.service; +import java.util.List; import javax.ws.rs.GET; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Response; import org.apache.syncope.ext.scimv2.api.SCIMConstants; +import org.apache.syncope.ext.scimv2.api.data.ResourceType; +import org.apache.syncope.ext.scimv2.api.data.SCIMResource; +import org.apache.syncope.ext.scimv2.api.data.ServiceProviderConfig; -@Path("") -public interface RootService extends SCIMService { +@Path("v2") +public interface RootService extends SCIMService<SCIMResource> { @GET - @Path("ServiceProviderConfigs") + @Path("ServiceProviderConfig") @Produces({ SCIMConstants.APPLICATION_SCIM_JSON }) - Response serviceProviderConfigs(); + ServiceProviderConfig serviceProviderConfig(); @GET @Path("ResourceTypes") @Produces({ SCIMConstants.APPLICATION_SCIM_JSON }) - Response resourceTypes(); + List<ResourceType> resourceTypes(); + + @GET + @Path("ResourceTypes/{type}") + @Produces({ SCIMConstants.APPLICATION_SCIM_JSON }) + ResourceType resourceType(@PathParam("type") String type); @GET @Path("Schemas") @Produces({ SCIMConstants.APPLICATION_SCIM_JSON }) Response schemas(); + @GET + @Path("Schemas/{schema}") + @Produces({ SCIMConstants.APPLICATION_SCIM_JSON }) + Response schema(@PathParam("schema") String schema); } http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java index 73518b5..8003b66 100644 --- a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java +++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/service/UserService.java @@ -32,7 +32,7 @@ import org.apache.cxf.jaxrs.ext.PATCH; import org.apache.syncope.ext.scimv2.api.SCIMConstants; import org.apache.syncope.ext.scimv2.api.data.SCIMUser; -@Path("Users") +@Path("v2/Users") public interface UserService extends SCIMService<SCIMUser> { @POST http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java new file mode 100644 index 0000000..37b15b6 --- /dev/null +++ b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/Resource.java @@ -0,0 +1,41 @@ +/* + * 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.ext.scimv2.api.type; + +public enum Resource { + + ServiceProviderConfig("urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"), + ResourceType("urn:ietf:params:scim:schemas:core:2.0:ResourceType"), + Schema("urn:ietf:params:scim:schemas:core:2.0:Schema"), + User("urn:ietf:params:scim:schemas:core:2.0:User"), + EnterpriseUser("urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"), + Group("urn:ietf:params:scim:schemas:core:2.0:Group"), + ListResponse("urn:ietf:params:scim:api:messages:2.0:ListResponse"); + + private final String schema; + + Resource(final String schema) { + this.schema = schema; + } + + public String schema() { + return schema; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java b/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java deleted file mode 100644 index faf5ccc..0000000 --- a/ext/scimv2/scim-rest-api/src/main/java/org/apache/syncope/ext/scimv2/api/type/ResourceType.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.ext.scimv2.api.type; - -public enum ResourceType { - - User("urn:ietf:params:scim:schemas:core:2.0:User"), - Group("urn:ietf:params:scim:schemas:core:2.0:Group"), - ListResponse("urn:ietf:params:scim:api:messages:2.0:ListResponse"); - - private final String schema; - - ResourceType(final String schema) { - this.schema = schema; - } - - public String getSchema() { - return schema; - } - -} http://git-wip-us.apache.org/repos/asf/syncope/blob/f04ab6c2/ext/scimv2/scim-rest-cxf/pom.xml ---------------------------------------------------------------------- diff --git a/ext/scimv2/scim-rest-cxf/pom.xml b/ext/scimv2/scim-rest-cxf/pom.xml index ffa7483..25a9249 100644 --- a/ext/scimv2/scim-rest-cxf/pom.xml +++ b/ext/scimv2/scim-rest-cxf/pom.xml @@ -98,13 +98,8 @@ under the License. </dependency> <dependency> - <groupId>org.apache.syncope.core</groupId> - <artifactId>syncope-core-logic</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> <groupId>org.apache.syncope.ext.scimv2</groupId> - <artifactId>syncope-ext-scimv2-scim-rest-api</artifactId> + <artifactId>syncope-ext-scimv2-logic</artifactId> <version>${project.version}</version> </dependency> </dependencies>