Skip to content

Commit

Permalink
Merge branch 'feature/forgot-username' of github.com:Evolveum/midpoin…
Browse files Browse the repository at this point in the history
…t into feature/forgot-username

* 'feature/forgot-username' of github.com:Evolveum/midpoint:
  duplicate url usage fix
  added login recovery result page; some refactoring in auth channels
  • Loading branch information
katkav committed Aug 4, 2023
2 parents 46378d0 + 64f44b1 commit d680893
Show file tree
Hide file tree
Showing 14 changed files with 170 additions and 62 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2010-2023 Evolveum
~
~ This work is dual-licensed under the Apache License 2.0
~ and European Union Public License. See LICENSE file for details.
-->

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:wicket="http://wicket.apache.org">
<body>
<wicket:extend>
<div wicket:id="userLoginName" />
</wicket:extend>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2023 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/
package com.evolveum.midpoint.gui.impl.page.login;

import com.evolveum.midpoint.authentication.api.authorization.AuthorizationAction;
import com.evolveum.midpoint.authentication.api.authorization.PageDescriptor;
import com.evolveum.midpoint.authentication.api.authorization.Url;

import com.evolveum.midpoint.authentication.api.config.MidpointAuthentication;
import com.evolveum.midpoint.security.api.AuthorizationConstants;

import com.evolveum.midpoint.web.component.util.VisibleBehaviour;

import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

import java.io.Serial;

@PageDescriptor(
urls = {
@Url(mountUrl = "/loginRecovery", matchUrlForSecurity = "/loginRecovery")
},
action = {
@AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_LOGIN_RECOVERY_FINISH_URL,
label = "PageLoginRecoveryFinish.auth.label",
description = "PageLoginRecoveryFinish.auth.description") })
public class PageLoginRecoveryFinish extends AbstractPageLogin {

@Serial private static final long serialVersionUID = 1L;

private static final String ID_USER_LOGIN_PANEL = "userLoginName";

@Override
protected boolean isBackButtonVisible() {
return true;
}

@Override
protected void initCustomLayout() {
Label loginNamePanel = new Label(ID_USER_LOGIN_PANEL, Model.of(getAuthorizedUserName()));
loginNamePanel.setOutputMarkupId(true);
loginNamePanel.add(new VisibleBehaviour(this::isUserAuthorized));
add(loginNamePanel);
}

@Override
protected IModel<String> getLoginPanelTitleModel() {
return createStringResource(getTitleKey());
}

private String getTitleKey() {
return isUserAuthorized() ? "PageLoginRecoveryFinish.title.success" : "PageLoginRecoveryFinish.title.fail";
}

@Override
protected IModel<String> getLoginPanelDescriptionModel() {
return createStringResource(getTitleDescriptionKey());
}

private String getTitleDescriptionKey() {
return isUserAuthorized() ? "PageLoginRecoveryFinish.title.success" : "PageLoginRecoveryFinish.title.fail";
}

private boolean isUserAuthorized() {
return getAuthorizedUserName() != null;
}

private String getAuthorizedUserName() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication instanceof MidpointAuthentication) {
return ((MidpointAuthentication) authentication).getUsername();
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ protected void initModuleLayout(MidpointForm form) {

@Override
protected IModel<String> getLoginPanelTitleModel() {
return createStringResource("PageArchetypeSelection.title");
return createStringResource("PageArchetypeSelection.form.title");
}

@Override
protected IModel<String> getLoginPanelDescriptionModel() {
return createStringResource("PageArchetypeSelection.title.description");
return createStringResource("PageArchetypeSelection.form.description");
}

private void initArchetypeSelectionPanel(MidpointForm<?> form) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

@PageDescriptor(urls = {
@Url(mountUrl = "/correlation", matchUrlForSecurity = "/correlation")},
permitAll = true, loginPage = true, authModule = AuthenticationModuleNameConstants.CORRELATION) //todo remove permit all later : [KV] why?
permitAll = true, loginPage = true, authModule = AuthenticationModuleNameConstants.CORRELATION)
public class PageCorrelation extends PageAbstractAttributeVerification<CorrelationModuleAuthentication> {

@Serial private static final long serialVersionUID = 1L;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

@PageDescriptor(
urls = {
@Url(mountUrl = "/loginRecovery", matchUrlForSecurity = "/loginRecovery")
@Url(mountUrl = "/loginRecovery1", matchUrlForSecurity = "/loginRecovery1")
},
action = {
@AuthorizationAction(actionUri = PageSelf.AUTH_SELF_ALL_URI,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@
<xsd:element name="correlator" type="tns:CorrelationModuleConfigurationType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
"name" attribute of the correlator as set in object template.
Correlator configuration.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
Expand All @@ -468,7 +468,13 @@
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="correlatorIdentifier" type="xsd:string"/>
<xsd:element name="correlatorIdentifier" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
"name" attribute of the correlator as set in object template.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="order" type="xsd:int"/>
<!-- TODO thresholds-->
</xsd:sequence>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public String getPathAfterSuccessfulAuthentication() {
return "/actuator";
}

public Collection<Authorization> resolveAuthorities(Collection<Authorization> authorities) {
@Override
public Collection<Authorization> cleanupAuthorities(Collection<Authorization> authorities) {
ArrayList<Authorization> newAuthorities = new ArrayList<>();
for (Authorization authority : authorities) {
Authorization clone = authority.clone();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
*/
package com.evolveum.midpoint.authentication.impl.channel;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import com.evolveum.midpoint.authentication.api.AuthenticationChannel;
import com.evolveum.midpoint.security.api.Authorization;
Expand All @@ -15,6 +17,8 @@

import com.evolveum.midpoint.authentication.api.util.AuthUtil;

import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationType;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;

Expand Down Expand Up @@ -87,10 +91,39 @@ public boolean isDefault() {
return Boolean.TRUE.equals(this.channel.isDefault());
}

/**
* This method cares about removing some undesirable authorities and adding some additional authorities
* (e.g. an authority for the password reset page should be added to the list in case of successful user authentication)
*
* @param authorities
* @return
*/
public Collection<Authorization> resolveAuthorities(Collection<Authorization> authorities) {
var cleanedUpAuthorities = cleanupAuthorities(authorities);
var newAuthorities = new ArrayList<>(cleanedUpAuthorities);
addAdditionalAuthorities(authorities);
return Collections.unmodifiableList(newAuthorities);
}

protected Collection<Authorization> cleanupAuthorities(Collection<Authorization> authorities) {
return authorities;
}

private void addAdditionalAuthorities(Collection<Authorization> authorities) {
getAdditionalAuthoritiesList()
.forEach(a -> authorities.add(createAuthorization(a)));
}

protected Collection<String> getAdditionalAuthoritiesList() {
return Collections.emptyList();
}

private Authorization createAuthorization(String authUrl) {
var authorizationType = new AuthorizationType();
authorizationType.getAction().add(authUrl);
return new Authorization(authorizationType);
}

@Override
public void postSuccessAuthenticationProcessing() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,10 @@ public boolean isPostAuthenticationEnabled() {
}

@Override
public Collection<Authorization> resolveAuthorities(Collection<Authorization> authorities) {
protected Collection<String> getAdditionalAuthoritiesList() {
if (isPostAuthenticationEnabled()) {
AuthorizationType authorizationBean = new AuthorizationType();
authorizationBean.getAction().add(AuthorizationConstants.AUTZ_UI_SELF_POST_AUTHENTICATION_URL);
Authorization postAuthenticationAuthz = new Authorization(authorizationBean);
return Collections.singletonList(postAuthenticationAuthz);
return Collections.singletonList(AuthorizationConstants.AUTZ_UI_SELF_POST_AUTHENTICATION_URL);
}
return super.resolveAuthorities(authorities);
return super.getAdditionalAuthoritiesList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@
package com.evolveum.midpoint.authentication.impl.channel;

import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.security.api.Authorization;
import com.evolveum.midpoint.security.api.AuthorizationConstants;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthenticationSequenceChannelType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationType;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

/**
* @author skublik
Expand Down Expand Up @@ -53,13 +51,7 @@ public String getPathDuringProccessing() {
}

@Override
public Collection<Authorization> resolveAuthorities(Collection<Authorization> authorities) {
ArrayList<Authorization> newAuthorities = new ArrayList<>();
AuthorizationType authorizationBean = new AuthorizationType();
authorizationBean.getAction().add(AuthorizationConstants.AUTZ_UI_INVITATION_URL);
Authorization selfServiceCredentialsAuthz = new Authorization(authorizationBean);
newAuthorities.add(selfServiceCredentialsAuthz);
authorities.addAll(newAuthorities);
return authorities;
protected Collection<String> getAdditionalAuthoritiesList() {
return Collections.singletonList(AuthorizationConstants.AUTZ_UI_INVITATION_URL);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,9 @@
package com.evolveum.midpoint.authentication.impl.channel;

import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.security.api.Authorization;
import com.evolveum.midpoint.security.api.AuthorizationConstants;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthenticationSequenceChannelType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationType;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

Expand All @@ -32,17 +27,9 @@ public String getPathAfterSuccessfulAuthentication() {
return "/loginRecovery";
}

// public Collection<Authorization> resolveAuthorities(@NotNull Collection<Authorization> authorities) {
// ArrayList<Authorization> newAuthorities = new ArrayList<>();
// for (Authorization authzI : authorities) {
// authzI.getAction().removeIf(action -> action.contains(AuthorizationConstants.NS_AUTHORIZATION_UI));
// }
// AuthorizationType authorizationBean = new AuthorizationType();
// authorizationBean.getAction().add(AuthorizationConstants.AUTZ_UI_USERNAME_RECOVERY_URL);
// Authorization selfServiceCredentialsAuthz = new Authorization(authorizationBean);
// newAuthorities.add(selfServiceCredentialsAuthz);
// newAuthorities.addAll(authorities);
// return Collections.unmodifiableList(newAuthorities);
// }
@Override
protected Collection<String> getAdditionalAuthoritiesList() {
return Collections.singletonList(AuthorizationConstants.AUTZ_UI_LOGIN_RECOVERY_FINISH_URL);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ public String getPathAfterSuccessfulAuthentication() {
return "/resetPassword";
}

public Collection<Authorization> resolveAuthorities(@NotNull Collection<Authorization> authorities) {
ArrayList<Authorization> newAuthorities = new ArrayList<>();
@Override
public Collection<Authorization> cleanupAuthorities(@NotNull Collection<Authorization> authorities) {
for (Authorization authzI : authorities) {
authzI.getAction().removeIf(action -> action.contains(AuthorizationConstants.NS_AUTHORIZATION_UI));
}
AuthorizationType authorizationBean = new AuthorizationType();
authorizationBean.getAction().add(AuthorizationConstants.AUTZ_UI_RESET_PASSWORD_URL);
Authorization selfServiceCredentialsAuthz = new Authorization(authorizationBean);
newAuthorities.add(selfServiceCredentialsAuthz);
newAuthorities.addAll(authorities);
return Collections.unmodifiableList(newAuthorities);
return authorities;
}

@Override
protected Collection<String> getAdditionalAuthoritiesList() {
return Collections.singletonList(AuthorizationConstants.AUTZ_UI_RESET_PASSWORD_URL);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@
*/
package com.evolveum.midpoint.authentication.impl.channel;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.security.api.Authorization;
import com.evolveum.midpoint.security.api.AuthorizationConstants;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthenticationSequenceChannelType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationType;

/**
* @author skublik
Expand Down Expand Up @@ -48,12 +46,7 @@ public boolean isSupportActivationByChannel() {
}

@Override
public Collection<Authorization> resolveAuthorities(Collection<Authorization> authorities) {
ArrayList<Authorization> newAuthorities = new ArrayList<>(authorities);
AuthorizationType authorizationBean = new AuthorizationType();
authorizationBean.getAction().add(AuthorizationConstants.AUTZ_UI_SELF_REGISTRATION_FINISH_URL);
Authorization selfServiceCredentialsAuthz = new Authorization(authorizationBean);
newAuthorities.add(selfServiceCredentialsAuthz);
return newAuthorities;
protected Collection<String> getAdditionalAuthoritiesList() {
return Collections.singletonList(AuthorizationConstants.AUTZ_UI_SELF_REGISTRATION_FINISH_URL);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@
*/
package com.evolveum.midpoint.security.api;

import java.util.Arrays;
import java.util.Collection;
import javax.xml.namespace.QName;

import com.evolveum.axiom.concepts.Path;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.path.PathSet;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
Expand Down Expand Up @@ -424,6 +421,8 @@ public class AuthorizationConstants {

public static final QName AUTZ_UI_SELF_REGISTRATION_FINISH_QNAME = new QName(NS_AUTHORIZATION_UI, "selfRegistFinish");
public static final String AUTZ_UI_SELF_REGISTRATION_FINISH_URL = NS_AUTHORIZATION_UI + "#selfRegistFinish";
public static final QName AUTZ_UI_LOGIN_RECOVERY_FINISH_QNAME = new QName(NS_AUTHORIZATION_UI, "loginRecovery");
public static final String AUTZ_UI_LOGIN_RECOVERY_FINISH_URL = NS_AUTHORIZATION_UI + "#loginRecovery";
public static final String AUTZ_UI_INVITATION_URL = NS_AUTHORIZATION_UI + "#invitation";

public static final QName AUTZ_UI_PREVIEW_CHANGES_QNAME = new QName(NS_AUTHORIZATION_UI, "previewChanges");
Expand Down

0 comments on commit d680893

Please sign in to comment.