SYNCOPE-701 first working implementation
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/223a64e2 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/223a64e2 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/223a64e2 Branch: refs/heads/SYNCOPE-156 Commit: 223a64e26deff69a4ed8275d0f1348ca4e130a01 Parents: 764fa2e Author: Andrea Patricelli <[email protected]> Authored: Mon Oct 5 15:12:55 2015 +0200 Committer: Andrea Patricelli <[email protected]> Committed: Fri Oct 30 10:26:17 2015 +0100 ---------------------------------------------------------------------- client/enduser/pom.xml | 194 +++++++++ .../enduser/SyncopeEnduserApplication.java | 157 +++++++ .../client/enduser/SyncopeEnduserSession.java | 279 +++++++++++++ .../client/enduser/adapters/UserTOAdapter.java | 78 ++++ .../client/enduser/model/Credentials.java | 65 +++ .../client/enduser/model/SchemaResponse.java | 79 ++++ .../client/enduser/model/UserTORequest.java | 174 ++++++++ .../syncope/client/enduser/pages/HomePage.java | 35 ++ .../enduser/resources/AbstractBaseResource.java | 58 +++ .../client/enduser/resources/ErrorResource.java | 50 +++ .../client/enduser/resources/LoginResource.java | 84 ++++ .../enduser/resources/LogoutResource.java | 43 ++ .../enduser/resources/SchemaResource.java | 116 ++++++ .../resources/SecurityQuestionResource.java | 73 ++++ .../resources/UserSelfCreateResource.java | 97 +++++ .../enduser/resources/UserSelfReadResource.java | 66 +++ .../resources/UserSelfUpdateResource.java | 96 +++++ .../META-INF/resources/app/css/app.css | 28 ++ .../META-INF/resources/app/css/editUser.css | 253 ++++++++++++ .../META-INF/resources/app/css/login.css | 103 +++++ .../META-INF/resources/app/img/ajax-loader.gif | Bin 0 -> 1924 bytes .../META-INF/resources/app/img/busy.gif | Bin 0 -> 2834 bytes .../META-INF/resources/app/img/favicon.png | Bin 0 -> 641 bytes .../META-INF/resources/app/img/logo-green.png | Bin 0 -> 12178 bytes .../META-INF/resources/app/img/logo.png | Bin 0 -> 8913 bytes .../resources/META-INF/resources/app/index.html | 116 ++++++ .../resources/META-INF/resources/app/js/app.js | 283 +++++++++++++ .../app/js/controllers/HomeController.js | 39 ++ .../app/js/controllers/LanguageController.js | 66 +++ .../app/js/controllers/LoginController.js | 93 +++++ .../app/js/controllers/UserController.js | 206 +++++++++ .../app/js/directives/dynamicAttribute.js | 190 +++++++++ .../js/directives/dynamicDerivedAttributes.js | 52 +++ .../app/js/directives/dynamicPlainAttributes.js | 45 ++ .../js/directives/dynamicVirtualAttributes.js | 52 +++ .../resources/app/js/directives/equals.js | 49 +++ .../resources/app/js/directives/loader.js | 32 ++ .../app/js/directives/navigationButtons.js | 31 ++ .../js/directives/passwordStrengthEstimator.js | 102 +++++ .../resources/app/js/filters/propsFilter.js | 52 +++ .../resources/app/js/services/authService.js | 74 ++++ .../resources/app/js/services/realmService.js | 47 +++ .../resources/app/js/services/schemaService.js | 42 ++ .../app/js/services/securityQuestionService.js | 41 ++ .../app/js/services/userSelfService.js | 69 ++++ .../resources/app/views/dynamicAttribute.html | 58 +++ .../app/views/dynamicDerivedAttributes.html | 21 + .../app/views/dynamicPlainAttributes.html | 22 + .../app/views/dynamicVirtualAttributes.html | 18 + .../META-INF/resources/app/views/editUser.html | 73 ++++ .../resources/app/views/generic-error.html | 24 ++ .../META-INF/resources/app/views/home.html | 34 ++ .../resources/app/views/navigationButtons.html | 8 + .../META-INF/resources/app/views/self.html | 131 ++++++ .../resources/app/views/user-credentials.html | 60 +++ .../app/views/user-derived-schemas.html | 37 ++ .../resources/app/views/user-groups.html | 37 ++ .../resources/app/views/user-plain-schemas.html | 37 ++ .../resources/app/views/user-resources.html | 28 ++ .../app/views/user-virtual-schemas.html | 37 ++ .../main/resources/META-INF/web-fragment.xml | 72 ++++ .../src/main/resources/enduser.properties | 30 ++ .../syncope/client/enduser/pages/HomePage.html | 22 + .../enduser/SyncopeEnduserApplicationTest.java | 69 ++++ client/pom.xml | 1 + .../syncope/common/lib/types/Entitlement.java | 10 - .../syncope/core/logic/AnyTypeClassLogic.java | 4 +- .../apache/syncope/core/logic/AnyTypeLogic.java | 4 +- .../apache/syncope/core/logic/SchemaLogic.java | 2 +- .../core/reference/AuthenticationITCase.java | 11 - fit/enduser-reference/pom.xml | 413 +++++++++++++++++++ .../src/main/resources/context.xml | 23 ++ .../src/main/resources/enduser.properties | 30 ++ .../src/main/resources/log4j2.xml | 58 +++ .../src/main/webapp/WEB-INF/glassfish-web.xml | 25 ++ .../WEB-INF/jboss-deployment-structure.xml | 37 ++ .../src/main/webapp/WEB-INF/weblogic.xml | 35 ++ fit/pom.xml | 1 + pom.xml | 89 +++- 79 files changed, 5343 insertions(+), 27 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/pom.xml ---------------------------------------------------------------------- diff --git a/client/enduser/pom.xml b/client/enduser/pom.xml new file mode 100644 index 0000000..a9dc260 --- /dev/null +++ b/client/enduser/pom.xml @@ -0,0 +1,194 @@ +<?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</groupId> + <artifactId>syncope-client</artifactId> + <version>2.0.0-SNAPSHOT</version> + </parent> + + <name>Apache Syncope Client Enduser</name> + <description>Apache Syncope Client Enduser</description> + <groupId>org.apache.syncope.client</groupId> + <artifactId>syncope-client-enduser</artifactId> + <packaging>jar</packaging> + + <properties> + <rootpom.basedir>${basedir}/../..</rootpom.basedir> + </properties> + + <dependencies> + + <dependency> + <groupId>org.apache.syncope.core</groupId> + <artifactId>syncope-core-misc</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.apache.wicket</groupId> + <artifactId>wicket</artifactId> + <type>pom</type> + </dependency> + <dependency> + <groupId>org.apache.wicket</groupId> + <artifactId>wicket-extensions</artifactId> + </dependency> + <dependency> + <groupId>org.apache.wicket</groupId> + <artifactId>wicket-datetime</artifactId> + </dependency> + <dependency> + <groupId>org.apache.wicket</groupId> + <artifactId>wicket-spring</artifactId> + </dependency> + <dependency> + <groupId>org.apache.wicket</groupId> + <artifactId>wicket-auth-roles</artifactId> + </dependency> + + <!--AngularJS--> + <dependency> + <groupId>org.webjars.bower</groupId> + <artifactId>angular</artifactId> + </dependency> + <dependency> + <groupId>org.webjars.bower</groupId> + <artifactId>angular-route</artifactId> + </dependency> + <dependency> + <groupId>org.webjars.bower</groupId> + <artifactId>angular-resource</artifactId> + </dependency> + <dependency> + <groupId>org.webjars</groupId> + <artifactId>angular-ui-router</artifactId> + </dependency> + <dependency> + <groupId>org.webjars.bower</groupId> + <artifactId>angular-animate</artifactId> + </dependency> + <dependency> + <groupId>org.webjars.bower</groupId> + <artifactId>angular-cookies</artifactId> + </dependency> + <dependency> + <groupId>org.webjars</groupId> + <artifactId>angular-growl-2</artifactId> + </dependency> + <!--Bootstrap--> + <dependency> + <groupId>org.webjars</groupId> + <artifactId>font-awesome</artifactId> + </dependency> + <dependency> + <groupId>org.webjars</groupId> + <artifactId>bootstrap-select</artifactId> + </dependency> + <dependency> + <groupId>org.webjars</groupId> + <artifactId>bootstrap</artifactId> + </dependency> + <dependency> + <groupId>org.webjars</groupId> + <artifactId>ionicons</artifactId> + </dependency> + <dependency> + <groupId>org.webjars</groupId> + <artifactId>angular-ui-bootstrap</artifactId> + </dependency> + <dependency> + <groupId>org.webjars</groupId> + <artifactId>angular-ui-select</artifactId> + </dependency> + <dependency> + <groupId>org.webjars.bower</groupId> + <artifactId>angular-sanitize</artifactId> + </dependency> + <dependency> + <groupId>org.webjars.bower</groupId> + <artifactId>select2</artifactId> + </dependency> + <dependency> + <groupId>org.webjars.bower</groupId> + <artifactId>FileSaver.js</artifactId> + </dependency> + + <!--Jquery--> + <dependency> + <groupId>org.webjars</groupId> + <artifactId>jquery</artifactId> + </dependency> + <dependency> + <groupId>org.webjars</groupId> + <artifactId>jquery-cookie</artifactId> + </dependency> + <dependency> + <groupId>org.webjars</groupId> + <artifactId>jquery-ui</artifactId> + </dependency> + + <!--Logging--> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.syncope.client</groupId> + <artifactId>syncope-client-lib</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- TEST --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + </plugin> + </plugins> + + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource> + </resources> + + </build> + +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/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 new file mode 100644 index 0000000..4acc756 --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserApplication.java @@ -0,0 +1,157 @@ +/* + * 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; + +import java.io.Serializable; +import org.apache.syncope.client.enduser.pages.HomePage; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import org.apache.syncope.client.enduser.resources.ErrorResource; +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.UserSelfCreateResource; +import org.apache.syncope.client.enduser.resources.UserSelfReadResource; +import org.apache.syncope.client.enduser.resources.UserSelfUpdateResource; +import org.apache.wicket.Page; +import org.apache.wicket.Session; +import org.apache.wicket.protocol.http.WebApplication; +import org.apache.wicket.request.Request; +import org.apache.wicket.request.Response; +import org.apache.wicket.request.resource.IResource; +import org.apache.wicket.request.resource.ResourceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SyncopeEnduserApplication extends WebApplication implements Serializable { + + private static final long serialVersionUID = -6445919351044845120L; + + private static final Logger LOG = LoggerFactory.getLogger(SyncopeEnduserApplication.class); + + public static final List<Locale> SUPPORTED_LOCALES = Collections.unmodifiableList(Arrays.asList( + new Locale[] { + Locale.ENGLISH, Locale.ITALIAN, new Locale("pt", "BR") + })); + + @Override + protected void init() { + super.init(); + + LOG.debug("init SyncopeEnduserApplication"); + + // resource to provide login functionality managed by wicket + mountResource("/api/login", new ResourceReference("login") { + + private static final long serialVersionUID = -128426276529456602L; + + @Override + public IResource getResource() { + return new LoginResource(); + } + }); + + // resource to provide logout functionality managed by wicket + mountResource("/api/logout", new ResourceReference("logout") { + + private static final long serialVersionUID = -128426276529456602L; + + @Override + public IResource getResource() { + return new LogoutResource(); + } + }); + + // resource to retrieve info about logged user + mountResource("/api/self/read", new ResourceReference("userSelfRead") { + + private static final long serialVersionUID = -128426276529456602L; + + @Override + public IResource getResource() { + return new UserSelfReadResource(); + } + }); + + // resource to provide user self create functionality managed by wicket + mountResource("/api/self/create", new ResourceReference("userSelfCreate") { + + private static final long serialVersionUID = -128426276529456602L; + + @Override + public IResource getResource() { + return new UserSelfCreateResource(); + } + }); + + // resource to provide user self update functionality managed by wicket + mountResource("/api/self/update", new ResourceReference("userSelfUpdate") { + + private static final long serialVersionUID = -128426276529456602L; + + @Override + public IResource getResource() { + return new UserSelfUpdateResource(); + } + }); + + mountResource("/api/schemas", new ResourceReference("schemas") { + + private static final long serialVersionUID = -128426276529456602L; + + @Override + public IResource getResource() { + return new SchemaResource(); + } + }); + + mountResource("/api/securityQuestions", new ResourceReference("securityQuestions") { + + private static final long serialVersionUID = -128426276529456602L; + + @Override + public IResource getResource() { + return new SecurityQuestionResource(); + } + }); + + mountResource("/api/error", new ResourceReference("error") { + + private static final long serialVersionUID = -128426276529456602L; + + @Override + public IResource getResource() { + return new ErrorResource(); + } + }); + } + + @Override + public Class<? extends Page> getHomePage() { + return HomePage.class; + } + + @Override + public Session newSession(final Request request, final Response response) { + return new SyncopeEnduserSession(request); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java new file mode 100644 index 0000000..c5abc1d --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/SyncopeEnduserSession.java @@ -0,0 +1,279 @@ +/* + * 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; + +import java.io.File; +import java.text.DateFormat; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import javax.ws.rs.core.EntityTag; +import javax.ws.rs.core.MediaType; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.cxf.jaxrs.client.WebClient; +import org.apache.syncope.client.lib.SyncopeClient; +import org.apache.syncope.client.lib.SyncopeClientFactoryBean; +import org.apache.syncope.common.lib.SyncopeConstants; +import org.apache.syncope.common.lib.to.SyncopeTO; +import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.common.rest.api.service.SyncopeService; +import org.apache.wicket.Session; +import org.apache.wicket.protocol.http.WebSession; +import org.apache.wicket.request.Request; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Custom Syncope Enduser Session class. + */ +public class SyncopeEnduserSession extends WebSession { + + private static final long serialVersionUID = 1284946129513378647L; + + private static final Logger LOG = LoggerFactory.getLogger(SyncopeEnduserSession.class); + + public static final List<Locale> SUPPORTED_LOCALES = Arrays.asList(new Locale[] { + Locale.ENGLISH, Locale.ITALIAN, new Locale("pt", "BR") }); + + protected static final String ENDUSER_PROPERTIES = "enduser.properties"; + + private String username; + + private String password; + + private String scheme; + + private String host; + + private String port; + + private String rootPath; + + private String anonymousUser; + + private String anonymousKey; + + private Boolean storePassword; + + private String version; + + private String license; + + private final SyncopeClientFactoryBean clientFactory; + + private SyncopeClient client; + + private final SyncopeClient anonymousClient; + + private final SyncopeTO syncopeTO; + + private UserTO selfTO; + + private final Map<Class<?>, Object> services = Collections.synchronizedMap(new HashMap<Class<?>, Object>()); + + public static SyncopeEnduserSession get() { + return (SyncopeEnduserSession) Session.get(); + } + + public SyncopeEnduserSession(final Request request) { + super(request); + + // load properties from classpath file + loadProperties(); + + clientFactory = new SyncopeClientFactoryBean(); + clientFactory.setAddress(new StringBuilder(scheme) + .append("://") + .append(host) + .append(":") + .append(port) + .append("/") + .append(rootPath) + .toString()); + clientFactory.setContentType(SyncopeClientFactoryBean.ContentType.JSON); + + anonymousClient = clientFactory.create(anonymousUser, anonymousKey); + syncopeTO = anonymousClient.getService(SyncopeService.class).info(); + + } + + public boolean authenticate(final String username, final String password) { + boolean authenticated = false; + + try { + client = clientFactory.setDomain(SyncopeConstants.MASTER_DOMAIN).create(username, password); + + Pair<Map<String, Set<String>>, UserTO> self = client.self(); + selfTO = self.getValue(); + + this.username = username; + this.password = password; + // bind explicitly this session to have a stateful behavior during http requests, unless session will expire + // for every request + this.bind(); + authenticated = true; + } catch (Exception e) { + LOG.error("Authentication failed", e); + } + + return authenticated; + } + + public <T> void resetClient(final Class<T> service) { + T serviceInstance = getCachedService(service); + WebClient.client(serviceInstance).reset(); + } + + @SuppressWarnings("unchecked") + private <T> T getCachedService(final Class<T> serviceClass) { + T service; + if (services.containsKey(serviceClass)) { + service = (T) services.get(serviceClass); + } else { + service = client == null ? anonymousClient.getService(serviceClass) : client.getService(serviceClass); + services.put(serviceClass, service); + } + + return service; + } + + public <T> T getService(final Class<T> serviceClass) { + return getCachedService(serviceClass); + } + + public <T> T getService(final String etag, final Class<T> serviceClass) { + T serviceInstance = getCachedService(serviceClass); + WebClient.client(serviceInstance).match(new EntityTag(etag), false). + type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON); + + return serviceInstance; + } + + public <T> T getService(final MediaType mediaType, final Class<T> serviceClass) { + T service; + + synchronized (clientFactory) { + SyncopeClientFactoryBean.ContentType preType = clientFactory.getContentType(); + + clientFactory.setContentType(SyncopeClientFactoryBean.ContentType.fromString(mediaType.toString())); + service = clientFactory.create(username, password).getService(serviceClass); + clientFactory.setContentType(preType); + } + + return service; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public String getScheme() { + return scheme; + } + + public String getHost() { + return host; + } + + public String getPort() { + return port; + } + + public String getRootPath() { + return rootPath; + } + + public String getAnonymousUser() { + return anonymousUser; + } + + public String getAnonymousKey() { + return anonymousKey; + } + + public Boolean storePassword() { + return this.storePassword; + } + + public String getVersion() { + return version; + } + + public String getLicense() { + return license; + } + + public SyncopeTO getSyncopeTO() { + return syncopeTO; + } + + public UserTO getSelfTO() { + return selfTO; + } + + public boolean isAuthenticated() { + return getUsername() != null; + } + + public DateFormat getDateFormat() { + final Locale locale = getLocale() == null ? Locale.ENGLISH : getLocale(); + + return DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale); + } + + private void loadProperties() { + Properties properties = new Properties(); + + try { + properties.load(getClass().getResourceAsStream("/" + ENDUSER_PROPERTIES)); + File enduserDir = new File(properties.getProperty("enduser.directory")); + if (enduserDir.exists() && enduserDir.canRead() && enduserDir.isDirectory()) { + File enduserDirProps = FileUtils.getFile(enduserDir, ENDUSER_PROPERTIES); + if (enduserDirProps.exists() && enduserDirProps.canRead() && enduserDirProps.isFile()) { + properties.clear(); + properties.load(FileUtils.openInputStream(enduserDir)); + } + } + } catch (Exception e) { + LOG.error("Error loading {} file", ENDUSER_PROPERTIES, e); +// throw new WicketRuntimeException("Could not read " + ENDUSER_PROPERTIES, e); + } + + this.scheme = properties.getProperty("scheme"); + this.host = properties.getProperty("host"); + this.port = properties.getProperty("port"); + this.rootPath = properties.getProperty("rootPath"); + this.anonymousUser = properties.getProperty("anonymousUser"); + this.anonymousKey = properties.getProperty("anonymousKey"); + this.storePassword = Boolean.valueOf(properties.getProperty("storePassword")); + version = properties.getProperty("version"); + license = properties.getProperty("license"); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/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 new file mode 100644 index 0000000..551555f --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/adapters/UserTOAdapter.java @@ -0,0 +1,78 @@ +/* + * 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.adapters; + +import org.apache.syncope.client.enduser.model.UserTORequest; +import org.apache.syncope.common.lib.to.UserTO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class UserTOAdapter { + + private static final Logger LOG = LoggerFactory.getLogger(UserTOAdapter.class); + + public UserTO fromUserTORequest(final UserTORequest userTORequest, final String oldSelfPassword) { + + // adapter code, to be moved in a new utility class + final UserTO userTO = new UserTO(); + // set key if in update mode + final Long key = userTORequest.getKey(); + if (key != null) { + userTO.setKey(key); + } + // set username... + userTO.setUsername(userTORequest.getUsername()); + // ...and password + String requestPassword = userTORequest.getPassword(); + if (requestPassword == null || requestPassword.isEmpty()) { + userTO.setPassword(oldSelfPassword == null ? null : oldSelfPassword); + } else { + userTO.setPassword(requestPassword); + } + + //set security question and answer + userTO.setSecurityQuestion(userTORequest.getSecurityQuestion()); + userTO.setSecurityAnswer(userTORequest.getSecurityAnswer()); + //set realm + userTO.setRealm(userTORequest.getRealm()); + // add attributes + userTO.getPlainAttrs().addAll(userTORequest.getPlainAttrs().values()); + userTO.getDerAttrs().addAll(userTORequest.getDerAttrs().values()); + userTO.getVirAttrs().addAll(userTORequest.getVirAttrs().values()); + + return userTO; + } + + public UserTORequest toUserTORequest(final UserTO userTO) { + + final UserTORequest userTORequest = new UserTORequest(). + key(userTO.getKey()). + username(userTO.getUsername()). + securityQuestion(userTO.getSecurityQuestion()). + securityAnswer(userTO.getSecurityAnswer()). + realm(userTO.getRealm()); + + userTORequest.getPlainAttrs().putAll(userTO.getPlainAttrMap()); + userTORequest.getDerAttrs().putAll(userTO.getDerAttrMap()); + userTORequest.getVirAttrs().putAll(userTO.getVirAttrMap()); + + return userTORequest; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/Credentials.java ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/Credentials.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/Credentials.java new file mode 100644 index 0000000..68e3106 --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/Credentials.java @@ -0,0 +1,65 @@ +/* + * 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.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.apache.commons.lang3.builder.ToStringBuilder; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Credentials { + + private String username; + + private String password; + + public Credentials() { + } + + public String getUsername() { + return username; + } + + public void setUsername(final String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(final String password) { + this.password = password; + } + + public Credentials username(final String username) { + this.username = username; + return this; + } + + public Credentials password(final String password) { + this.password = password; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/SchemaResponse.java ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/SchemaResponse.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/SchemaResponse.java new file mode 100644 index 0000000..912f287 --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/SchemaResponse.java @@ -0,0 +1,79 @@ +/* + * 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.model; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import org.apache.syncope.common.lib.to.DerSchemaTO; +import org.apache.syncope.common.lib.to.PlainSchemaTO; +import org.apache.syncope.common.lib.to.VirSchemaTO; + +public class SchemaResponse implements Serializable { + + private static final long serialVersionUID = -8896862106241712829L; + + private List<PlainSchemaTO> plainSchemas = new ArrayList<>(); + + private List<DerSchemaTO> derSchemas = new ArrayList<>(); + + private List<VirSchemaTO> virSchemas = new ArrayList<>(); + + public SchemaResponse() { + } + + public List<PlainSchemaTO> getPlainSchemas() { + return plainSchemas; + } + + public void setPlainSchemas(final List<PlainSchemaTO> plainSchemas) { + this.plainSchemas = plainSchemas; + } + + public List<DerSchemaTO> getDerSchemas() { + return derSchemas; + } + + public void setDerSchemas(final List<DerSchemaTO> derSchemas) { + this.derSchemas = derSchemas; + } + + public List<VirSchemaTO> getVirSchemas() { + return virSchemas; + } + + public void setVirSchemas(final List<VirSchemaTO> virSchemas) { + this.virSchemas = virSchemas; + } + + public SchemaResponse plainSchemas(final List<PlainSchemaTO> value) { + this.plainSchemas = value; + return this; + } + + public SchemaResponse derSchemas(final List<DerSchemaTO> value) { + this.derSchemas = value; + return this; + } + + public SchemaResponse virSchemas(final List<VirSchemaTO> value) { + this.virSchemas = value; + return this; + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/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 new file mode 100644 index 0000000..09bc219 --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/model/UserTORequest.java @@ -0,0 +1,174 @@ +/* + * 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.model; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.syncope.common.lib.to.AttrTO; + +public class UserTORequest implements Serializable { + + private static final long serialVersionUID = -6763020920564016374L; + + private Long key; + + private String username; + + private String password; + + private Long securityQuestion; + + private String securityAnswer; + + private String realm; + + private Map<String, AttrTO> plainAttrs = new HashMap<>(); + + private Map<String, AttrTO> derAttrs = new HashMap<>(); + + private Map<String, AttrTO> virAttrs = new HashMap<>(); + + public UserTORequest() { + } + + public Long getKey() { + return key; + } + + public void setKey(final Long key) { + this.key = key; + } + + public String getUsername() { + return username; + } + + public void setUsername(final String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(final String password) { + this.password = password; + } + + public Long getSecurityQuestion() { + return securityQuestion; + } + + public void setSecurityQuestion(final Long securityQuestion) { + this.securityQuestion = securityQuestion; + } + + public String getSecurityAnswer() { + return securityAnswer; + } + + public void setSecurityAnswer(final String securityAnswer) { + this.securityAnswer = securityAnswer; + } + + public String getRealm() { + return realm; + } + + public void setRealm(final String realm) { + this.realm = realm; + } + + public Map<String, AttrTO> getPlainAttrs() { + return plainAttrs; + } + + public void setPlainAttrs(final Map<String, AttrTO> plainAttrs) { + this.plainAttrs = plainAttrs; + } + + public Map<String, AttrTO> getDerAttrs() { + return derAttrs; + } + + public void setDerAttrs(final Map<String, AttrTO> derAttrs) { + this.derAttrs = derAttrs; + } + + public Map<String, AttrTO> getVirAttrs() { + return virAttrs; + } + + public void setVirAttrs(final Map<String, AttrTO> virAttrs) { + this.virAttrs = virAttrs; + } + + public UserTORequest key(final Long value) { + this.key = value; + return this; + } + + public UserTORequest username(final String value) { + this.username = value; + return this; + } + + public UserTORequest password(final String value) { + this.password = value; + return this; + } + + public UserTORequest securityQuestion(final Long value) { + this.securityQuestion = value; + return this; + } + + public UserTORequest securityAnswer(final String value) { + this.securityAnswer = value; + return this; + } + + public UserTORequest realm(final String value) { + this.realm = value; + return this; + } + + public UserTORequest plainAttrs(final Map<String, AttrTO> value) { + this.plainAttrs = value; + return this; + } + + public UserTORequest derAttrs(final Map<String, AttrTO> value) { + this.derAttrs = value; + return this; + } + + public UserTORequest virAttrs(final Map<String, AttrTO> value) { + this.virAttrs = value; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/pages/HomePage.java ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/pages/HomePage.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/pages/HomePage.java new file mode 100644 index 0000000..4c5c07e --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/pages/HomePage.java @@ -0,0 +1,35 @@ +/* + * 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.pages; + +import org.apache.wicket.NonResettingRestartException; +import org.apache.wicket.markup.html.WebPage; +import org.apache.wicket.request.mapper.parameter.PageParameters; + +public class HomePage extends WebPage { + + private static final long serialVersionUID = -3422492668689122688L; + + public HomePage(final PageParameters parameters) { + super(parameters); +// throw new RedirectToUrlException("/app/"); + throw new NonResettingRestartException("/app/"); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java new file mode 100644 index 0000000..a3aedfc --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/AbstractBaseResource.java @@ -0,0 +1,58 @@ +/* + * 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 org.apache.syncope.client.enduser.SyncopeEnduserSession; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.wicket.request.resource.AbstractResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractBaseResource extends AbstractResource { + + private static final long serialVersionUID = -7875801358718612782L; + + private static final Logger LOG = LoggerFactory.getLogger(AbstractBaseResource.class); + + protected <T> T getService(final Class<T> serviceClass) { + return SyncopeEnduserSession.get().getService(serviceClass); + } + + protected <T> T getService(final String etag, final Class<T> serviceClass) { + return SyncopeEnduserSession.get().getService(etag, serviceClass); + } + + protected <T> void resetClient(final Class<T> serviceClass) { + SyncopeEnduserSession.get().resetClient(serviceClass); + } + + protected boolean isSelfRegistrationAllowed() { + Boolean result = null; + try { + result = SyncopeEnduserSession.get().getSyncopeTO().isSelfRegAllowed(); + } catch (SyncopeClientException e) { + LOG.error("While seeking if self registration is allowed", e); + } + + return result == null + ? false + : result; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/ErrorResource.java ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/ErrorResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/ErrorResource.java new file mode 100644 index 0000000..bfceeab --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/ErrorResource.java @@ -0,0 +1,50 @@ +/* + * 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 javax.ws.rs.core.MediaType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Mirror REST resource for obtaining user self operations. + * + * @see org.apache.syncope.common.rest.api + */ +public class ErrorResource extends AbstractBaseResource { + + private static final long serialVersionUID = -9184809392631523912L; + + /** + * Logger. + */ + private static final Logger LOG = LoggerFactory.getLogger(ErrorResource.class); + + @Override + protected ResourceResponse newResourceResponse(final Attributes attributes) { + + ResourceResponse response = new ResourceResponse(); + response.disableCaching(); + response.setContentType(MediaType.APPLICATION_JSON); + + response.setStatusCode(403); + + return response; + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java new file mode 100644 index 0000000..fa6fa8c --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LoginResource.java @@ -0,0 +1,84 @@ +/* + * 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 org.apache.commons.lang3.StringUtils; +import org.apache.syncope.client.enduser.model.Credentials; +import org.apache.syncope.client.enduser.SyncopeEnduserSession; +import org.apache.syncope.core.misc.serialization.POJOHelper; +import org.apache.wicket.util.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LoginResource extends AbstractBaseResource { + + private static final long serialVersionUID = -7720997467070461915L; + + private static final Logger LOG = LoggerFactory.getLogger(LoginResource.class); + + public LoginResource() { + } + + @Override + protected ResourceResponse newResourceResponse(final Attributes attributes) { + + int responseStatus; + final String responseMessage; + ResourceResponse response = new ResourceResponse(); + + try { + HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest(); + Credentials credentials = POJOHelper.deserialize(IOUtils.toString(request.getInputStream()), + Credentials.class); + final String username = credentials.getUsername(); + final String password = credentials.getPassword().isEmpty() ? null : credentials.getPassword(); + + LOG.debug("Enduser login, user: {}", username); + + if (StringUtils.isBlank(username)) { + LOG.error("Could not read credentials from request: username is blank!"); + responseMessage = "Could not read credentials from request: username is blank!"; + responseStatus = 400; + } else { + // authenticate user + final boolean authenticated = SyncopeEnduserSession.get().authenticate(username, password); + responseStatus = authenticated ? 200 : 401; + responseMessage = username; + } + + response.setWriteCallback(new WriteCallback() { + + @Override + public void writeData(final Attributes attributes) throws IOException { + attributes.getResponse().write(responseMessage); + } + }); + + } catch (Exception e) { + responseStatus = 400; + LOG.error("Could not read credentials from request", e); + } + + response.setStatusCode(responseStatus); + return response; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LogoutResource.java ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LogoutResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LogoutResource.java new file mode 100644 index 0000000..545b44d --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/LogoutResource.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.client.enduser.resources; + +import org.apache.syncope.client.enduser.SyncopeEnduserSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LogoutResource extends AbstractBaseResource { + + private static final long serialVersionUID = -648841355644985051L; + + private static final Logger LOG = LoggerFactory.getLogger(LogoutResource.class); + + @Override + protected ResourceResponse newResourceResponse(final Attributes attributes) { + + LOG.debug("Enduser logout"); + + SyncopeEnduserSession.get().invalidate(); + + ResourceResponse response = new ResourceResponse(); + response.setStatusCode(204); + return response; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/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 new file mode 100644 index 0000000..544138b --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java @@ -0,0 +1,116 @@ +/* + * 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.ArrayList; +import java.util.List; +import org.apache.syncope.client.enduser.model.SchemaResponse; +import org.apache.syncope.common.lib.to.AbstractSchemaTO; +import org.apache.syncope.common.lib.to.AnyTypeTO; +import org.apache.syncope.common.lib.to.DerSchemaTO; +import org.apache.syncope.common.lib.to.PlainSchemaTO; +import org.apache.syncope.common.lib.to.VirSchemaTO; +import org.apache.syncope.common.lib.types.AnyTypeKind; +import org.apache.syncope.common.lib.types.SchemaType; +import org.apache.syncope.common.rest.api.service.AnyTypeClassService; +import org.apache.syncope.common.rest.api.service.AnyTypeService; +import org.apache.syncope.common.rest.api.service.SchemaService; +import org.apache.syncope.core.misc.serialization.POJOHelper; +import org.apache.wicket.request.resource.AbstractResource; +import org.apache.wicket.request.resource.IResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SchemaResource extends AbstractBaseResource { + + private static final Logger LOG = LoggerFactory.getLogger(SchemaResource.class); + + private static final long serialVersionUID = 6453101466981543020L; + + private final AnyTypeService anyTypeService; + + private final AnyTypeClassService anyTypeClassService; + + private final SchemaService schemaService; + + public SchemaResource() { + anyTypeService = getService(AnyTypeService.class); + anyTypeClassService = getService(AnyTypeClassService.class); + schemaService = getService(SchemaService.class); + } + + @Override + protected AbstractResource.ResourceResponse newResourceResponse(final IResource.Attributes attributes) { + + AbstractResource.ResourceResponse response = new AbstractResource.ResourceResponse(); + + int responseStatus = 200; + + try { + + final AnyTypeTO anyTypeUserTO = anyTypeService.read(AnyTypeKind.USER.name()); + + final List<PlainSchemaTO> plainSchemas = new ArrayList<>(); + final List<DerSchemaTO> derSchemas = new ArrayList<>(); + final List<VirSchemaTO> virSchemas = new ArrayList<>(); + + // read all USER type schemas + for (String clazz : anyTypeUserTO.getClasses()) { + plainSchemas.addAll(getSchemaTOs(anyTypeClassService.read(clazz).getPlainSchemas(), SchemaType.PLAIN, + PlainSchemaTO.class)); + derSchemas.addAll(getSchemaTOs(anyTypeClassService.read(clazz).getDerSchemas(), SchemaType.DERIVED, + DerSchemaTO.class)); + virSchemas.addAll(getSchemaTOs(anyTypeClassService.read(clazz).getVirSchemas(), SchemaType.VIRTUAL, + VirSchemaTO.class)); + } + + response.setWriteCallback(new AbstractResource.WriteCallback() { + + @Override + public void writeData(final IResource.Attributes attributes) throws IOException { + attributes.getResponse().write(POJOHelper.serialize(new SchemaResponse(). + plainSchemas(plainSchemas). + derSchemas(derSchemas). + virSchemas(virSchemas))); + } + }); + + } catch (Exception e) { + LOG.error("Error retrieving " + AnyTypeKind.USER.name() + " class schemas", e); + responseStatus = 400; + } + + response.setStatusCode(responseStatus); + return response; + } + + private <T extends AbstractSchemaTO> List<T> getSchemaTOs(final List<String> schemaNames, + final SchemaType schemaType, final Class<T> type) { + + List<T> schemaTOs = new ArrayList<>(); + + for (String schemaName : schemaNames) { + schemaTOs.add(type.cast(schemaService.read(schemaType, schemaName))); + } + + return schemaTOs; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java new file mode 100644 index 0000000..f1ab6c8 --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SecurityQuestionResource.java @@ -0,0 +1,73 @@ +/* + * 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 org.apache.syncope.common.lib.to.SecurityQuestionTO; +import org.apache.syncope.common.rest.api.service.SecurityQuestionService; +import org.apache.syncope.core.misc.serialization.POJOHelper; +import org.apache.wicket.request.resource.AbstractResource; +import org.apache.wicket.request.resource.IResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SecurityQuestionResource extends AbstractBaseResource { + + private static final Logger LOG = LoggerFactory.getLogger(SecurityQuestionResource.class); + + private static final long serialVersionUID = 6453101466981543020L; + + private final SecurityQuestionService securityQuestionService; + + public SecurityQuestionResource() { + securityQuestionService = getService(SecurityQuestionService.class); + } + + @Override + protected AbstractResource.ResourceResponse newResourceResponse(final IResource.Attributes attributes) { + + AbstractResource.ResourceResponse response = new AbstractResource.ResourceResponse(); + + int responseStatus = 200; + + try { + + LOG.debug("List available security questions"); + + final List<SecurityQuestionTO> securityQuestionTOs = securityQuestionService.list(); + + response.setWriteCallback(new AbstractResource.WriteCallback() { + + @Override + public void writeData(final IResource.Attributes attributes) throws IOException { + attributes.getResponse().write(POJOHelper.serialize(securityQuestionTOs)); + } + }); + + } catch (Exception e) { + LOG.error("Error retrieving security questions", e); + responseStatus = 400; + } + + response.setStatusCode(responseStatus); + return response; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.java new file mode 100644 index 0000000..61734a7 --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfCreateResource.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.client.enduser.resources; + +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import org.apache.syncope.client.enduser.SyncopeEnduserSession; +import org.apache.syncope.client.enduser.adapters.UserTOAdapter; +import org.apache.syncope.client.enduser.model.UserTORequest; +import org.apache.syncope.common.rest.api.service.UserSelfService; +import org.apache.syncope.core.misc.serialization.POJOHelper; +import org.apache.wicket.util.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class UserSelfCreateResource extends AbstractBaseResource { + + private static final long serialVersionUID = -2721621682300247583L; + + private static final Logger LOG = LoggerFactory.getLogger(UserSelfCreateResource.class); + + private final UserSelfService userSelfService; + + private final UserTOAdapter userTOAdapter; + + public UserSelfCreateResource() { + userTOAdapter = new UserTOAdapter(); + userSelfService = getService(UserSelfService.class); + } + + @Override + protected ResourceResponse newResourceResponse(final Attributes attributes) { + + int responseStatus = 200; + final StringBuilder responseMessage = new StringBuilder(); + ResourceResponse response = new ResourceResponse(); + + try { + HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest(); + + final UserTORequest userTORequest = POJOHelper.deserialize(IOUtils.toString(request.getInputStream()), + UserTORequest.class); + + if (isSelfRegistrationAllowed() && userTORequest != null) { + LOG.debug("Received user self registration request for user: [{}]", userTORequest.getUsername()); + LOG.trace("Received user self registration request is: [{}]", userTORequest); + // adapt request and create user + userSelfService.create(userTOAdapter.fromUserTORequest(userTORequest, null), + SyncopeEnduserSession.get().storePassword()); + responseMessage.append("User").append(userTORequest.getUsername()).append("created successfully"); + } else { + responseMessage.append(userTORequest == null + ? "Request received is not valid" + : "Self registration not allowed"); + responseStatus = 403; + } + response.setWriteCallback(new WriteCallback() { + + @Override + public void writeData(final Attributes attributes) throws IOException { + attributes.getResponse().write(responseMessage); + } + }); + + } catch (final Exception e) { + responseStatus = 400; + response.setWriteCallback(new WriteCallback() { + + @Override + public void writeData(final Attributes attributes) throws IOException { + attributes.getResponse().write(e.getMessage()); + } + }); + LOG.error("Could not read userTO from request", e); + } + + response.setStatusCode(responseStatus); + return response; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java new file mode 100644 index 0000000..3519e78 --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfReadResource.java @@ -0,0 +1,66 @@ +/* + * 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 org.apache.syncope.client.enduser.SyncopeEnduserSession; +import org.apache.syncope.client.enduser.adapters.UserTOAdapter; +import org.apache.syncope.core.misc.serialization.POJOHelper; +import org.apache.wicket.request.resource.AbstractResource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Mirror REST resource for obtaining user self operations. + * + * @see org.apache.syncope.common.rest.api + */ +public class UserSelfReadResource extends AbstractResource { + + private static final long serialVersionUID = -9184809392631523912L; + + /** + * Logger. + */ + private static final Logger LOG = LoggerFactory.getLogger(UserSelfReadResource.class); + + private final UserTOAdapter userTOAdapter; + + public UserSelfReadResource() { + userTOAdapter = new UserTOAdapter(); + } + + @Override + protected ResourceResponse newResourceResponse(final Attributes attributes) { + + ResourceResponse response = new ResourceResponse(); + final String selfTOJson = POJOHelper.serialize(userTOAdapter.toUserTORequest(SyncopeEnduserSession.get(). + getSelfTO())); + + response.setWriteCallback(new WriteCallback() { + + @Override + public void writeData(final Attributes attributes) throws IOException { + attributes.getResponse().write(selfTOJson); + } + }); + + return response; + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java new file mode 100644 index 0000000..5fc9c82 --- /dev/null +++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/UserSelfUpdateResource.java @@ -0,0 +1,96 @@ +/* + * 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 org.apache.syncope.client.enduser.SyncopeEnduserSession; +import org.apache.syncope.client.enduser.adapters.UserTOAdapter; +import org.apache.syncope.client.enduser.model.UserTORequest; +import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.common.rest.api.service.UserSelfService; +import org.apache.syncope.core.misc.serialization.POJOHelper; +import org.apache.wicket.util.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class UserSelfUpdateResource extends AbstractBaseResource { + + private static final long serialVersionUID = -2721621682300247583L; + + private static final Logger LOG = LoggerFactory.getLogger(UserSelfUpdateResource.class); + + private final UserSelfService userSelfService; + + private final UserTOAdapter userTOAdapter; + + public UserSelfUpdateResource() { + userTOAdapter = new UserTOAdapter(); + userSelfService = getService(UserSelfService.class); + } + + @Override + protected ResourceResponse newResourceResponse(final Attributes attributes) { + + int responseStatus = 200; + final String responseMessage; + ResourceResponse response = new ResourceResponse(); + + try { + HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest(); + + final UserTORequest userTOResponse = POJOHelper.deserialize(IOUtils.toString(request.getInputStream()), + UserTORequest.class); + + LOG.debug("userTOResponse: {}", userTOResponse); + + // adapt user, change self password only value passed is not null and has changed + UserTO userTO = userTOAdapter.fromUserTORequest(userTOResponse, SyncopeEnduserSession.get().getPassword()); + + LOG.debug("Enduser user self update, user: {}", userTO.toString()); + + // update user + userSelfService.update(userTO); + responseMessage = "User updated successfully"; + + response.setWriteCallback(new WriteCallback() { + + @Override + public void writeData(final Attributes attributes) throws IOException { + attributes.getResponse().write(responseMessage); + } + }); + + } catch (final Exception e) { + responseStatus = 400; + response.setWriteCallback(new WriteCallback() { + + @Override + public void writeData(final Attributes attributes) throws IOException { + attributes.getResponse().write(e.getMessage()); + } + }); + LOG.error("Could not read userTO from request", e); + } + + response.setStatusCode(responseStatus); + return response; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/css/app.css ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/app.css b/client/enduser/src/main/resources/META-INF/resources/app/css/app.css new file mode 100644 index 0000000..e5ae8e5 --- /dev/null +++ b/client/enduser/src/main/resources/META-INF/resources/app/css/app.css @@ -0,0 +1,28 @@ +/* +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. +*/ + +/* app general css stylesheet */ + +.growl-container > .growl-item.ng-enter, +.growl-container > .growl-item.ng-leave { + -webkit-transition:1s linear all; + -moz-transition:1s linear all; + -o-transition:1s linear all; + transition:1s linear all; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/css/editUser.css ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/editUser.css b/client/enduser/src/main/resources/META-INF/resources/app/css/editUser.css new file mode 100644 index 0000000..ee13bd0 --- /dev/null +++ b/client/enduser/src/main/resources/META-INF/resources/app/css/editUser.css @@ -0,0 +1,253 @@ +/* +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. +*/ + +#form-container { + position: relative; + width: 100%; + margin: 0 auto; + text-align: center; +} + +#form-container .page-header { background: -moz-linear-gradient(top, #a9db80 0%, #96c56f 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a9db80), color-stop(100%,#96c56f)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* IE10+ */ + margin: 1% 16%; + width: 72%; padding:10px; + /* shadows and rounded borders */ + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); + -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); + box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); +} +#form-container .breadcrumb-header { + margin: 1% 16%; + width: 72%; padding:10px; +} + +.signup-form { + text-align: left; + padding: 2%; +} + +#attribute { + padding: 0 255px; +} + +#attribute-derived, +#attribute-virtual { + padding: 0 155px; +} + +.attribute-virtual-value-container { + margin-top: 2%; + list-style: none; + padding-right: 5%; +} + +.attribute-virtual-value-field { + font-weight: 700; + padding: 6px 12px; + margin-bottom: 2%; +} + +.minus{ + margin-bottom: 2%; +} + +.fileButton{ + margin-top: 2%; +} + +.upper-select { + padding-right: 71%; + padding-left: 18%; +} + +.attribute-ui-select { + width: 100%; + padding-right: 7%; + padding-left: 7%; +} + +#previous { + background: -moz-linear-gradient(top, #a9db80 0%, #96c56f 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a9db80), color-stop(100%,#96c56f)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* IE10+ */ + float: left; + color: black; + width: 30%; +} +#previous:hover { + background: #658D5D; +} + +#next{ + background: -moz-linear-gradient(top, #a9db80 0%, #96c56f 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a9db80), color-stop(100%,#96c56f)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* IE10+ */ + margin-top: 5px; + float: right; + color: black; + width: 30%; +} +#next:hover { + background: #658D5D; +} + +#save{ + background: -moz-linear-gradient(top, #a9db80 0%, #96c56f 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a9db80), color-stop(100%,#96c56f)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* IE10+ */ + color: black; + margin-top: 5%; + width: 15%; +} +#save:hover { + background: #658D5D; +} +#cancel { + margin-top: 5%; + width: 15%; +} + +#form-views { width:auto; } + +/* basic styling for entering and leaving */ +/* left and right to add to ensure full width: position:absolute; left:30px; right:30px; */ +#form-views.ng-enter, +#form-views.ng-leave { + transition:0.5s all ease; -moz-transition:0.5s all ease; -webkit-transition:0.5s all ease; +} + +/* enter animation */ +#form-views.ng-enter { + -webkit-animation:slideInRight 0.5s both ease; + -moz-animation:slideInRight 0.5s both ease; + animation:slideInRight 0.5s both ease; +} + +/* leave animation */ +#form-views.ng-leave { + -webkit-animation:slideOutLeft 0.5s both ease; + -moz-animation:slideOutLeft 0.5s both ease; + animation:slideOutLeft 0.5s both ease; +} + +/** Button breadcrumb **/ +.btn-breadcrumb .btn:not(:last-child):after { + content: " "; + display: block; + width: 0; + height: 0; + border-top: 17px solid transparent; + border-bottom: 17px solid transparent; + border-left: 10px solid white; + position: absolute; + top: 50%; + margin-top: -17px; + left: 100%; + z-index: 3; +} +.btn-breadcrumb .btn:not(:last-child):before { + content: " "; + display: block; + width: 0; + height: 0; + border-top: 17px solid transparent; + border-bottom: 17px solid transparent; + border-left: 10px solid rgb(173, 173, 173); + position: absolute; + top: 50%; + margin-top: -17px; + margin-left: 1px; + left: 100%; + z-index: 3; +} + +/** The Spacing **/ +.btn-breadcrumb .btn { + padding:6px 12px 6px 24px; +} +.btn-breadcrumb .btn:first-child { + padding:6px 6px 6px 10px; +} +.btn-breadcrumb .btn:last-child { + padding:6px 18px 6px 24px; +} + +/** Default button **/ +.btn-breadcrumb .btn.btn-default:not(:last-child):after { + border-left: 10px solid #fff; +} +.btn-breadcrumb .btn.btn-default:not(:last-child):before { + border-left: 10px solid #ccc; +} +.btn-breadcrumb .btn.btn-default:hover:not(:last-child):after { + border-left: 10px solid #ebebeb; +} +.btn-breadcrumb .btn.btn-default:hover:not(:last-child):before { + border-left: 10px solid #adadad; +} + +.breadcrumb-disabled-link { + pointer-events: none; + cursor: default; +} + +.text-validation-error{ + color: #dd301b; + font-weight: 600; +} +/* ANIMATIONS +============================================================================= */ +/* slide out to the left */ +@keyframes slideOutLeft { + to { transform: translateX(-200%); } +} +@-moz-keyframes slideOutLeft { + to { -moz-transform: translateX(-200%); } +} +@-webkit-keyframes slideOutLeft { + to { -webkit-transform: translateX(-200%); } +} + +/* slide in from the right */ +@keyframes slideInRight { + from { transform:translateX(200%); } + to { transform: translateX(0); } +} +@-moz-keyframes slideInRight { + from { -moz-transform:translateX(200%); } + to { -moz-transform: translateX(0); } +} +@-webkit-keyframes slideInRight { + from { -webkit-transform:translateX(200%); } + to { -webkit-transform: translateX(0); } +} + http://git-wip-us.apache.org/repos/asf/syncope/blob/223a64e2/client/enduser/src/main/resources/META-INF/resources/app/css/login.css ---------------------------------------------------------------------- diff --git a/client/enduser/src/main/resources/META-INF/resources/app/css/login.css b/client/enduser/src/main/resources/META-INF/resources/app/css/login.css new file mode 100644 index 0000000..fdc9e3e --- /dev/null +++ b/client/enduser/src/main/resources/META-INF/resources/app/css/login.css @@ -0,0 +1,103 @@ +/* + * 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. + */ + +body, html { + margin: 45px 0; + height: 100%; + background-repeat: no-repeat; + /*background-image: linear-gradient(rgb(104, 145, 162), #00a65a);*/ + background-color: #EEEEEE; +} +#login-container { + position: relative; + width: 100%; + margin: 0 auto; + text-align: center; + background-color: #FFF; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.65); + box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.65); +} +#login-container .row > div { + margin-bottom: 1em; +} +#login-container .row > div:last-child { + margin-bottom: 0; +} +#login-container #logo { + position: relative; + float: left; + margin-left: 15%; + border-top-right-radius: 100px; + border-top-left-radius: 100px; + border-bottom-right-radius: 100px; + border-bottom-left-radius: 100px; +} + +#login-container #language{ + padding: 0px; + height: 40px; +} + +#login-container #signup-btn { + padding-top: 15px; + padding-bottom: 15px; +} +#login-container #signup-btn:hover { + background-color: #1d1d1d; + border-color: #181818; +} + +.login-btn { + background: -moz-linear-gradient(top, #a9db80 0%, #96c56f 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a9db80), color-stop(100%,#96c56f)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #a9db80 0%,#96c56f 100%); /* IE10+ */ + margin-top: 5px; + color: black; +} +.login-btn:hover { + background: #658D5D; +} + +#login { + position: relative; + padding: 25px 25px 50px 25px; + margin-bottom: 1em; +} +#login #login-form { + margin-top: 2em; + margin-bottom: 2em; + text-align: left; +} +#login-form{ + padding: 0 195px; + margin: 7%; +} +#languageContainer { + padding: 0 25px; +} + +.logout{ + float: right; +} \ No newline at end of file
