From eb85b11e05491f1c76e6600594c1a61e001c65ae Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Wed, 2 Nov 2016 10:46:52 +0100 Subject: [PATCH 1/2] small improvements for registration process - suport initial/required lifecycle state, .. --- .../api/component/captcha/CaptchaPanel.html | 35 +++++ .../api/component/captcha/CaptchaPanel.java | 108 +++++++++++++++ .../login/PageRegistrationConfirmation.java | 42 +++++- .../web/page/login/PageSelfRegistration.html | 19 +-- .../web/page/login/PageSelfRegistration.java | 131 ++++++------------ .../web/page/login/SelfRegistrationDto.java | 35 +++-- .../xml/ns/public/common/common-core-3.xsd | 10 +- .../security/AuthenticationEvaluatorImpl.java | 12 +- 8 files changed, 270 insertions(+), 122 deletions(-) create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/captcha/CaptchaPanel.html create mode 100644 gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/captcha/CaptchaPanel.java diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/captcha/CaptchaPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/captcha/CaptchaPanel.html new file mode 100644 index 00000000000..15e03df5e0c --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/captcha/CaptchaPanel.html @@ -0,0 +1,35 @@ + + + + + + +

+ + change +

+

+ Please replicate the text you see above +
+ +

+ +
+
+ + + \ No newline at end of file diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/captcha/CaptchaPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/captcha/CaptchaPanel.java new file mode 100644 index 00000000000..944caf49868 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/captcha/CaptchaPanel.java @@ -0,0 +1,108 @@ +package com.evolveum.midpoint.gui.api.component.captcha; + +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.AjaxLink; +import org.apache.wicket.extensions.markup.html.captcha.CaptchaImageResource; +import org.apache.wicket.feedback.ContainerFeedbackMessageFilter; +import org.apache.wicket.markup.ComponentTag; +import org.apache.wicket.markup.html.form.RequiredTextField; +import org.apache.wicket.markup.html.image.Image; +import org.apache.wicket.markup.html.panel.FeedbackPanel; +import org.apache.wicket.model.PropertyModel; + +import com.evolveum.midpoint.gui.api.component.BasePanel; + +public class CaptchaPanel extends BasePanel { + + private static final long serialVersionUID = 1L; + + /** + * The generated random text; + */ + protected String randomText; + + /** + * The text provided by the user + */ + private String captchaText; + + private final CaptchaImageResource captchaImageResource; + + /** + * Constructor. + * + * @param id + * The component id + */ + public CaptchaPanel(String id) { + super(id); + + final FeedbackPanel feedback = new FeedbackPanel("feedback", + new ContainerFeedbackMessageFilter(CaptchaPanel.this)); + add(feedback); + + captchaImageResource = createCaptchImageResource(); + final Image captchaImage = new Image("image", captchaImageResource); + captchaImage.setOutputMarkupId(true); + add(captchaImage); + + AjaxLink changeCaptchaLink = new AjaxLink("changeLink") { + private static final long serialVersionUID = 1L; + + @Override + public void onClick(AjaxRequestTarget target) { + captchaImageResource.invalidate(); + target.add(captchaImage); + } + }; + add(changeCaptchaLink); + + add(new RequiredTextField("text", + new PropertyModel(CaptchaPanel.this, "captchaText"), String.class) { + private static final long serialVersionUID = 1L; + + @Override + protected final void onComponentTag(final ComponentTag tag) { + super.onComponentTag(tag); + // clear the field after each render + tag.put("value", ""); + } + }); + } + + protected CaptchaImageResource createCaptchImageResource() { + return new CaptchaImageResource() { + private static final long serialVersionUID = 1L; + + @Override + protected byte[] render() { + randomText = randomString(6, 8); + getChallengeIdModel().setObject(randomText); + return super.render(); + } + }; + } + + public void invalidateCaptcha() { + captchaImageResource.invalidate(); + } + + static int randomInt(int min, int max) + { + return (int)(Math.random() * (max - min) + min); + } + + static String randomString(int min, int max) + { + int num = randomInt(min, max); + byte b[] = new byte[num]; + for (int i = 0; i < num; i++) + b[i] = (byte)randomInt('a', 'z'); + return new String(b); + } + + public String getCaptchaText() { + return captchaText; + } + +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageRegistrationConfirmation.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageRegistrationConfirmation.java index 03dc53935d1..49e1a31de66 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageRegistrationConfirmation.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageRegistrationConfirmation.java @@ -35,6 +35,7 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.NonceType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; //CONFIRMATION_LINK = "http://localhost:8080/midpoint/confirm/registration/"; @@ -48,7 +49,8 @@ public class PageRegistrationConfirmation extends PageRegistrationBase { private static final String ID_LINK_LOGIN = "linkToLogin"; private static final String ID_SUCCESS_PANEL = "successPanel"; private static final String ID_ERROR_PANEL = "errorPanel"; - + + private static final String OPERATION_ASSIGN_DEFAULT_ROLES = DOT_CLASS + ".assignDefaultRoles"; private static final String OPERATION_FINISH_REGISTRATION = DOT_CLASS + "finishRegistration"; private static final long serialVersionUID = 1L; @@ -84,6 +86,12 @@ private void init(final PageParameters pageParameters) { } final MidPointPrincipal principal = (MidPointPrincipal) token.getPrincipal(); + result = assignDefaultRoles(principal.getOid()); + if (result.getStatus() == OperationResultStatus.FATAL_ERROR) { + initLayout(result); + return; + } + final NonceType nonceClone = principal.getUser().getCredentials().getNonce().clone(); result = removeNonce(principal.getOid(), nonceClone); @@ -106,6 +114,37 @@ private UsernamePasswordAuthenticationToken authenticateUser(String username, St } } + private OperationResult assignDefaultRoles(final String userOid){ + List> assignments = new ArrayList<>(); + for (ObjectReferenceType defaultRole : getSelfRegistrationConfiguration().getDefaultRoles()) { + AssignmentType assignment = new AssignmentType(); + assignment.setTargetRef(defaultRole); + try { + getPrismContext().adopt(assignment); + assignments.add(ContainerDelta.createModificationAdd(UserType.F_ASSIGNMENT, UserType.class, getPrismContext(), assignment)); + } catch (SchemaException e) { + //nothing to do + } + } + + final ObjectDelta delta = ObjectDelta.createModifyDelta(userOid, assignments, UserType.class, getPrismContext()); + + return runPrivileged(new Producer() { + + @Override + public OperationResult run() { + OperationResult result = new OperationResult(OPERATION_ASSIGN_DEFAULT_ROLES); + Task task = createAnonymousTask(OPERATION_ASSIGN_DEFAULT_ROLES); + WebModelServiceUtils.save(delta, result, task, PageRegistrationConfirmation.this); + result.computeStatusIfUnknown(); + + return result; + } + }); + + + } + private OperationResult removeNonce(final String userOid, final NonceType nonce){ return runPrivileged(new Producer() { @@ -117,6 +156,7 @@ public OperationResult run() { ObjectDelta userAssignmentsDelta; try { userAssignmentsDelta = ObjectDelta.createModificationDeleteContainer(UserType.class, userOid, new ItemPath(UserType.F_CREDENTIALS, CredentialsType.F_NONCE), getPrismContext(), nonce); + userAssignmentsDelta.addModificationReplaceProperty(UserType.F_LIFECYCLE_STATE, SchemaConstants.LIFECYCLE_ACTIVE); } catch (SchemaException e) { result.recordFatalError("Could not create delta"); return result; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.html index f7dc3d94022..588ec94873c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.html @@ -86,22 +86,11 @@ - - -

- -

-

- -

- - - - - - + +
+ + +

diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.java index 83f13c33a72..70f49e6b3c5 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.java @@ -25,6 +25,7 @@ import com.evolveum.midpoint.common.policy.StringPolicyUtils; import com.evolveum.midpoint.common.policy.ValuePolicyGenerator; import com.evolveum.midpoint.gui.api.component.autocomplete.AutoCompleteTextPanel; +import com.evolveum.midpoint.gui.api.component.captcha.CaptchaPanel; import com.evolveum.midpoint.gui.api.component.password.PasswordPanel; import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.gui.api.page.PageBase; @@ -100,6 +101,8 @@ public class PageSelfRegistration extends PageRegistrationBase { private static final String ID_CHANGE_LINK = "changeLink"; private static final String ID_USER_TEXT = "text"; + private static final String ID_CAPTCHA = "captcha"; + private static final String OPERATION_SAVE_USER = DOT_CLASS + "saveUser"; private static final String OPERATION_LOAD_ORGANIZATIONS = DOT_CLASS + "loadOrganization"; @@ -216,44 +219,35 @@ public Iterator getIterator(String input) { password.getBaseFormComponent().add(new EmptyOnBlurAjaxFormUpdatingBehaviour()); mainForm.add(password); - final CaptchaImageResource captcha = new CaptchaImageResource(new AbstractReadOnlyModel() { - - private static final long serialVersionUID = 1L; - - @Override - public String getObject() { - randomString = generateCaptcha(); - return randomString; - } - - }); - - final Image captchaImage = new Image(ID_IMAGE, captcha); - captchaImage.setOutputMarkupId(true); - mainForm.add(captchaImage); - - AjaxLink changeCaptchaLink = new AjaxLink(ID_CHANGE_LINK) { - private static final long serialVersionUID = 1L; - - @Override - public void onClick(AjaxRequestTarget target) { - updateCaptcha(captcha, target); - } - }; - mainForm.add(changeCaptchaLink); - - RequiredTextField userText = new RequiredTextField(ID_USER_TEXT, - new PropertyModel(PageSelfRegistration.this, "captchaString"), String.class) { - - private static final long serialVersionUID = 1L; + CaptchaPanel captcha = new CaptchaPanel(ID_CAPTCHA); + captcha.setOutputMarkupId(true); +// final CaptchaImageResource captcha = new CaptchaImageResource(new AbstractReadOnlyModel() { +// +// private static final long serialVersionUID = 1L; +// +// @Override +// public String getObject() { +// randomString = generateCaptcha(); +// return randomString; +// } +// +// }); +// +// final Image captchaImage = new Image(ID_IMAGE, captcha); +// captchaImage.setOutputMarkupId(true); + mainForm.add(captcha); - @Override - protected final void onComponentTag(final ComponentTag tag) { - super.onComponentTag(tag); - tag.put("value", ""); - } +// AjaxLink changeCaptchaLink = new AjaxLink(ID_CHANGE_LINK) { +// private static final long serialVersionUID = 1L; +// +// @Override +// public void onClick(AjaxRequestTarget target) { +// updateCaptcha(captcha, target); +// } +// }; +// mainForm.add(changeCaptchaLink); - }; + // userText.add(new EmptyOnBlurAjaxFormUpdatingBehaviour(){ // // @Override @@ -262,9 +256,7 @@ protected final void onComponentTag(final ComponentTag tag) { // getDefaultModelObject(); // } // }); - userText.setOutputMarkupId(true); - - mainForm.add(userText); + AjaxSubmitButton register = new AjaxSubmitButton(ID_SUBMIT_REGISTRATION) { @@ -273,7 +265,7 @@ protected final void onComponentTag(final ComponentTag tag) { protected void onSubmit(AjaxRequestTarget target, org.apache.wicket.markup.html.form.Form form) { - submitRegistration(target, captcha); + submitRegistration(target); } @@ -302,7 +294,7 @@ public boolean isEnabled() { } - private void submitRegistration(AjaxRequestTarget target, CaptchaImageResource captcha) { + private void submitRegistration(AjaxRequestTarget target) { OperationResult result = runPrivileged(new Producer() { @@ -324,37 +316,6 @@ public OperationResult run() { getSession() .success(createStringResource("PageSelfRegistration.registration.success").getString()); -// PageParameters params = getPageParameters(); -// -// if (params != null) { -// ConnectionEnvironment connEnv = new ConnectionEnvironment(); -// connEnv.setChannel(SchemaConstants.CHANNEL_GUI_SELF_REGISTRATION_URI); -// UserType userType = userModel.getObject(); -// ProtectedStringType protectedString = userType.getCredentials().getNonce().getValue(); -// String nonce = null; -// if (protectedString.getClearValue() == null) { -// getPrismContext().getDefaultProtector(). -// } -// getAuthenticationEvaluator().authenticateUserNonce(connEnv, userType.getName().getOrig(),, noncePolicy) -// List values = params.getAllNamed(); -// List> rolesToAssign = new ArrayList<>(); -// Task task = createSimpleTask("Request roles"); -// for (NamedPair namedPair : values) { -// PrismObject abstractRole = WebModelServiceUtils.loadObject(AbstractRoleType.class, namedPair.getValue(), this, task, result); -// AssignmentType assignment = new AssignmentType(); -// if (abstractRole != null) { -// assignment.setTarget(abstractRole.asObjectable()); -// try { -// rolesToAssign.add(ContainerDelta.createModificationAdd(UserType.F_ASSIGNMENT, UserType.class, getPrismContext(), assignment)); -// } catch (SchemaException e) { -// //just ignore this assignment (for now) -// } -// } -// } -// } -// -// - switch (getSelfRegistrationConfiguration().getAuthenticationMethod()) { case MAIL: target.add(PageSelfRegistration.this); @@ -373,7 +334,7 @@ public OperationResult run() { } - updateCaptcha(captcha, target); + updateCaptcha(target); target.add(getFeedbackPanel()); } @@ -423,11 +384,11 @@ public List run() { } - private void updateCaptcha(CaptchaImageResource captcha, AjaxRequestTarget target) { + private void updateCaptcha(AjaxRequestTarget target) { - captcha.invalidate(); - Image captchaImage = (Image) get(createComponentPath(ID_MAIN_FORM, ID_IMAGE)); - target.add(captchaImage); + CaptchaPanel captcha = (CaptchaPanel) get(createComponentPath(ID_MAIN_FORM, ID_CAPTCHA)); + captcha.invalidateCaptcha(); + target.add(captcha); } private void saveUser(Task task, OperationResult result) { @@ -467,19 +428,8 @@ private UserType prepareUserToSave(Task task, } userType.getCredentials().setNonce(nonceType); + userType.setLifecycleState(getSelfRegistrationConfiguration().getInitialLifecycleState()); - for (ObjectReferenceType defaultRole : getSelfRegistrationConfiguration().getDefaultRoles()) { - AssignmentType assignment = new AssignmentType(); - assignment.setTargetRef(defaultRole); - try { - getPrismContext().adopt(assignment); - userType.getAssignment().add(assignment); - } catch (SchemaException e) { - //nothing to do - } - - } - try { getPrismContext().adopt(userType); } catch (SchemaException e) { @@ -492,7 +442,8 @@ private UserType prepareUserToSave(Task task, private String generateNonce(NonceCredentialsPolicyType noncePolicy, Task task, OperationResult result) { ValuePolicyType policy = null; - if (noncePolicy.getValuePolicyRef() != null) { + + if (noncePolicy != null && noncePolicy.getValuePolicyRef() != null) { PrismObject valuePolicy = WebModelServiceUtils.loadObject(ValuePolicyType.class, noncePolicy.getValuePolicyRef().getOid(), PageSelfRegistration.this, task, result); policy = valuePolicy.asObjectable(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/SelfRegistrationDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/SelfRegistrationDto.java index f997f6c407a..7a6785eed1e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/SelfRegistrationDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/SelfRegistrationDto.java @@ -32,6 +32,9 @@ enum AuthenticationPolicy { private MailAuthenticationPolicyType mailAuthenticationPolicy; private SmsAuthenticationPolicyType smsAuthenticationPolicy; private NonceCredentialsPolicyType noncePolicy; + + private String requiredLifecycleState; + private String initialLifecycleState; public void initSelfRegistrationDto(SecurityPolicyType securityPolicy) throws SchemaException { if (securityPolicy == null) { @@ -44,17 +47,21 @@ public void initSelfRegistrationDto(SecurityPolicyType securityPolicy) throws Sc this.name = selfRegistration.getName(); this.defaultRoles = selfRegistration.getDefaultRole(); - + this.initialLifecycleState = selfRegistration.getInitialLifecycleState(); + this.requiredLifecycleState = selfRegistration.getRequiredLifecycleState(); + AbstractAuthenticationPolicyType authPolicy = getAuthenticationPolicy( selfRegistration.getAdditionalAuthenticationName(), securityPolicy); if (authPolicy instanceof MailAuthenticationPolicyType) { this.mailAuthenticationPolicy = (MailAuthenticationPolicyType) authPolicy; + noncePolicy = getCredentialPolicy(((MailAuthenticationPolicyType) authPolicy).getMailNonce(), securityPolicy); } else if (authPolicy instanceof SmsAuthenticationPolicyType) { this.smsAuthenticationPolicy = (SmsAuthenticationPolicyType) authPolicy; + noncePolicy = getCredentialPolicy(((SmsAuthenticationPolicyType) authPolicy).getSmsNonce(), securityPolicy); } - noncePolicy = getCredentialPolicy(authPolicy, securityPolicy); + } @@ -166,7 +173,7 @@ private T getAuthenticationPolicy(S } - private NonceCredentialsPolicyType getCredentialPolicy(AbstractAuthenticationPolicyType authPolicy, + private NonceCredentialsPolicyType getCredentialPolicy(String policyName, SecurityPolicyType securityPolicy) throws SchemaException { CredentialsPolicyType credentialsPolicy = securityPolicy.getCredentials(); if (credentialsPolicy == null) { @@ -175,12 +182,6 @@ private NonceCredentialsPolicyType getCredentialPolicy(AbstractAuthenticationPol List noncePolicies = credentialsPolicy.getNonce(); - String policyName = null; - if (authPolicy != null) { - policyName = authPolicy.getNonceName(); - - } - List availableNoncePolicies = new ArrayList<>(); for (NonceCredentialsPolicyType noncePolicy : noncePolicies) { if (noncePolicy.getName() == null && policyName == null) { @@ -255,5 +256,21 @@ public NonceCredentialsPolicyType getNoncePolicy() { public void setNoncePolicy(NonceCredentialsPolicyType noncePolicy) { this.noncePolicy = noncePolicy; } + + public String getInitialLifecycleState() { + return initialLifecycleState; + } + + public void setInitialLifecycleState(String initialLifecycleState) { + this.initialLifecycleState = initialLifecycleState; + } + + public String getRequiredLifecycleState() { + return requiredLifecycleState; + } + + public void setRequiredLifecycleState(String requiredLifecycleState) { + this.requiredLifecycleState = requiredLifecycleState; + } } diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd index b2def7d391b..42e6321addc 100644 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd @@ -10343,8 +10343,6 @@ - - @@ -10362,6 +10360,8 @@ + + @@ -10380,6 +10380,8 @@ + + @@ -10401,6 +10403,10 @@ + + + + diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/AuthenticationEvaluatorImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/AuthenticationEvaluatorImpl.java index 2d490be980e..8a0404df5f0 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/AuthenticationEvaluatorImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/AuthenticationEvaluatorImpl.java @@ -74,7 +74,7 @@ public UsernamePasswordAuthenticationToken authenticateUserPassword(ConnectionEn throw new BadCredentialsException("web.security.provider.password.encoding"); } - MidPointPrincipal principal = getAndCheckPrincipal(connEnv, enteredUsername); + MidPointPrincipal principal = getAndCheckPrincipal(connEnv, enteredUsername, true); UserType userType = principal.getUser(); CredentialsType credentials = userType.getCredentials(); @@ -136,7 +136,7 @@ public UsernamePasswordAuthenticationToken authenticateUserNonce(ConnectionEnvir throw new BadCredentialsException("web.security.provider.password.encoding"); } - MidPointPrincipal principal = getAndCheckPrincipal(connEnv, enteredUsername); + MidPointPrincipal principal = getAndCheckPrincipal(connEnv, enteredUsername, false); UserType userType = principal.getUser(); CredentialsType credentials = userType.getCredentials(); @@ -173,7 +173,7 @@ public String getAndCheckUserPassword(ConnectionEnvironment connEnv, String ente throws AuthenticationCredentialsNotFoundException, DisabledException, LockedException, CredentialsExpiredException, AuthenticationServiceException, AccessDeniedException, UsernameNotFoundException { - MidPointPrincipal principal = getAndCheckPrincipal(connEnv, enteredUsername); + MidPointPrincipal principal = getAndCheckPrincipal(connEnv, enteredUsername, true); UserType userType = principal.getUser(); CredentialsType credentials = userType.getCredentials(); @@ -213,7 +213,7 @@ public String getAndCheckUserPassword(ConnectionEnvironment connEnv, String ente public PreAuthenticatedAuthenticationToken authenticateUserPreAuthenticated(ConnectionEnvironment connEnv, String enteredUsername) { - MidPointPrincipal principal = getAndCheckPrincipal(connEnv, enteredUsername); + MidPointPrincipal principal = getAndCheckPrincipal(connEnv, enteredUsername, true); // Authorizations if (!hasAnyAuthorization(principal)) { @@ -229,7 +229,7 @@ public PreAuthenticatedAuthenticationToken authenticateUserPreAuthenticated(Conn } @NotNull - private MidPointPrincipal getAndCheckPrincipal(ConnectionEnvironment connEnv, String enteredUsername) { + private MidPointPrincipal getAndCheckPrincipal(ConnectionEnvironment connEnv, String enteredUsername, boolean checkActivation) { if (StringUtils.isBlank(enteredUsername)) { recordAuthenticationFailure(enteredUsername, connEnv, "no username"); @@ -249,7 +249,7 @@ private MidPointPrincipal getAndCheckPrincipal(ConnectionEnvironment connEnv, St throw new UsernameNotFoundException("web.security.provider.invalid"); } - if (!principal.isEnabled()) { + if (checkActivation && !principal.isEnabled()) { recordAuthenticationFailure(principal, connEnv, "user disabled"); throw new DisabledException("web.security.provider.disabled"); } From cee07dfa0fd2119b19ae1e88b916b8153f512f8c Mon Sep 17 00:00:00 2001 From: Katarina Valalikova Date: Wed, 2 Nov 2016 11:49:48 +0100 Subject: [PATCH 2/2] self registration improvements.. adding button for registration on login page, checking initial and required state.. --- .../api/component/captcha/CaptchaPanel.java | 4 + .../midpoint/web/page/login/PageLogin.html | 3 + .../midpoint/web/page/login/PageLogin.java | 42 ++++++++- .../web/page/login/PageSelfRegistration.java | 87 +++++++++++-------- .../localization/Midpoint.properties | 2 + 5 files changed, 99 insertions(+), 39 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/captcha/CaptchaPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/captcha/CaptchaPanel.java index 944caf49868..7ef7dcb3150 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/captcha/CaptchaPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/captcha/CaptchaPanel.java @@ -105,4 +105,8 @@ public String getCaptchaText() { return captchaText; } + public String getRandomText() { + return randomText; + } + } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageLogin.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageLogin.html index ab53bfae1a7..913b58c6e6d 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageLogin.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageLogin.html @@ -50,6 +50,9 @@ + + + diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageLogin.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageLogin.java index c9f13c003fc..ce4c16c5c7c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageLogin.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageLogin.java @@ -18,6 +18,7 @@ import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; @@ -28,6 +29,10 @@ import com.evolveum.midpoint.web.security.MidPointApplication; import com.evolveum.midpoint.web.security.SecurityUtils; import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsPolicyType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RegistrationsPolicyType; + +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.protocol.http.servlet.ServletWebRequest; import org.apache.wicket.request.cycle.RequestCycle; @@ -46,10 +51,12 @@ public class PageLogin extends PageBase { private static final Trace LOGGER = TraceManager.getTrace(PageLogin.class); private static final String ID_FORGET_PASSWORD = "forgetpassword"; + private static final String ID_SELF_REGISTRATION = "selfRegistration"; private static final String DOT_CLASS = PageLogin.class.getName() + "."; protected static final String OPERATION_LOAD_RESET_PASSWORD_POLICY = DOT_CLASS + "loadPasswordResetPolicy"; - + private static final String OPERATION_LOAD_REGISTRATION_POLICY = DOT_CLASS + "loadRegistrationPolicy"; + public PageLogin() { if (SecurityUtils.getPrincipalUser() != null) { MidPointApplication app = getMidpointApplication(); @@ -82,6 +89,39 @@ public boolean isVisible() { } }); add(link); + + AjaxLink registration = new AjaxLink(ID_SELF_REGISTRATION) { + + @Override + public void onClick(AjaxRequestTarget target) { + setResponsePage(PageSelfRegistration.class); + } + }; + registration.add(new VisibleEnableBehaviour() { + private static final long serialVersionUID = 1L; + + @Override + public boolean isVisible() { + OperationResult parentResult = new OperationResult(OPERATION_LOAD_REGISTRATION_POLICY); + + RegistrationsPolicyType registrationPolicies = null; + try { + Task task = createAnonymousTask(OPERATION_LOAD_REGISTRATION_POLICY); + registrationPolicies = getModelInteractionService().getRegistrationPolicy(null, task, parentResult); + } catch (ObjectNotFoundException | SchemaException e) { + LOGGER.warn("Cannot read credentials policy: " + e.getMessage(), e); + } + + boolean linkIsVisible = false; + if (registrationPolicies != null + && registrationPolicies.getSelfRegistration() != null) { + linkIsVisible = true; + } + + return linkIsVisible; + } + }); + add(registration); } @Override diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.java index 5f270334d71..e01ea4b7203 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/login/PageSelfRegistration.java @@ -28,6 +28,7 @@ import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; +import com.evolveum.midpoint.model.api.ModelExecuteOptions; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismObjectDefinition; import com.evolveum.midpoint.prism.delta.ObjectDelta; @@ -35,6 +36,7 @@ import com.evolveum.midpoint.prism.query.ObjectPaging; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; +import com.evolveum.midpoint.schema.SearchResultList; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; @@ -165,6 +167,7 @@ public void setObject(String object) { } }); firstName.getBaseFormComponent().add(new EmptyOnBlurAjaxFormUpdatingBehaviour()); + firstName.getBaseFormComponent().setRequired(true); mainForm.add(firstName); TextPanel lastName = new TextPanel<>(ID_LAST_NAME, @@ -179,11 +182,13 @@ public void setObject(String object) { }); lastName.getBaseFormComponent().add(new EmptyOnBlurAjaxFormUpdatingBehaviour()); + lastName.getBaseFormComponent().setRequired(true); mainForm.add(lastName); TextPanel email = new TextPanel<>(ID_EMAIL, new PropertyModel(userModel, UserType.F_EMAIL_ADDRESS.getLocalPart())); email.getBaseFormComponent().add(new EmptyOnBlurAjaxFormUpdatingBehaviour()); + email.getBaseFormComponent().setRequired(true); mainForm.add(email); AutoCompleteTextPanel organization = new AutoCompleteTextPanel(ID_ORGANIZATION, @@ -204,47 +209,13 @@ public Iterator getIterator(String input) { + CredentialsType.F_PASSWORD.getLocalPart() + "." + PasswordType.F_VALUE.getLocalPart())); password.getBaseFormComponent().add(new EmptyOnBlurAjaxFormUpdatingBehaviour()); + password.getBaseFormComponent().setRequired(true); mainForm.add(password); CaptchaPanel captcha = new CaptchaPanel(ID_CAPTCHA); captcha.setOutputMarkupId(true); -// final CaptchaImageResource captcha = new CaptchaImageResource(new AbstractReadOnlyModel() { -// -// private static final long serialVersionUID = 1L; -// -// @Override -// public String getObject() { -// randomString = generateCaptcha(); -// return randomString; -// } -// -// }); -// -// final Image captchaImage = new Image(ID_IMAGE, captcha); -// captchaImage.setOutputMarkupId(true); mainForm.add(captcha); -// AjaxLink changeCaptchaLink = new AjaxLink(ID_CHANGE_LINK) { -// private static final long serialVersionUID = 1L; -// -// @Override -// public void onClick(AjaxRequestTarget target) { -// updateCaptcha(captcha, target); -// } -// }; -// mainForm.add(changeCaptchaLink); - - - // userText.add(new EmptyOnBlurAjaxFormUpdatingBehaviour(){ - // - // @Override - // protected void onUpdate(AjaxRequestTarget target) { - // PageSelfRegistration.this.captchaString = (String) - // getDefaultModelObject(); - // } - // }); - - AjaxSubmitButton register = new AjaxSubmitButton(ID_SUBMIT_REGISTRATION) { private static final long serialVersionUID = 1L; @@ -280,9 +251,22 @@ public boolean isEnabled() { }); } + + private CaptchaPanel getCaptcha() { + return (CaptchaPanel) get(createComponentPath(ID_MAIN_FORM, ID_CAPTCHA)); + } private void submitRegistration(AjaxRequestTarget target) { + CaptchaPanel captcha = getCaptcha(); + if (captcha.getCaptchaText() != null && captcha.getRandomText() != null) { + if (!captcha.getCaptchaText().equals(captcha.getRandomText())) { + getSession().error(createStringResource("PageSelfRegistration.captcha.validation.failed").getString()); + captcha.invalidateCaptcha(); + throw new RestartResponseException(this); + } + } + OperationResult result = runPrivileged(new Producer() { @Override @@ -384,21 +368,48 @@ private void saveUser(Task task, OperationResult result) { ObjectDelta userDelta = ObjectDelta.createAddDelta(userType.asPrismObject()); userDelta.setPrismContext(getPrismContext()); - WebModelServiceUtils.save(userDelta, result, task, PageSelfRegistration.this); + WebModelServiceUtils.save(userDelta, ModelExecuteOptions.createOverwrite(), result, task, PageSelfRegistration.this); result.computeStatus(); } private UserType prepareUserToSave(Task task, OperationResult result) { - String organization = getOrganization(); + + SelfRegistrationDto selfRegistrationConfiguration = getSelfRegistrationConfiguration(); UserType userType = userModel.getObject(); + if (selfRegistrationConfiguration.getRequiredLifecycleState() != null) { + ObjectQuery query = QueryBuilder.queryFor(UserType.class, getPrismContext()) + .item(UserType.F_EMAIL_ADDRESS).eq(userType.getEmailAddress()) + .build(); + SearchResultList> users = null; + try { + users = getModelService().searchObjects(UserType.class, query, null, task, result); + } catch (SchemaException | ObjectNotFoundException | SecurityViolationException + | CommunicationException | ConfigurationException e) { + // TODO Auto-generated catch block + } + + if (users == null || users.size() == 0 || users.size() > 1) { + getSession().error(createStringResource("PageSelfRegistration.registration.failed.unsatisfied.registration.configuration").getString()); + throw new RestartResponseException(this); + + } + + PrismObject preregisteredUser = users.iterator().next(); + + userType.setOid(preregisteredUser.getOid()); + + } + + String organization = getOrganization(); + if (organization != null) { userType.getOrganization().add(new PolyStringType(organization)); } ProtectedStringType nonceCredentials = new ProtectedStringType(); - nonceCredentials.setClearValue(generateNonce(getSelfRegistrationConfiguration().getNoncePolicy(), task, result)); + nonceCredentials.setClearValue(generateNonce(selfRegistrationConfiguration.getNoncePolicy(), task, result)); NonceType nonceType = new NonceType(); nonceType.setValue(nonceCredentials); diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint.properties b/gui/admin-gui/src/main/resources/localization/Midpoint.properties index 312792aac2e..05ebdb3b6e4 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint.properties @@ -3417,3 +3417,5 @@ ObjectType.description=Description PageUserHistory.title='{0}' historical data {1} PageXmlDataReview.title=Historical data PageXmlDataReview.aceEditorPanelTitle='{0}' historical xml data {1} +PageLogin.selfRegistration=Sign up +PageSelfRegistration.registration.failed.unsatisfied.registration.configuration=Registration process not allowed. Please contact system administrator.