[CST-6151] can change password feature must return false if current user is logged in as another.

This commit is contained in:
eskander
2022-07-04 15:27:22 +02:00
parent f32d1ad0b0
commit 957f13f834
4 changed files with 98 additions and 1 deletions

View File

@@ -119,6 +119,8 @@ public class Context implements AutoCloseable {
*/
private Mode mode;
private boolean switchedContextUser = false;
/**
* Cache that is only used the context is in READ_ONLY mode
*/
@@ -706,6 +708,7 @@ public class Context implements AutoCloseable {
* restored
*/
public void switchContextUser(EPerson newUser) {
boolean isAdmin = false;
if (currentUserPreviousState != null) {
throw new IllegalStateException(
"A previous user is already set, you can only switch back and foreward one time");
@@ -715,6 +718,7 @@ public class Context implements AutoCloseable {
specialGroupsPreviousState = specialGroups;
specialGroups = new HashSet<>();
currentUser = newUser;
switchedContextUser = true;
}
/**
@@ -730,6 +734,7 @@ public class Context implements AutoCloseable {
specialGroups = specialGroupsPreviousState;
specialGroupsPreviousState = null;
currentUserPreviousState = null;
switchedContextUser = false;
}
/**
@@ -944,4 +949,8 @@ public class Context implements AutoCloseable {
public void setAuthenticationMethod(final String authenticationMethod) {
this.authenticationMethod = authenticationMethod;
}
public boolean isSwitchedContextUser() {
return switchedContextUser;
}
}

View File

@@ -29,7 +29,8 @@ public class CanChangePasswordFeature implements AuthorizationFeature {
@Override
public boolean isAuthorized(Context context, BaseObjectRest object) throws SQLException {
if (context.getCurrentUser() != null && StringUtils.equals(context.getAuthenticationMethod(), "password")) {
if (context.getCurrentUser() != null && !context.isSwitchedContextUser()
&& StringUtils.equals(context.getAuthenticationMethod(), "password")) {
return true;
}
return false;

View File

@@ -132,6 +132,7 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio
private Authorization authorization;
private EPersonRest ePersonRest;
private EPersonRest adminRest;
private final String feature = CanChangePasswordFeature.NAME;
@@ -151,6 +152,10 @@ public class AuthenticationRestControllerIT extends AbstractControllerIntegratio
public void testStatusAuthenticatedAsAdmin() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
AuthorizationFeature canChangePasswordFeature = authorizationFeatureService.find(CanChangePasswordFeature.NAME);
adminRest = ePersonConverter.convert(admin, DefaultProjection.DEFAULT);
authorization = new Authorization(admin, canChangePasswordFeature, adminRest);
getClient(token).perform(get("/api/authn/status").param("projection", "full"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", AuthenticationStatusMatcher.matchFullEmbeds()))

View File

@@ -0,0 +1,82 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.dspace.app.rest.authorization.Authorization;
import org.dspace.app.rest.authorization.AuthorizationFeature;
import org.dspace.app.rest.authorization.AuthorizationFeatureService;
import org.dspace.app.rest.authorization.impl.CanChangePasswordFeature;
import org.dspace.app.rest.converter.EPersonConverter;
import org.dspace.app.rest.matcher.AuthorizationMatcher;
import org.dspace.app.rest.model.EPersonRest;
import org.dspace.app.rest.projection.DefaultProjection;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Test for the Can Change Password Feature.
*
* @author Mohamed Eskander (mohamed.eskander at 4science.it)
*
*/
public class CanChangePasswordFeatureIT extends AbstractControllerIntegrationTest {
@Autowired
private AuthorizationFeatureService authorizationFeatureService;
@Autowired
private EPersonConverter ePersonConverter;
private AuthorizationFeature canChangePasswordFeature;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
canChangePasswordFeature = authorizationFeatureService.find(CanChangePasswordFeature.NAME);
}
@Test
public void testCanChangePasswordFeatureWithAdmin() throws Exception {
EPersonRest adminRest = ePersonConverter.convert(admin, DefaultProjection.DEFAULT);
Authorization authorization = new Authorization(admin, canChangePasswordFeature, adminRest);
String tokenAdmin = getAuthToken(admin.getEmail(), password);
getClient(tokenAdmin).perform(get("/api/authz/authorizations/" + authorization.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.is(
AuthorizationMatcher.matchAuthorization(authorization))));
}
@Test
public void testCanChangePasswordFeatureWithNotAdmin() throws Exception {
EPersonRest ePersonRest = ePersonConverter.convert(eperson, DefaultProjection.DEFAULT);
Authorization authorization = new Authorization(eperson, canChangePasswordFeature, ePersonRest);
String tokenEperson = getAuthToken(eperson.getEmail(), password);
getClient(tokenEperson).perform(get("/api/authz/authorizations/" + authorization.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.is(
AuthorizationMatcher.matchAuthorization(authorization))));
}
@Test
public void testCanChangePasswordFeatureIfAdminImpersonatingAnotherUser() throws Exception {
EPersonRest ePersonRest = ePersonConverter.convert(eperson, DefaultProjection.DEFAULT);
Authorization authorization = new Authorization(eperson, canChangePasswordFeature, ePersonRest);
String tokenAdmin = getAuthToken(admin.getEmail(), password);
getClient(tokenAdmin).perform(get("/api/authz/authorizations/" + authorization.getID()))
.andExpect(status().isNotFound());
}
}