You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2014/09/19 10:53:25 UTC
svn commit: r1626148 [1/3] - in /syncope/branches/1_2_X: ./
common/src/main/java/org/apache/syncope/common/mod/
common/src/main/java/org/apache/syncope/common/services/
common/src/main/java/org/apache/syncope/common/to/
common/src/main/java/org/apache/...
Author: ilgrosso
Date: Fri Sep 19 08:53:24 2014
New Revision: 1626148
URL: http://svn.apache.org/r1626148
Log:
[SYNCOPE-135] core features completed, now let's go to console
Added:
syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/SecurityQuestionService.java (with props)
syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/SecurityQuestionTO.java (with props)
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/beans/SecurityQuestion.java (with props)
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/SecurityQuestionDAO.java (with props)
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/SecurityQuestionDAOImpl.java (with props)
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/SecurityQuestionController.java (with props)
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/SecurityQuestionDataBinder.java (with props)
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/SecurityQuestionServiceImpl.java (with props)
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Notify.java (with props)
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/PasswordReset.java (with props)
syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.html.vm (with props)
syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.txt.vm (with props)
syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.html.vm (with props)
syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.txt.vm (with props)
syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/SecurityQuestionTest.java (with props)
syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/relationships/SecurityQuestionTest.java (with props)
syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/SecurityQuestionTestITCase.java (with props)
Modified:
syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/mod/UserMod.java
syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/ConnectorService.java
syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/UserSelfService.java
syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/ConnPoolConfTO.java
syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/UserTO.java
syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/types/ClientExceptionType.java
syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/types/RESTHeaders.java
syncope/branches/1_2_X/core/pom.xml
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/notification/NotificationJob.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/UserDAO.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/UserDAOImpl.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/NotificationController.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/NotificationDataBinder.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/NotificationServiceImpl.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/SchemaServiceImpl.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/UserSelfServiceImpl.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/util/Encryptor.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/util/POJOHelper.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/UserWorkflowAdapter.java
syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java
syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml
syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml.oracle
syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml.sqlserver
syncope/branches/1_2_X/core/src/main/resources/content.xml
syncope/branches/1_2_X/core/src/main/resources/mail.properties
syncope/branches/1_2_X/core/src/main/resources/userWorkflow.bpmn20.xml
syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/connid/PasswordGeneratorTest.java
syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java
syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java
syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/UserTest.java
syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java
syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/NotificationTestITCase.java
syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/UserSelfTestITCase.java
syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java
syncope/branches/1_2_X/core/src/test/resources/content.xml
syncope/branches/1_2_X/core/src/test/resources/mail.properties
syncope/branches/1_2_X/core/src/test/resources/userWorkflow.bpmn20.xml
syncope/branches/1_2_X/pom.xml
Modified: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/mod/UserMod.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/mod/UserMod.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/mod/UserMod.java (original)
+++ syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/mod/UserMod.java Fri Sep 19 08:53:24 2014
@@ -43,6 +43,10 @@ public class UserMod extends AbstractSub
private StatusMod pwdPropRequest;
+ private Long securityQuestion;
+
+ private String securityAnswer;
+
public UserMod() {
super();
@@ -88,6 +92,22 @@ public class UserMod extends AbstractSub
this.pwdPropRequest = pwdPropRequest;
}
+ 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;
+ }
+
@JsonIgnore
@Override
public boolean isEmpty() {
@@ -96,6 +116,8 @@ public class UserMod extends AbstractSub
&& username == null
&& membershipsToAdd.isEmpty()
&& membershipsToRemove.isEmpty()
- && pwdPropRequest == null;
+ && pwdPropRequest == null
+ && securityQuestion == null
+ && securityAnswer == null;
}
}
Modified: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/ConnectorService.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/ConnectorService.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/ConnectorService.java (original)
+++ syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/ConnectorService.java Fri Sep 19 08:53:24 2014
@@ -155,12 +155,12 @@ public interface ConnectorService extend
* Updates the connector instance matching the provided id.
*
* @param connInstanceId connector instance id to be updated
- * @param connInstaceTO connector instance to be stored
+ * @param connInstanceTO connector instance to be stored
*/
@PUT
@Path("{connInstanceId}")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
- void update(@NotNull @PathParam("connInstanceId") Long connInstanceId, @NotNull ConnInstanceTO connInstaceTO);
+ void update(@NotNull @PathParam("connInstanceId") Long connInstanceId, @NotNull ConnInstanceTO connInstanceTO);
/**
* Deletes the connector instance matching the provided id.
@@ -172,14 +172,14 @@ public interface ConnectorService extend
void delete(@NotNull @PathParam("connInstanceId") Long connInstanceId);
/**
- * @param connInstaceTO connector instance to be used for connection check
+ * @param connInstanceTO connector instance to be used for connection check
* @return true if connection could be established
*/
@POST
@Path("check")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
- boolean check(@NotNull ConnInstanceTO connInstaceTO);
+ boolean check(@NotNull ConnInstanceTO connInstanceTO);
/**
* Reload all connector bundles and instances.
Added: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/SecurityQuestionService.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/SecurityQuestionService.java?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/SecurityQuestionService.java (added)
+++ syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/SecurityQuestionService.java Fri Sep 19 08:53:24 2014
@@ -0,0 +1,110 @@
+/*
+ * 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.common.services;
+
+import java.util.List;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.cxf.jaxrs.model.wadl.Description;
+import org.apache.cxf.jaxrs.model.wadl.Descriptions;
+import org.apache.cxf.jaxrs.model.wadl.DocTarget;
+import org.apache.syncope.common.to.SecurityQuestionTO;
+
+/**
+ * REST operations for configuration.
+ */
+@Path("securityQuestions")
+public interface SecurityQuestionService extends JAXRSService {
+
+ /**
+ * Returns a list of all security questions.
+ *
+ * @return list of all security questions
+ */
+ @GET
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ List<SecurityQuestionTO> list();
+
+ /**
+ * Returns security question with matching id.
+ *
+ * @param securityQuestionId security question id to be read
+ * @return security question with matching id
+ */
+ @GET
+ @Path("{securityQuestionId}")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ SecurityQuestionTO read(@NotNull @PathParam("securityQuestionId") Long securityQuestionId);
+
+ /**
+ * Creates a new security question.
+ *
+ * @param securityQuestionTO security question to be created
+ * @return <tt>Response</tt> object featuring <tt>Location</tt> header of created security question
+ */
+ @Descriptions({
+ @Description(target = DocTarget.RESPONSE,
+ value = "Featuring <tt>Location</tt> header of created security question")
+ })
+ @POST
+ @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ Response create(@NotNull SecurityQuestionTO securityQuestionTO);
+
+ /**
+ * Updates the security question matching the provided id.
+ *
+ * @param securityQuestionId security question id to be updated
+ * @param securityQuestionTO security question to be stored
+ */
+ @PUT
+ @Path("{securityQuestionId}")
+ @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ void update(@NotNull @PathParam("securityQuestionId") Long securityQuestionId,
+ @NotNull SecurityQuestionTO securityQuestionTO);
+
+ /**
+ * Deletes the security question matching the provided id.
+ *
+ * @param securityQuestionId security question id to be deleted
+ */
+ @DELETE
+ @Path("{securityQuestionId}")
+ void delete(@NotNull @PathParam("securityQuestionId") Long securityQuestionId);
+
+ /**
+ * Ask for security question configured for the user matching the given username, if any.
+ *
+ * @param username username for which the security question is requested
+ * @return security question, if configured for the user matching the given username
+ */
+ @GET
+ @Path("byUser/{username}")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ SecurityQuestionTO readByUser(@NotNull @PathParam("username") String username);
+}
Propchange: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/SecurityQuestionService.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/SecurityQuestionService.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/SecurityQuestionService.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/UserSelfService.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/UserSelfService.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/UserSelfService.java (original)
+++ syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/services/UserSelfService.java Fri Sep 19 08:53:24 2014
@@ -46,12 +46,15 @@ public interface UserSelfService extends
/**
* Checks whether self-registration is allowed.
*
- * @return <tt>Response</tt> contains special Syncope HTTP header indicating if user self registration is allowed
+ * @return <tt>Response</tt> contains special Syncope HTTP header indicating if user self registration and / or
+ * password reset is allowed
* @see org.apache.syncope.common.types.RESTHeaders#SELFREGISTRATION_ALLOWED
+ * @see org.apache.syncope.common.types.RESTHeaders#PASSWORDRESET_ALLOWED
*/
@Descriptions({
@Description(target = DocTarget.RESPONSE,
- value = "Contains special Syncope HTTP header indicating if user self registration is allowed")
+ value = "Contains special Syncope HTTP header indicating if user self registration "
+ + "and / or password reset is allowed")
})
@OPTIONS
Response getOptions();
@@ -114,4 +117,28 @@ public interface UserSelfService extends
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
Response delete();
+ /**
+ * Provides answer for the security question configured for user matching the given username, if any.
+ * If provided anwser matches the one stored for that user, a password reset token is internally generated,
+ * otherwise an error is returned.
+ *
+ * @param username username for which the security answer is provided
+ * @param securityAnswer actual answer text
+ */
+ @POST
+ @Path("requestPasswordReset")
+ void requestPasswordReset(@NotNull @QueryParam("username") String username, String securityAnswer);
+
+ /**
+ * Reset the password value for the user matching the provided token, if available and still valid.
+ * If the token actually matches one of users, and if it is still valid at the time of submission, the matching
+ * user's password value is set as provided. The new password value will need anyway to comply with all relevant
+ * password policies.
+ *
+ * @param token password reset token
+ * @param password new password to be set
+ */
+ @POST
+ @Path("confirmPasswordReset")
+ void confirmPasswordReset(@NotNull @QueryParam("token") String token, String password);
}
Modified: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/ConnPoolConfTO.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/ConnPoolConfTO.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/ConnPoolConfTO.java (original)
+++ syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/ConnPoolConfTO.java Fri Sep 19 08:53:24 2014
@@ -26,6 +26,8 @@ import org.apache.syncope.common.Abstrac
@XmlType
public class ConnPoolConfTO extends AbstractBaseBean {
+ private static final long serialVersionUID = -214360178113476623L;
+
private Integer maxObjects;
private Integer minIdle;
Added: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/SecurityQuestionTO.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/SecurityQuestionTO.java?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/SecurityQuestionTO.java (added)
+++ syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/SecurityQuestionTO.java Fri Sep 19 08:53:24 2014
@@ -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.common.to;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.AbstractBaseBean;
+
+@XmlRootElement(name = "securityQuestion")
+@XmlType
+public class SecurityQuestionTO extends AbstractBaseBean {
+
+ private static final long serialVersionUID = 5969810939993556530L;
+
+ private long id;
+
+ private String content;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(final long id) {
+ this.id = id;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(final String content) {
+ this.content = content;
+ }
+
+}
Propchange: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/SecurityQuestionTO.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/SecurityQuestionTO.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/SecurityQuestionTO.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/UserTO.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/UserTO.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/UserTO.java (original)
+++ syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/to/UserTO.java Fri Sep 19 08:53:24 2014
@@ -58,6 +58,10 @@ public class UserTO extends AbstractSubj
private Integer failedLogins;
+ private Long securityQuestion;
+
+ private String securityAnswer;
+
public String getPassword() {
return password;
}
@@ -150,6 +154,22 @@ public class UserTO extends AbstractSubj
this.lastLoginDate = lastLoginDate;
}
+ 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;
+ }
+
@Override
public String toString() {
return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE) {
Modified: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/types/ClientExceptionType.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/types/ClientExceptionType.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/types/ClientExceptionType.java (original)
+++ syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/types/ClientExceptionType.java Fri Sep 19 08:53:24 2014
@@ -28,6 +28,7 @@ public enum ClientExceptionType {
DataIntegrityViolation(Response.Status.BAD_REQUEST),
EntityExists(Response.Status.CONFLICT),
GenericPersistence(Response.Status.BAD_REQUEST),
+ InvalidSecurityAnswer(Response.Status.BAD_REQUEST),
InvalidLogger(Response.Status.BAD_REQUEST),
InvalidConnInstance(Response.Status.BAD_REQUEST),
InvalidConnIdConf(Response.Status.BAD_REQUEST),
Modified: syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/types/RESTHeaders.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/types/RESTHeaders.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/types/RESTHeaders.java (original)
+++ syncope/branches/1_2_X/common/src/main/java/org/apache/syncope/common/types/RESTHeaders.java Fri Sep 19 08:53:24 2014
@@ -39,6 +39,11 @@ public final class RESTHeaders {
public static final String SELFREGISTRATION_ALLOWED = "Syncope.SelfRegistration.Allowed";
/**
+ * Option key stating if user request create is allowed or not.
+ */
+ public static final String PASSWORDRESET_ALLOWED = "Syncope.PasswordReset.Allowed";
+
+ /**
* Option key stating if Activiti workflow adapter is in use for users.
*/
public static final String ACTIVITI_USER_ENABLED = "Syncope.Activiti.User.Enabled";
Modified: syncope/branches/1_2_X/core/pom.xml
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/pom.xml?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/pom.xml (original)
+++ syncope/branches/1_2_X/core/pom.xml Fri Sep 19 08:53:24 2014
@@ -180,7 +180,11 @@ under the License.
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
-
+ <dependency>
+ <groupId>com.fasterxml.jackson.module</groupId>
+ <artifactId>jackson-module-afterburner</artifactId>
+ </dependency>
+
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/notification/NotificationJob.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/notification/NotificationJob.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/notification/NotificationJob.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/notification/NotificationJob.java Fri Sep 19 08:53:24 2014
@@ -89,12 +89,7 @@ public class NotificationJob implements
private long maxRetries;
private void init() {
- try {
- maxRetries = confDAO.find("notification.maxRetries", "0").getValues().get(0).getLongValue();
- } catch (NumberFormatException e) {
- LOG.error("Invalid maximum number of retries, retries disabled", e);
- maxRetries = 0;
- }
+ maxRetries = confDAO.find("notification.maxRetries", "0").getValues().get(0).getLongValue();
if (mailSender instanceof JavaMailSenderImpl
&& StringUtils.isNotBlank(((JavaMailSenderImpl) mailSender).getUsername())) {
Added: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/beans/SecurityQuestion.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/beans/SecurityQuestion.java?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/beans/SecurityQuestion.java (added)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/beans/SecurityQuestion.java Fri Sep 19 08:53:24 2014
@@ -0,0 +1,48 @@
+/*
+ * 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.persistence.beans;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class SecurityQuestion extends AbstractBaseBean {
+
+ private static final long serialVersionUID = -7646140284033489392L;
+
+ @Id
+ private Long id;
+
+ @Column(unique = true)
+ private String content;
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(final String content) {
+ this.content = content;
+ }
+
+}
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/beans/SecurityQuestion.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/beans/SecurityQuestion.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/beans/SecurityQuestion.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java Fri Sep 19 08:53:24 2014
@@ -39,6 +39,7 @@ import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@@ -53,6 +54,7 @@ import org.apache.syncope.core.persisten
import org.apache.syncope.core.persistence.beans.AbstractSubject;
import org.apache.syncope.core.persistence.beans.AbstractVirAttr;
import org.apache.syncope.core.persistence.beans.ExternalResource;
+import org.apache.syncope.core.persistence.beans.SecurityQuestion;
import org.apache.syncope.core.persistence.beans.membership.Membership;
import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
import org.apache.syncope.core.persistence.validation.entity.SyncopeUserCheck;
@@ -154,7 +156,13 @@ public class SyncopeUser extends Abstrac
@JoinColumn(name = "resource_name"))
@Valid
private Set<ExternalResource> resources;
-
+
+ @ManyToOne(fetch = FetchType.EAGER, optional = true)
+ private SecurityQuestion securityQuestion;
+
+ @Column(nullable = true)
+ private String securityAnswer;
+
public SyncopeUser() {
super();
@@ -267,7 +275,7 @@ public class SyncopeUser extends Abstrac
this.cipherAlgorithm = cipherAlgoritm;
}
- public void setPassword(final String password, final CipherAlgorithm cipherAlgoritm, final int historySize) {
+ public void setPassword(final String password, final CipherAlgorithm cipherAlgoritm) {
// clear password
this.clearPassword = password;
@@ -494,8 +502,8 @@ public class SyncopeUser extends Abstrac
res = passwordHistory.subList(size >= passwordHistory.size()
? 0
: passwordHistory.size() - size, passwordHistory.size()).contains(cipherAlgorithm == null
- ? password
- : Encryptor.getInstance().encode(password, cipherAlgorithm));
+ ? password
+ : Encryptor.getInstance().encode(password, cipherAlgorithm));
} catch (Exception e) {
LOG.error("Error evaluating password history", e);
}
@@ -503,4 +511,21 @@ public class SyncopeUser extends Abstrac
return res;
}
+
+ public SecurityQuestion getSecurityQuestion() {
+ return securityQuestion;
+ }
+
+ public void setSecurityQuestion(final SecurityQuestion securityQuestion) {
+ this.securityQuestion = securityQuestion;
+ }
+
+ public String getSecurityAnswer() {
+ return securityAnswer;
+ }
+
+ public void setSecurityAnswer(final String securityAnswer) {
+ this.securityAnswer = securityAnswer;
+ }
+
}
Added: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/SecurityQuestionDAO.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/SecurityQuestionDAO.java?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/SecurityQuestionDAO.java (added)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/SecurityQuestionDAO.java Fri Sep 19 08:53:24 2014
@@ -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.core.persistence.dao;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.beans.SecurityQuestion;
+import org.apache.syncope.core.persistence.validation.entity.InvalidEntityException;
+
+public interface SecurityQuestionDAO extends DAO {
+
+ SecurityQuestion find(Long id);
+
+ List<SecurityQuestion> findAll();
+
+ SecurityQuestion save(SecurityQuestion securityQuestion) throws InvalidEntityException;
+
+ void delete(Long id);
+
+}
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/SecurityQuestionDAO.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/SecurityQuestionDAO.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/SecurityQuestionDAO.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/UserDAO.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/UserDAO.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/UserDAO.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/UserDAO.java Fri Sep 19 08:53:24 2014
@@ -22,6 +22,7 @@ import java.util.List;
import java.util.Set;
import org.apache.syncope.core.persistence.beans.ExternalResource;
+import org.apache.syncope.core.persistence.beans.SecurityQuestion;
import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
import org.apache.syncope.core.persistence.beans.user.UAttrValue;
import org.apache.syncope.core.persistence.dao.search.OrderByClause;
@@ -35,6 +36,10 @@ public interface UserDAO extends Subject
SyncopeUser findByWorkflowId(String workflowId);
+ SyncopeUser findByToken(String token);
+
+ List<SyncopeUser> findBySecurityQuestion(SecurityQuestion securityQuestion);
+
List<SyncopeUser> findByDerAttrValue(String schemaName, String value);
List<SyncopeUser> findByAttrValue(String schemaName, UAttrValue attrValue);
@@ -54,4 +59,5 @@ public interface UserDAO extends Subject
void delete(Long id);
void delete(SyncopeUser user);
+
}
Added: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/SecurityQuestionDAOImpl.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/SecurityQuestionDAOImpl.java?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/SecurityQuestionDAOImpl.java (added)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/SecurityQuestionDAOImpl.java Fri Sep 19 08:53:24 2014
@@ -0,0 +1,70 @@
+/*
+ * 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.persistence.dao.impl;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.core.persistence.beans.SecurityQuestion;
+import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
+import org.apache.syncope.core.persistence.dao.SecurityQuestionDAO;
+import org.apache.syncope.core.persistence.dao.UserDAO;
+import org.apache.syncope.core.persistence.validation.entity.InvalidEntityException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class SecurityQuestionDAOImpl extends AbstractDAOImpl implements SecurityQuestionDAO {
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Override
+ public SecurityQuestion find(final Long id) {
+ return entityManager.find(SecurityQuestion.class, id);
+ }
+
+ @Override
+ public List<SecurityQuestion> findAll() {
+ final TypedQuery<SecurityQuestion> query = entityManager.createQuery(
+ "SELECT e FROM " + SecurityQuestion.class.getSimpleName() + " e ", SecurityQuestion.class);
+ return query.getResultList();
+ }
+
+ @Override
+ public SecurityQuestion save(final SecurityQuestion securityQuestion) throws InvalidEntityException {
+ return entityManager.merge(securityQuestion);
+ }
+
+ @Override
+ public void delete(final Long id) {
+ SecurityQuestion securityQuestion = find(id);
+ if (securityQuestion == null) {
+ return;
+ }
+
+ for (SyncopeUser user : userDAO.findBySecurityQuestion(securityQuestion)) {
+ user.setSecurityQuestion(null);
+ user.setSecurityAnswer(null);
+ userDAO.save(user);
+ }
+
+ entityManager.remove(securityQuestion);
+ }
+
+}
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/SecurityQuestionDAOImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/SecurityQuestionDAOImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/SecurityQuestionDAOImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/UserDAOImpl.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/UserDAOImpl.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/UserDAOImpl.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/UserDAOImpl.java Fri Sep 19 08:53:24 2014
@@ -30,6 +30,7 @@ import org.apache.syncope.core.persisten
import org.apache.syncope.core.persistence.beans.AbstractAttributable;
import org.apache.syncope.core.persistence.beans.AbstractVirAttr;
import org.apache.syncope.core.persistence.beans.ExternalResource;
+import org.apache.syncope.core.persistence.beans.SecurityQuestion;
import org.apache.syncope.core.persistence.beans.membership.Membership;
import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
import org.apache.syncope.core.persistence.beans.user.UAttrValue;
@@ -78,7 +79,7 @@ public class UserDAOImpl extends Abstrac
@Override
public SyncopeUser find(final String username) {
TypedQuery<SyncopeUser> query = entityManager.createQuery("SELECT e FROM " + SyncopeUser.class.getSimpleName()
- + " e " + "WHERE e.username = :username", SyncopeUser.class);
+ + " e WHERE e.username = :username", SyncopeUser.class);
query.setParameter("username", username);
SyncopeUser result = null;
@@ -94,7 +95,7 @@ public class UserDAOImpl extends Abstrac
@Override
public SyncopeUser findByWorkflowId(final String workflowId) {
TypedQuery<SyncopeUser> query = entityManager.createQuery("SELECT e FROM " + SyncopeUser.class.getSimpleName()
- + " e " + "WHERE e.workflowId = :workflowId", SyncopeUser.class);
+ + " e WHERE e.workflowId = :workflowId", SyncopeUser.class);
query.setParameter("workflowId", workflowId);
SyncopeUser result = null;
@@ -108,6 +109,31 @@ public class UserDAOImpl extends Abstrac
}
@Override
+ public SyncopeUser findByToken(final String token) {
+ TypedQuery<SyncopeUser> query = entityManager.createQuery("SELECT e FROM " + SyncopeUser.class.getSimpleName()
+ + " e WHERE e.token = :token", SyncopeUser.class);
+ query.setParameter("token", token);
+
+ SyncopeUser result = null;
+ try {
+ result = query.getSingleResult();
+ } catch (NoResultException e) {
+ LOG.debug("No user found with token {}", token, e);
+ }
+
+ return result;
+ }
+
+ @Override
+ public List<SyncopeUser> findBySecurityQuestion(final SecurityQuestion securityQuestion) {
+ TypedQuery<SyncopeUser> query = entityManager.createQuery("SELECT e FROM " + SyncopeUser.class.getSimpleName()
+ + " e WHERE e.securityQuestion = :securityQuestion", SyncopeUser.class);
+ query.setParameter("securityQuestion", securityQuestion);
+
+ return query.getResultList();
+ }
+
+ @Override
protected TypedQuery<AbstractAttrValue> findByAttrValueQuery(final String entityName) {
return entityManager.createQuery("SELECT e FROM " + entityName + " e"
+ " WHERE e.attribute.schema.name = :schemaName AND (e.stringValue IS NOT NULL"
Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/NotificationController.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/NotificationController.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/NotificationController.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/NotificationController.java Fri Sep 19 08:53:24 2014
@@ -66,7 +66,7 @@ public class NotificationController exte
@PreAuthorize("hasRole('NOTIFICATION_CREATE')")
public NotificationTO create(final NotificationTO notificationTO) {
- return binder.getNotificationTO(notificationDAO.save(binder.createNotification(notificationTO)));
+ return binder.getNotificationTO(notificationDAO.save(binder.create(notificationTO)));
}
@PreAuthorize("hasRole('NOTIFICATION_UPDATE')")
@@ -77,7 +77,7 @@ public class NotificationController exte
throw new NotFoundException(String.valueOf(notificationTO.getId()));
}
- binder.updateNotification(notification, notificationTO);
+ binder.update(notification, notificationTO);
notification = notificationDAO.save(notification);
return binder.getNotificationTO(notification);
@@ -87,19 +87,16 @@ public class NotificationController exte
public NotificationTO delete(final Long notificationId) {
Notification notification = notificationDAO.find(notificationId);
if (notification == null) {
- LOG.error("Could not find notificatin '" + notificationId + "'");
+ LOG.error("Could not find notification '" + notificationId + "'");
throw new NotFoundException(String.valueOf(notificationId));
}
- NotificationTO notificationToDelete = binder.getNotificationTO(notification);
+ NotificationTO deleted = binder.getNotificationTO(notification);
notificationDAO.delete(notificationId);
- return notificationToDelete;
+ return deleted;
}
- /**
- * {@inheritDoc}
- */
@Override
protected NotificationTO resolveReference(final Method method, final Object... args)
throws UnresolvedReferenceException {
Added: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/SecurityQuestionController.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/SecurityQuestionController.java?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/SecurityQuestionController.java (added)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/SecurityQuestionController.java Fri Sep 19 08:53:24 2014
@@ -0,0 +1,150 @@
+/*
+ * 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.rest.controller;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.syncope.common.to.SecurityQuestionTO;
+import org.apache.syncope.core.persistence.beans.SecurityQuestion;
+import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
+import org.apache.syncope.core.persistence.dao.NotFoundException;
+import org.apache.syncope.core.persistence.dao.SecurityQuestionDAO;
+import org.apache.syncope.core.persistence.dao.UserDAO;
+import org.apache.syncope.core.rest.data.SecurityQuestionDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SecurityQuestionController extends AbstractTransactionalController<SecurityQuestionTO> {
+
+ @Autowired
+ private SecurityQuestionDAO securityQuestionDAO;
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Autowired
+ private SecurityQuestionDataBinder binder;
+
+ @PreAuthorize("hasRole('SECURITY_QUESTION_LIST')")
+ public List<SecurityQuestionTO> list() {
+ List<SecurityQuestionTO> result = new ArrayList<SecurityQuestionTO>();
+ for (SecurityQuestion securityQuestion : securityQuestionDAO.findAll()) {
+ result.add(binder.getSecurityQuestionTO(securityQuestion));
+ }
+
+ return result;
+ }
+
+ @PreAuthorize("hasRole('SECURITY_QUESTION_READ')")
+ public SecurityQuestionTO read(final Long securityQuestionId) {
+ SecurityQuestion securityQuestion = securityQuestionDAO.find(securityQuestionId);
+ if (securityQuestion == null) {
+ LOG.error("Could not find security question '" + securityQuestionId + "'");
+
+ throw new NotFoundException(String.valueOf(securityQuestionId));
+ }
+
+ return binder.getSecurityQuestionTO(securityQuestion);
+ }
+
+ @PreAuthorize("hasRole('SECURITY_QUESTION_CREATE')")
+ public SecurityQuestionTO create(final SecurityQuestionTO securityQuestionTO) {
+ return binder.getSecurityQuestionTO(securityQuestionDAO.save(binder.create(securityQuestionTO)));
+ }
+
+ @PreAuthorize("hasRole('SECURITY_QUESTION_UPDATE')")
+ public SecurityQuestionTO update(final SecurityQuestionTO securityQuestionTO) {
+ SecurityQuestion securityQuestion = securityQuestionDAO.find(securityQuestionTO.getId());
+ if (securityQuestion == null) {
+ LOG.error("Could not find security question '" + securityQuestionTO.getId() + "'");
+
+ throw new NotFoundException(String.valueOf(securityQuestionTO.getId()));
+ }
+
+ binder.update(securityQuestion, securityQuestionTO);
+ securityQuestion = securityQuestionDAO.save(securityQuestion);
+
+ return binder.getSecurityQuestionTO(securityQuestion);
+ }
+
+ @PreAuthorize("hasRole('SECURITY_QUESTION_DELETE')")
+ public SecurityQuestionTO delete(final Long securityQuestionId) {
+ SecurityQuestion securityQuestion = securityQuestionDAO.find(securityQuestionId);
+ if (securityQuestion == null) {
+ LOG.error("Could not find security question '" + securityQuestionId + "'");
+
+ throw new NotFoundException(String.valueOf(securityQuestionId));
+ }
+
+ SecurityQuestionTO deleted = binder.getSecurityQuestionTO(securityQuestion);
+ securityQuestionDAO.delete(securityQuestionId);
+ return deleted;
+ }
+
+ @PreAuthorize("isAnonymous() or hasRole(T(org.apache.syncope.common.SyncopeConstants).ANONYMOUS_ENTITLEMENT)")
+ public SecurityQuestionTO read(final String username) {
+ if (username == null) {
+ throw new NotFoundException("Null username");
+ }
+ SyncopeUser user = userDAO.find(username);
+ if (user == null) {
+ throw new NotFoundException("User " + username);
+ }
+
+ if (user.getSecurityQuestion() == null) {
+ LOG.error("Could not find security question for user '" + username + "'");
+
+ throw new NotFoundException("Security question for user " + username);
+ }
+
+ return binder.getSecurityQuestionTO(user.getSecurityQuestion());
+ }
+
+ @Override
+ protected SecurityQuestionTO resolveReference(final Method method, final Object... args)
+ throws UnresolvedReferenceException {
+
+ Long id = null;
+
+ if (ArrayUtils.isNotEmpty(args)) {
+ for (int i = 0; id == null && i < args.length; i++) {
+ if (args[i] instanceof Long) {
+ id = (Long) args[i];
+ } else if (args[i] instanceof SecurityQuestionTO) {
+ id = ((SecurityQuestionTO) args[i]).getId();
+ }
+ }
+ }
+
+ if (id != null) {
+ try {
+ return binder.getSecurityQuestionTO(securityQuestionDAO.find(id));
+ } catch (Throwable ignore) {
+ LOG.debug("Unresolved reference", ignore);
+ throw new UnresolvedReferenceException(ignore);
+ }
+ }
+
+ throw new UnresolvedReferenceException();
+ }
+}
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/SecurityQuestionController.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/SecurityQuestionController.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/SecurityQuestionController.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java Fri Sep 19 08:53:24 2014
@@ -46,6 +46,7 @@ import org.apache.syncope.core.persisten
import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
import org.apache.syncope.core.persistence.dao.SubjectSearchDAO;
import org.apache.syncope.core.persistence.dao.ConfDAO;
+import org.apache.syncope.core.persistence.dao.NotFoundException;
import org.apache.syncope.core.persistence.dao.RoleDAO;
import org.apache.syncope.core.persistence.dao.UserDAO;
import org.apache.syncope.core.persistence.dao.search.OrderByClause;
@@ -107,6 +108,11 @@ public class UserController extends Abst
return confDAO.find("selfRegistration.allowed", "false").getValues().get(0).getBooleanValue();
}
+ @Transactional(readOnly = true)
+ public boolean isPasswordResetAllowed() {
+ return confDAO.find("passwordReset.allowed", "false").getValues().get(0).getBooleanValue();
+ }
+
@PreAuthorize("hasRole('USER_READ')")
public String getUsername(final Long userId) {
return binder.getUserTO(userId).getUsername();
@@ -359,6 +365,46 @@ public class UserController extends Abst
return savedTO;
}
+ @PreAuthorize("isAnonymous() or hasRole(T(org.apache.syncope.common.SyncopeConstants).ANONYMOUS_ENTITLEMENT)")
+ @Transactional
+ public void requestPasswordReset(final String username, final String securityAnswer) {
+ if (username == null) {
+ throw new NotFoundException("Null username");
+ }
+
+ SyncopeUser user = userDAO.find(username);
+ if (user == null) {
+ throw new NotFoundException("User " + username);
+ }
+
+ if (securityAnswer == null || !securityAnswer.equals(user.getSecurityAnswer())) {
+ throw SyncopeClientException.build(ClientExceptionType.InvalidSecurityAnswer);
+ }
+
+ uwfAdapter.requestPasswordReset(user.getId());
+ }
+
+ @PreAuthorize("isAnonymous() or hasRole(T(org.apache.syncope.common.SyncopeConstants).ANONYMOUS_ENTITLEMENT)")
+ @Transactional
+ public void confirmPasswordReset(final String token, final String password) {
+ SyncopeUser user = userDAO.findByToken(token);
+ if (user == null) {
+ throw new NotFoundException("User with token " + token);
+ }
+
+ uwfAdapter.confirmPasswordReset(user.getId(), token, password);
+
+ List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(user, null, null);
+ PropagationReporter propReporter =
+ ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
+ try {
+ taskExecutor.execute(tasks, propReporter);
+ } catch (PropagationException e) {
+ LOG.error("Error propagation primary resource", e);
+ propReporter.onPrimaryResourceFailure(tasks);
+ }
+ }
+
@PreAuthorize("isAuthenticated() "
+ "and not(hasRole(T(org.apache.syncope.common.SyncopeConstants).ANONYMOUS_ENTITLEMENT))")
public UserTO deleteSelf() {
@@ -564,14 +610,11 @@ public class UserController extends Abst
return original;
}
- /**
- * {@inheritDoc}
- */
@Override
protected UserTO resolveReference(final Method method, final Object... args) throws UnresolvedReferenceException {
Object id = null;
- if (ArrayUtils.isNotEmpty(args)) {
+ if (!"confirmPasswordReset".equals(method.getName()) && ArrayUtils.isNotEmpty(args)) {
for (int i = 0; id == null && i < args.length; i++) {
if (args[i] instanceof Long) {
id = (Long) args[i];
Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/AbstractAttributableDataBinder.java Fri Sep 19 08:53:24 2014
@@ -73,7 +73,6 @@ import org.apache.syncope.core.persisten
import org.apache.syncope.core.persistence.beans.user.UVirSchema;
import org.apache.syncope.core.persistence.dao.AttrDAO;
import org.apache.syncope.core.persistence.dao.AttrValueDAO;
-import org.apache.syncope.core.persistence.dao.ConfDAO;
import org.apache.syncope.core.persistence.dao.DerAttrDAO;
import org.apache.syncope.core.persistence.dao.DerSchemaDAO;
import org.apache.syncope.core.persistence.dao.MembershipDAO;
@@ -101,9 +100,6 @@ public abstract class AbstractAttributab
protected static final Logger LOG = LoggerFactory.getLogger(AbstractAttributableDataBinder.class);
@Autowired
- protected ConfDAO confDAO;
-
- @Autowired
protected RoleDAO roleDAO;
@Autowired
@@ -215,8 +211,8 @@ public abstract class AbstractAttributab
List<String> valuesProvided = schema.isMultivalue()
? values
: (values.isEmpty()
- ? Collections.<String>emptyList()
- : Collections.singletonList(values.iterator().next()));
+ ? Collections.<String>emptyList()
+ : Collections.singletonList(values.iterator().next()));
for (String value : valuesProvided) {
if (value == null || value.isEmpty()) {
Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/NotificationDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/NotificationDataBinder.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/NotificationDataBinder.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/NotificationDataBinder.java Fri Sep 19 08:53:24 2014
@@ -41,13 +41,13 @@ public class NotificationDataBinder {
return result;
}
- public Notification createNotification(final NotificationTO notificationTO) {
+ public Notification create(final NotificationTO notificationTO) {
Notification result = new Notification();
- updateNotification(result, notificationTO);
+ update(result, notificationTO);
return result;
}
- public void updateNotification(final Notification notification, final NotificationTO notificationTO) {
+ public void update(final Notification notification, final NotificationTO notificationTO) {
BeanUtils.copyProperties(notificationTO, notification, IGNORE_PROPERTIES);
notification.setUserAbout(notificationTO.getUserAbout());
Added: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/SecurityQuestionDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/SecurityQuestionDataBinder.java?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/SecurityQuestionDataBinder.java (added)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/SecurityQuestionDataBinder.java Fri Sep 19 08:53:24 2014
@@ -0,0 +1,46 @@
+/*
+ * 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.rest.data;
+
+import org.apache.syncope.common.to.SecurityQuestionTO;
+import org.apache.syncope.common.util.BeanUtils;
+import org.apache.syncope.core.persistence.beans.SecurityQuestion;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SecurityQuestionDataBinder {
+
+ public SecurityQuestionTO getSecurityQuestionTO(final SecurityQuestion securityQuestion) {
+ SecurityQuestionTO securityQuestionTO = new SecurityQuestionTO();
+
+ BeanUtils.copyProperties(securityQuestion, securityQuestionTO);
+
+ return securityQuestionTO;
+ }
+
+ public SecurityQuestion create(final SecurityQuestionTO securityQuestionTO) {
+ SecurityQuestion result = new SecurityQuestion();
+ update(result, securityQuestionTO);
+ return result;
+ }
+
+ public void update(final SecurityQuestion securityQuestion, final SecurityQuestionTO securityQuestionTO) {
+ BeanUtils.copyProperties(securityQuestionTO, securityQuestion, "id");
+ }
+}
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/SecurityQuestionDataBinder.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/SecurityQuestionDataBinder.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/SecurityQuestionDataBinder.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java Fri Sep 19 08:53:24 2014
@@ -30,9 +30,7 @@ import org.apache.syncope.common.mod.Use
import org.apache.syncope.common.to.MembershipTO;
import org.apache.syncope.common.to.UserTO;
import org.apache.syncope.common.types.AttributableType;
-import org.apache.syncope.common.types.CipherAlgorithm;
import org.apache.syncope.common.types.IntMappingType;
-import org.apache.syncope.common.types.PasswordPolicySpec;
import org.apache.syncope.common.types.ResourceOperation;
import org.apache.syncope.common.types.ClientExceptionType;
import org.apache.syncope.common.util.BeanUtils;
@@ -45,7 +43,7 @@ import org.apache.syncope.core.persisten
import org.apache.syncope.core.persistence.beans.AbstractMappingItem;
import org.apache.syncope.core.persistence.beans.AbstractVirAttr;
import org.apache.syncope.core.persistence.beans.ExternalResource;
-import org.apache.syncope.core.persistence.beans.PasswordPolicy;
+import org.apache.syncope.core.persistence.beans.SecurityQuestion;
import org.apache.syncope.core.persistence.beans.membership.MAttr;
import org.apache.syncope.core.persistence.beans.membership.MDerAttr;
import org.apache.syncope.core.persistence.beans.membership.MVirAttr;
@@ -53,6 +51,7 @@ import org.apache.syncope.core.persisten
import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
import org.apache.syncope.core.persistence.dao.NotFoundException;
+import org.apache.syncope.core.persistence.dao.SecurityQuestionDAO;
import org.apache.syncope.core.propagation.PropagationByResource;
import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
import org.apache.syncope.core.util.AttributableUtil;
@@ -68,12 +67,15 @@ import org.springframework.transaction.a
public class UserDataBinder extends AbstractAttributableDataBinder {
private static final String[] IGNORE_USER_PROPERTIES = {
- "memberships", "attrs", "derAttrs", "virAttrs", "resources"
+ "memberships", "attrs", "derAttrs", "virAttrs", "resources", "securityQuestion"
};
@Autowired
private ConnObjectUtil connObjectUtil;
+ @Autowired
+ private SecurityQuestionDAO securityQuestionDAO;
+
@Resource(name = "adminUser")
private String adminUser;
@@ -82,6 +84,21 @@ public class UserDataBinder extends Abst
private final Encryptor encryptor = Encryptor.getInstance();
+ private void securityChecks(final SyncopeUser user) {
+ // Allows anonymous (during self-registration) and self (during self-update) to read own SyncopeUser,
+ // otherwise goes thorugh security checks to see if needed role entitlements are owned
+ if (!EntitlementUtil.getAuthenticatedUsername().equals(anonymousUser)
+ && !EntitlementUtil.getAuthenticatedUsername().equals(user.getUsername())) {
+
+ Set<Long> roleIds = user.getRoleIds();
+ Set<Long> adminRoleIds = EntitlementUtil.getRoleIds(EntitlementUtil.getOwnedEntitlementNames());
+ roleIds.removeAll(adminRoleIds);
+ if (!roleIds.isEmpty()) {
+ throw new UnauthorizedRoleException(roleIds);
+ }
+ }
+ }
+
@Transactional(readOnly = true)
public SyncopeUser getUserFromId(final Long userId) {
if (userId == null) {
@@ -93,19 +110,24 @@ public class UserDataBinder extends Abst
throw new NotFoundException("User " + userId);
}
- // Allows anonymous (during self-registration) and self (during self-update) to read own SyncopeUser,
- // otherwise goes thorugh security checks to see if needed role entitlements are owned
- if (!EntitlementUtil.getAuthenticatedUsername().equals(anonymousUser)
- && !EntitlementUtil.getAuthenticatedUsername().equals(user.getUsername())) {
+ securityChecks(user);
- Set<Long> roleIds = user.getRoleIds();
- Set<Long> adminRoleIds = EntitlementUtil.getRoleIds(EntitlementUtil.getOwnedEntitlementNames());
- roleIds.removeAll(adminRoleIds);
- if (!roleIds.isEmpty()) {
- throw new UnauthorizedRoleException(roleIds);
- }
+ return user;
+ }
+
+ @Transactional(readOnly = true)
+ public SyncopeUser getUserFromUsername(final String username) {
+ if (username == null) {
+ throw new NotFoundException("Null username");
+ }
+
+ SyncopeUser user = userDAO.find(username);
+ if (user == null) {
+ throw new NotFoundException("User " + username);
}
+ securityChecks(user);
+
return user;
}
@@ -159,55 +181,11 @@ public class UserDataBinder extends Abst
return encryptor.verify(password, user.getCipherAlgorithm(), user.getPassword());
}
- @Transactional(readOnly = true)
- public SyncopeUser getUserFromUsername(final String username) {
- if (username == null) {
- throw new NotFoundException("Null username");
- }
-
- SyncopeUser user = userDAO.find(username);
- if (user == null) {
- throw new NotFoundException("User " + username);
- }
-
- Set<Long> roleIds = user.getRoleIds();
- Set<Long> adminRoleIds = EntitlementUtil.getRoleIds(EntitlementUtil.getOwnedEntitlementNames());
- roleIds.removeAll(adminRoleIds);
-
- if (!roleIds.isEmpty()) {
- throw new UnauthorizedRoleException(roleIds);
- }
-
- return user;
- }
-
- /**
- * Get predefined password cipher algorithm from SyncopeConf.
- *
- * @return cipher algorithm.
- */
- private CipherAlgorithm getPredefinedCipherAlgoritm() {
- final String algorithm = confDAO.find(
- "password.cipher.algorithm", CipherAlgorithm.AES.name()).getValues().get(0).getStringValue();
-
- try {
- return CipherAlgorithm.valueOf(algorithm);
- } catch (IllegalArgumentException e) {
- throw new NotFoundException("Cipher algorithm " + algorithm);
- }
- }
-
private void setPassword(final SyncopeUser user, final String password,
final SyncopeClientCompositeException scce) {
- int passwordHistorySize = 0;
- PasswordPolicy policy = policyDAO.getGlobalPasswordPolicy();
- if (policy != null && policy.getSpecification(PasswordPolicySpec.class) != null) {
- passwordHistorySize = policy.getSpecification(PasswordPolicySpec.class).getHistoryLength();
- }
-
try {
- user.setPassword(password, getPredefinedCipherAlgoritm(), passwordHistorySize);
+ user.setPassword(password, Encryptor.getPredefinedCipherAlgoritm());
} catch (NotFoundException e) {
final SyncopeClientException invalidCiperAlgorithm =
SyncopeClientException.build(ClientExceptionType.NotFound);
@@ -261,6 +239,15 @@ public class UserDataBinder extends Abst
// set username
user.setUsername(userTO.getUsername());
+
+ // security question / answer
+ if (userTO.getSecurityQuestion() != null) {
+ SecurityQuestion securityQuestion = securityQuestionDAO.find(userTO.getSecurityQuestion());
+ if (securityQuestion != null) {
+ user.setSecurityQuestion(securityQuestion);
+ }
+ }
+ user.setSecurityAnswer(userTO.getSecurityAnswer());
}
/**
@@ -304,6 +291,21 @@ public class UserDataBinder extends Abst
}
}
+ // security question / answer:
+ // userMod.getSecurityQuestion() is null => remove user security question and answer
+ // userMod.getSecurityQuestion() == 0 => don't change anything
+ // userMod.getSecurityQuestion() > 0 => update user security question and answer
+ if (userMod.getSecurityQuestion() == null) {
+ user.setSecurityQuestion(null);
+ user.setSecurityAnswer(null);
+ } else if (userMod.getSecurityQuestion() > 0) {
+ SecurityQuestion securityQuestion = securityQuestionDAO.find(userMod.getSecurityQuestion());
+ if (securityQuestion != null) {
+ user.setSecurityQuestion(securityQuestion);
+ user.setSecurityAnswer(userMod.getSecurityAnswer());
+ }
+ }
+
// attributes, derived attributes, virtual attributes and resources
propByRes.merge(fill(user, userMod, AttributableUtil.getInstance(AttributableType.USER), scce));
@@ -413,8 +415,11 @@ public class UserDataBinder extends Abst
BeanUtils.copyProperties(user, userTO, IGNORE_USER_PROPERTIES);
- connObjectUtil.retrieveVirAttrValues(user, AttributableUtil.getInstance(AttributableType.USER));
+ if (user.getSecurityQuestion() != null) {
+ userTO.setSecurityQuestion(user.getSecurityQuestion().getId());
+ }
+ connObjectUtil.retrieveVirAttrValues(user, AttributableUtil.getInstance(AttributableType.USER));
fillTO(userTO, user.getAttrs(), user.getDerAttrs(), user.getVirAttrs(), user.getResources());
MembershipTO membershipTO;
@@ -495,8 +500,8 @@ public class UserDataBinder extends Abst
? fillVirtual(
membership,
membership.getVirAttrs() == null
- ? Collections.<String>emptySet()
- : getAttributeNames(membership.getVirAttrs()),
+ ? Collections.<String>emptySet()
+ : getAttributeNames(membership.getVirAttrs()),
vAttrsToBeUpdated,
AttributableUtil.getInstance(AttributableType.MEMBERSHIP))
: fillVirtual(
Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/NotificationServiceImpl.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/NotificationServiceImpl.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/NotificationServiceImpl.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/NotificationServiceImpl.java Fri Sep 19 08:53:24 2014
@@ -38,10 +38,10 @@ public class NotificationServiceImpl ext
@Override
public Response create(final NotificationTO notificationTO) {
- NotificationTO createdNotificationTO = controller.create(notificationTO);
- URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(createdNotificationTO.getId())).build();
+ NotificationTO created = controller.create(notificationTO);
+ URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getId())).build();
return Response.created(location).
- header(RESTHeaders.RESOURCE_ID, createdNotificationTO.getId()).
+ header(RESTHeaders.RESOURCE_ID, created.getId()).
build();
}
Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/SchemaServiceImpl.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/SchemaServiceImpl.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/SchemaServiceImpl.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/SchemaServiceImpl.java Fri Sep 19 08:53:24 2014
@@ -42,11 +42,11 @@ public class SchemaServiceImpl extends A
public <T extends AbstractSchemaTO> Response create(final AttributableType attrType, final SchemaType schemaType,
final T schemaTO) {
- T response = controller.create(attrType, schemaType, schemaTO);
+ T created = controller.create(attrType, schemaType, schemaTO);
- URI location = uriInfo.getAbsolutePathBuilder().path(response.getName()).build();
+ URI location = uriInfo.getAbsolutePathBuilder().path(created.getName()).build();
return Response.created(location).
- header(RESTHeaders.RESOURCE_ID, response.getName()).
+ header(RESTHeaders.RESOURCE_ID, created.getName()).
build();
}
Added: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/SecurityQuestionServiceImpl.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/SecurityQuestionServiceImpl.java?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/SecurityQuestionServiceImpl.java (added)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/SecurityQuestionServiceImpl.java Fri Sep 19 08:53:24 2014
@@ -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.core.services;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.services.SecurityQuestionService;
+import org.apache.syncope.common.to.SecurityQuestionTO;
+import org.apache.syncope.common.types.RESTHeaders;
+import org.apache.syncope.core.rest.controller.SecurityQuestionController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class SecurityQuestionServiceImpl extends AbstractServiceImpl implements SecurityQuestionService {
+
+ @Autowired
+ private SecurityQuestionController controller;
+
+ @Override
+ public List<SecurityQuestionTO> list() {
+ return controller.list();
+ }
+
+ @Override
+ public SecurityQuestionTO read(final Long securityQuestionId) {
+ return controller.read(securityQuestionId);
+ }
+
+ @Override
+ public Response create(final SecurityQuestionTO securityQuestionTO) {
+ SecurityQuestionTO created = controller.create(securityQuestionTO);
+
+ URI location = uriInfo.getAbsolutePathBuilder().path(String.valueOf(created.getId())).build();
+ return Response.created(location).
+ header(RESTHeaders.RESOURCE_ID, String.valueOf(created.getId())).
+ build();
+ }
+
+ @Override
+ public void update(final Long securityQuestionId, final SecurityQuestionTO securityQuestionTO) {
+ securityQuestionTO.setId(securityQuestionId);
+ controller.update(securityQuestionTO);
+ }
+
+ @Override
+ public void delete(final Long securityQuestionId) {
+ controller.delete(securityQuestionId);
+ }
+
+ @Override
+ public SecurityQuestionTO readByUser(final String username) {
+ return controller.read(username);
+ }
+
+}
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/SecurityQuestionServiceImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/SecurityQuestionServiceImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/SecurityQuestionServiceImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/UserSelfServiceImpl.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/UserSelfServiceImpl.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/UserSelfServiceImpl.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/services/UserSelfServiceImpl.java Fri Sep 19 08:53:24 2014
@@ -40,6 +40,7 @@ public class UserSelfServiceImpl extends
public Response getOptions() {
return Response.ok().header(HttpHeaders.ALLOW, OPTIONS_ALLOW).
header(RESTHeaders.SELFREGISTRATION_ALLOWED, controller.isSelfRegistrationAllowed()).
+ header(RESTHeaders.PASSWORDRESET_ALLOWED, controller.isSelfRegistrationAllowed()).
build();
}
@@ -47,7 +48,7 @@ public class UserSelfServiceImpl extends
public Response create(final UserTO userTO, final boolean storePassword) {
if (!controller.isSelfRegistrationAllowed()) {
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unauthorized);
- sce.getElements().add("SelfRegistration forbidden by configuration");
+ sce.getElements().add("Self registration forbidden by configuration");
throw sce;
}
@@ -73,4 +74,26 @@ public class UserSelfServiceImpl extends
return modificationResponse(deleted);
}
+ @Override
+ public void requestPasswordReset(final String username, final String securityAnswer) {
+ if (!controller.isPasswordResetAllowed()) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unauthorized);
+ sce.getElements().add("Password reset forbidden by configuration");
+ throw sce;
+ }
+
+ controller.requestPasswordReset(username, securityAnswer);
+ }
+
+ @Override
+ public void confirmPasswordReset(final String token, final String password) {
+ if (!controller.isPasswordResetAllowed()) {
+ SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unauthorized);
+ sce.getElements().add("Password reset forbidden by configuration");
+ throw sce;
+ }
+
+ controller.confirmPasswordReset(token, password);
+ }
+
}
Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/util/Encryptor.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/util/Encryptor.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/util/Encryptor.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/util/Encryptor.java Fri Sep 19 08:53:24 2014
@@ -35,6 +35,8 @@ import org.apache.commons.lang3.ArrayUti
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.SyncopeConstants;
import org.apache.syncope.common.types.CipherAlgorithm;
+import org.apache.syncope.core.persistence.dao.ConfDAO;
+import org.apache.syncope.core.persistence.dao.NotFoundException;
import org.jasypt.commons.CommonUtils;
import org.jasypt.digest.StandardStringDigester;
import org.slf4j.Logger;
@@ -132,6 +134,22 @@ public final class Encryptor {
}
}
+ /**
+ * Get predefined password cipher algorithm from SyncopeConf.
+ *
+ * @return cipher algorithm.
+ */
+ public static CipherAlgorithm getPredefinedCipherAlgoritm() {
+ ConfDAO confDAO = ApplicationContextProvider.getApplicationContext().getBean(ConfDAO.class);
+ final String algorithm = confDAO.find(
+ "password.cipher.algorithm", CipherAlgorithm.AES.name()).getValues().get(0).getStringValue();
+ try {
+ return CipherAlgorithm.valueOf(algorithm);
+ } catch (IllegalArgumentException e) {
+ throw new NotFoundException("Cipher algorithm " + algorithm);
+ }
+ }
+
public static Encryptor getInstance() {
return getInstance(secretKey);
}
Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/util/POJOHelper.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/util/POJOHelper.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/util/POJOHelper.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/util/POJOHelper.java Fri Sep 19 08:53:24 2014
@@ -18,9 +18,11 @@
*/
package org.apache.syncope.core.util;
+import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import org.identityconnectors.common.security.GuardedString;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.SyncToken;
@@ -46,6 +48,7 @@ public final class POJOHelper {
MAPPER = new ObjectMapper();
MAPPER.registerModule(pojoModule);
+ MAPPER.registerModule(new AfterburnerModule());
}
public static String serialize(final Object object) {