Skip to content

Commit

Permalink
Fixing user login with conditional roles (+test)
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Jul 31, 2014
1 parent 99cec3b commit 7b97a69
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 2 deletions.
Expand Up @@ -19,6 +19,7 @@
import java.util.Deque;

import com.evolveum.midpoint.model.impl.lens.LensContext;
import com.evolveum.midpoint.model.impl.lens.LensContextPlaceholder;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType;
Expand Down
Expand Up @@ -125,6 +125,10 @@ public LensContext(Class<F> focusClass, PrismContext prismContext, ProvisioningS
this.focusClass = focusClass;
}

protected LensContext(PrismContext prismContext) {
this.prismContext = prismContext;
}

public PrismContext getPrismContext() {
return prismContext;
}
Expand Down
@@ -0,0 +1,54 @@
/**
* Copyright (c) 2014 Evolveum
*
* Licensed 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 com.evolveum.midpoint.model.impl.lens;

import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.util.DebugUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;

/**
* This class does nothing. It just takes place when no real Lens Context is available.
* @see ModelExpressionThreadLocalHolder
*
* @author semancik
*
*/
public class LensContextPlaceholder<F extends ObjectType> extends LensContext<F> {

public LensContextPlaceholder(PrismContext prismContext) {
super(prismContext);
}

@Override
public String toString() {
return "LensContextPlaceholder()";
}

@Override
public String dump(boolean showTriples) {
return "LensContextPlaceholder()";
}

@Override
public String debugDump(int indent, boolean showTriples) {
StringBuilder sb = new StringBuilder();
DebugUtil.indentDebugDump(sb, indent);
sb.append("LensContextPlaceholder");
return sb.toString();
}


}
Expand Up @@ -25,6 +25,8 @@
import com.evolveum.midpoint.model.impl.UserComputer;
import com.evolveum.midpoint.model.impl.lens.AssignmentEvaluator;
import com.evolveum.midpoint.model.impl.lens.EvaluatedAssignment;
import com.evolveum.midpoint.model.impl.lens.LensContext;
import com.evolveum.midpoint.model.impl.lens.LensContextPlaceholder;
import com.evolveum.midpoint.model.impl.lens.LensUtil;
import com.evolveum.midpoint.prism.PrismContainerValue;
import com.evolveum.midpoint.prism.PrismContext;
Expand All @@ -41,6 +43,8 @@
import com.evolveum.midpoint.security.api.AuthorizationConstants;
import com.evolveum.midpoint.security.api.MidPointPrincipal;
import com.evolveum.midpoint.security.api.UserProfileService;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.task.api.TaskManager;
import com.evolveum.midpoint.util.exception.ExpressionEvaluationException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
Expand Down Expand Up @@ -84,6 +88,9 @@ public class UserProfileServiceImpl implements UserProfileService {

@Autowired(required = true)
private PrismContext prismContext;

@Autowired(required = true)
private TaskManager taskManager;

@Override
public MidPointPrincipal getPrincipal(String username) throws ObjectNotFoundException {
Expand Down Expand Up @@ -169,18 +176,25 @@ private void addAuthorizations(MidPointPrincipal principal) {
assignmentEvaluator.setMappingFactory(valueConstructionFactory);
assignmentEvaluator.setActivationComputer(activationComputer);
assignmentEvaluator.setNow(clock.currentTimeXMLGregorianCalendar());

// We do need only authorizations. Therefore we not need to evaluate constructions,
// so switching it off is faster. It also avoids nasty problems with resources being down,
// resource schema not available, etc.
assignmentEvaluator.setEvaluateConstructions(false);

// We do not have real lens context here. But the push methods in ModelExpressionThreadLocalHolder
// will need something to push on the stack. So give them context placeholder.
LensContext<UserType> lensContext = new LensContextPlaceholder<>(prismContext);
assignmentEvaluator.setLensContext(lensContext);

OperationResult result = new OperationResult(UserProfileServiceImpl.class.getName() + ".addAuthorizations");
Task task = taskManager.createTaskInstance(UserProfileServiceImpl.class.getName() + ".addAuthorizations");
OperationResult result = task.getResult();
for(AssignmentType assignmentType: userType.getAssignment()) {
try {
ItemDeltaItem<PrismContainerValue<AssignmentType>> assignmentIdi = new ItemDeltaItem<>();
assignmentIdi.setItemOld(LensUtil.createAssignmentSingleValueContainerClone(assignmentType));
assignmentIdi.recompute();
EvaluatedAssignment<UserType> assignment = assignmentEvaluator.evaluate(assignmentIdi, false, userType, userType.toString(), null, result);
EvaluatedAssignment<UserType> assignment = assignmentEvaluator.evaluate(assignmentIdi, false, userType, userType.toString(), task, result);
if (assignment.isValid()) {
authorizations.addAll(assignment.getAuthorizations());
}
Expand Down
Expand Up @@ -327,6 +327,8 @@ public class AbstractConfiguredModelIntegrationTest extends AbstractModelIntegra
protected static final String AUTZ_COMMAND_URL = QNameUtil.qNameToUri(AUTZ_COMMAND_QNAME);
protected static final QName AUTZ_PUNISH_QNAME = new QName(NS_TEST_AUTZ, "punish");
protected static final String AUTZ_PUNISH_URL = QNameUtil.qNameToUri(AUTZ_PUNISH_QNAME);
protected static final QName AUTZ_CAPSIZE_QNAME = new QName(NS_TEST_AUTZ, "capsize");
protected static final String AUTZ_CAPSIZE_URL = QNameUtil.qNameToUri(AUTZ_CAPSIZE_QNAME);

private static final Trace LOGGER = TraceManager.getTrace(AbstractConfiguredModelIntegrationTest.class);

Expand Down
Expand Up @@ -184,6 +184,9 @@ public class TestSecurity extends AbstractInitializedModelIntegrationTest {

protected static final File ROLE_BUSINESS_1_FILE = new File(TEST_DIR, "role-business-1.xml");
protected static final String ROLE_BUSINESS_1_OID = "00000000-0000-0000-0000-00000000aab1";

protected static final File ROLE_CONDITIONAL_FILE = new File(TEST_DIR, "role-conditional.xml");
protected static final String ROLE_CONDITIONAL_OID = "00000000-0000-0000-0000-00000000aac1";

private static final String LOG_PREFIX_FAIL = "SSSSS=X ";
private static final String LOG_PREFIX_ATTEMPT = "SSSSS=> ";
Expand Down Expand Up @@ -220,6 +223,8 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti
repoAddObjectFromFile(ROLE_APPLICATION_2_FILE, RoleType.class, initResult);
repoAddObjectFromFile(ROLE_BUSINESS_1_FILE, RoleType.class, initResult);

repoAddObjectFromFile(ROLE_CONDITIONAL_FILE, RoleType.class, initResult);

assignOrg(USER_GUYBRUSH_OID, ORG_SWASHBUCKLER_SECTION_OID, initTask, initResult);

PrismObject<UserType> userRum = createUser(USER_RUM_ROGERS_NAME, "Rum Rogers");
Expand Down Expand Up @@ -344,6 +349,80 @@ public void test052GetUserGuybrush() throws Exception {
assertNotAuthorized(principal, AUTZ_COMMAND_URL);
}

@Test
public void test060GuybrushConditionalRoleFalse() throws Exception {
final String TEST_NAME = "test060GuybrushConditionalRoleFalse";
TestUtil.displayTestTile(this, TEST_NAME);
assertLoggedInUser(USER_ADMINISTRATOR_USERNAME);

assignRole(USER_GUYBRUSH_OID, ROLE_CONDITIONAL_OID);

// WHEN
MidPointPrincipal principal = userProfileService.getPrincipal(USER_GUYBRUSH_USERNAME);

// THEN
display("Principal guybrush", principal);
assertEquals("wrong username", USER_GUYBRUSH_USERNAME, principal.getUsername());
assertEquals("wrong oid", USER_GUYBRUSH_OID, principal.getOid());
assertTrue("Unexpected authorizations", principal.getAuthorities().isEmpty());
display("User in principal guybrush", principal.getUser().asPrismObject());

principal.getUser().asPrismObject().checkConsistence(true, true);

assertNotAuthorized(principal, AUTZ_LOOT_URL);
assertNotAuthorized(principal, AUTZ_COMMAND_URL);
}

@Test
public void test061GuybrushConditionalRoleTrue() throws Exception {
final String TEST_NAME = "test061GuybrushConditionalRoleTrue";
TestUtil.displayTestTile(this, TEST_NAME);
assertLoggedInUser(USER_ADMINISTRATOR_USERNAME);

Task task = taskManager.createTaskInstance(TestRbac.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
modifyUserReplace(USER_GUYBRUSH_OID, UserType.F_EMPLOYEE_TYPE, task, result, "looser");

// WHEN
MidPointPrincipal principal = userProfileService.getPrincipal(USER_GUYBRUSH_USERNAME);

// THEN
display("Principal guybrush", principal);
assertEquals("wrong username", USER_GUYBRUSH_USERNAME, principal.getUsername());
assertEquals("wrong oid", USER_GUYBRUSH_OID, principal.getOid());
assertTrue("Unexpected authorizations", principal.getAuthorities().isEmpty());
display("User in principal guybrush", principal.getUser().asPrismObject());

principal.getUser().asPrismObject().checkConsistence(true, true);

assertNotAuthorized(principal, AUTZ_LOOT_URL);
assertNotAuthorized(principal, AUTZ_COMMAND_URL);
assertNotAuthorized(principal, AUTZ_CAPSIZE_URL);
}

@Test
public void test062GuybrushConditionalRoleUnassign() throws Exception {
final String TEST_NAME = "test062GuybrushConditionalRoleUnassign";
TestUtil.displayTestTile(this, TEST_NAME);
assertLoggedInUser(USER_ADMINISTRATOR_USERNAME);

unassignRole(USER_GUYBRUSH_OID, ROLE_CONDITIONAL_OID);

// WHEN
MidPointPrincipal principal = userProfileService.getPrincipal(USER_GUYBRUSH_USERNAME);

// THEN
display("Principal guybrush", principal);
assertEquals("wrong username", USER_GUYBRUSH_USERNAME, principal.getUsername());
assertEquals("wrong oid", USER_GUYBRUSH_OID, principal.getOid());
assertTrue("Unexpected authorizations", principal.getAuthorities().isEmpty());
display("User in principal guybrush", principal.getUser().asPrismObject());

principal.getUser().asPrismObject().checkConsistence(true, true);

assertNotAuthorized(principal, AUTZ_LOOT_URL);
assertNotAuthorized(principal, AUTZ_COMMAND_URL);
}

@Test
public void test100JackRolePirate() throws Exception {
Expand Down
@@ -0,0 +1,35 @@
<!--
~ Copyright (c) 2010-2014 Evolveum
~
~ Licensed 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.
-->
<role oid="00000000-0000-0000-0000-00000000aac1"
xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004">
<name>Conditional</name>
<authorization>
<action>http://midpoint.evolveum.com/xml/ns/test/authorization#superspecial</action>
</authorization>
<condition>
<source>
<path>$user/employeeType</path>
</source>
<expression>
<script>
<code>employeeType == 'special'</code>
</script>
</expression>
</condition>
</role>

0 comments on commit 7b97a69

Please sign in to comment.