Skip to content

Commit

Permalink
Merge branch 'master' into containers
Browse files Browse the repository at this point in the history
  • Loading branch information
1azyman committed Mar 14, 2014
2 parents 7877d77 + 070ad62 commit 9b14f94
Show file tree
Hide file tree
Showing 13 changed files with 255 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,13 @@ public String debugDump() {
@Override
public String debugDump(int indent) {
StringBuilder sb = new StringBuilder();
DebugUtil.debugDumpLabel(sb, "Authorization(", indent);
sb.append(authorizationType);
DebugUtil.debugDumpLabel(sb, "Authorization", indent);
if (authorizationType == null) {
sb.append(" null");
} else {
sb.append("\n");
authorizationType.asPrismContainerValue().debugDump(indent+1);
}
return sb.toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class AuthorizationConstants {
public static final String NS_AUTHORIZATION = NS_SECURITY_PREFIX + "authorization-2";
public static final String NS_AUTHORIZATION_UI = NS_SECURITY_PREFIX + "authorization-ui-2";
public static final String NS_AUTHORIZATION_WS = NS_SECURITY_PREFIX + "authorization-ws-2";
public static final String NS_AUTHORIZATION_MODEL = NS_SECURITY_PREFIX + "authorization-model-2";

public static final QName AUTZ_ALL_QNAME = new QName(NS_AUTHORIZATION, "all");
public static final String AUTZ_ALL_URL = QNameUtil.qNameToUri(AUTZ_ALL_QNAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,8 @@ public abstract class SchemaConstants {
public static final String NS_MODEL_CHANNEL = NS_MODEL + "/channels-2";
public static final QName CHANNEL_WEB_SERVICE_QNAME = new QName(NS_MODEL_CHANNEL, "webService");
public static final String CHANNEL_WEB_SERVICE_URI = QNameUtil.qNameToUri(CHANNEL_WEB_SERVICE_QNAME);

public static final String NS_GUI = NS_MIDPOINT_PUBLIC + "/gui";
public static final String NS_GUI_CHANNEL = NS_GUI + "/channels-2";
public static final QName CHANNEL_GUI_INIT_QNAME = new QName(NS_GUI_CHANNEL, "init");
public static final String CHANNEL_GUI_INIT_URI = QNameUtil.qNameToUri(CHANNEL_GUI_INIT_QNAME);
public static final QName CHANNEL_GUI_USER_QNAME = new QName(NS_GUI_CHANNEL, "user");
public static final String CHANNEL_GUI_USER_URI = QNameUtil.qNameToUri(CHANNEL_GUI_USER_QNAME);

public static final String NS_MODEL_SERVICE = NS_MODEL + "/service-2";

public static final String NS_MODEL_EXTENSION = NS_MODEL + "/extension-2";
public static final QName MODEL_EXTENSION_FRESHENESS_INTERVAL_PROPERTY_NAME = new QName(NS_MODEL_EXTENSION, "freshnessInterval");
Expand All @@ -162,6 +157,13 @@ public abstract class SchemaConstants {

public static final QName MODEL_EXTENSION_OBJECT_QUERY = new QName(NS_MODEL_EXTENSION, "objectQuery");

public static final String NS_GUI = NS_MIDPOINT_PUBLIC + "/gui";
public static final String NS_GUI_CHANNEL = NS_GUI + "/channels-2";
public static final QName CHANNEL_GUI_INIT_QNAME = new QName(NS_GUI_CHANNEL, "init");
public static final String CHANNEL_GUI_INIT_URI = QNameUtil.qNameToUri(CHANNEL_GUI_INIT_QNAME);
public static final QName CHANNEL_GUI_USER_QNAME = new QName(NS_GUI_CHANNEL, "user");
public static final String CHANNEL_GUI_USER_URI = QNameUtil.qNameToUri(CHANNEL_GUI_USER_QNAME);

public static final String INTENT_DEFAULT = "default";

// This constant should not be here. It is used by schema processor to
Expand Down
79 changes: 75 additions & 4 deletions infra/schema/src/main/resources/xml/ns/public/common/common-2a.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -6161,18 +6161,35 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- TODO <xsd:element name="object" type="tns:ObjectSpecificationType" minOccurs="0" maxOccurs="unbounded">
<xsd:element name="object" type="tns:ObjectSpecificationType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Object part from the (subject,action,object) authorization triple.
</xsd:documentation>
</xsd:annotation>
</xsd:element> -->
<!-- TODO: more elements will be added in the future: item, target, condition, parameters -->
</xsd:element>
<xsd:element name="item" type="t:XPathType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Specification of items that form a scope of this authorization. This autorization will
only affect the items specified in this element. If no items are specified then the
authorization applies to all items in the objects.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="target" type="tns:ObjectSpecificationType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Target of the operation. E.g. an role that is being assigned. It can be considered an operation
parameter. If no target is specified then the authorization applies to all possible targets.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- TODO: more elements will be added in the future: condition, parameters -->
</xsd:sequence>
<xsd:attribute name="id" type="xsd:long" use="optional"/>
</xsd:complexType>

<xsd:simpleType name="AuthorizationDecisionType">
<xsd:annotation>
<xsd:appinfo>
Expand All @@ -6197,6 +6214,60 @@
</xsd:restriction>
</xsd:simpleType>

<xsd:complexType name="ObjectSpecificationType">
<xsd:annotation>
<xsd:documentation>
Selects some objects from all the objects in midPoint.
</xsd:documentation>
<xsd:appinfo>
<a:container/>
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element ref="tns:description" minOccurs="0"/>
<xsd:element name="type" minOccurs="1" type="xsd:QName">
<xsd:annotation>
<xsd:documentation>
Type of the object to select.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="filter" type="q:QueryType" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
Action part from the (subject,action,object) authorization triple. It is an URL to allow extension.
Multiple actions may be specified. In that case the authorization applies to all of them.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="special" type="tns:SpecialObjectSpecificationType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Defines special object by relative description, such as "self".
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:long" use="optional"/>
</xsd:complexType>

<xsd:simpleType name="SpecialObjectSpecificationType">
<xsd:annotation>
<xsd:appinfo>
<jaxb:typesafeEnumClass/>
</xsd:appinfo>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="self">
<xsd:annotation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="SELF"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
</xsd:restriction>
</xsd:simpleType>

<xsd:complexType name="RoleType">
<xsd:annotation>
<xsd:documentation>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import javax.xml.namespace.QName;

import com.evolveum.midpoint.common.security.AuthorizationConstants;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
Expand All @@ -32,8 +33,10 @@
import com.evolveum.midpoint.schema.ObjectOperationOption;
import com.evolveum.midpoint.schema.ResultHandler;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.util.exception.CommunicationException;
import com.evolveum.midpoint.util.exception.ConfigurationException;
import com.evolveum.midpoint.util.exception.ConsistencyViolationException;
Expand Down Expand Up @@ -97,6 +100,17 @@ public interface ModelService {
String POST_INIT = CLASS_NAME_WITH_DOT + "postInit";
String DISCOVER_CONNECTORS = CLASS_NAME_WITH_DOT + "discoverConnectors";

String AUTZ_NAMESPACE = AuthorizationConstants.NS_AUTHORIZATION_MODEL;
String AUTZ_READ_URL = QNameUtil.qNameToUri(new QName(AUTZ_NAMESPACE, "read"));
String AUTZ_ADD_URL = QNameUtil.qNameToUri(new QName(AUTZ_NAMESPACE, "add"));
String AUTZ_MODIFY_URL = QNameUtil.qNameToUri(new QName(AUTZ_NAMESPACE, "modify"));
String AUTZ_DELETE_URL = QNameUtil.qNameToUri(new QName(AUTZ_NAMESPACE, "delete"));
String AUTZ_RECOMPUTE_URL = QNameUtil.qNameToUri(new QName(AUTZ_NAMESPACE, "recompute"));
String AUTZ_TEST_URL = QNameUtil.qNameToUri(new QName(AUTZ_NAMESPACE, "test"));
String AUTZ_IMPORT_OBJECTS_URL = QNameUtil.qNameToUri(new QName(AUTZ_NAMESPACE, "importObjects"));
String AUTZ_IMPORT_FROM_RESOURCE_URL = QNameUtil.qNameToUri(new QName(AUTZ_NAMESPACE, "importFromResource"));
String AUTZ_DISCOVER_CONNECTORS_URL = QNameUtil.qNameToUri(new QName(AUTZ_NAMESPACE, "discoverConnectors"));

/**
* <p>
* Returns object for provided OID. It retrieves the object from an appropriate source
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,22 @@
import com.evolveum.midpoint.model.api.TaskService;
import com.evolveum.midpoint.model.api.WorkflowService;
import com.evolveum.midpoint.model.api.hooks.ReadHook;
import com.evolveum.midpoint.model.security.AuthorizationEnforcer;
import com.evolveum.midpoint.model.util.Utils;
import com.evolveum.midpoint.wf.api.WorkflowManager;
import com.evolveum.midpoint.xml.ns._public.common.common_2a.TaskType;
import com.evolveum.midpoint.xml.ns._public.common.common_2a.WfProcessInstanceType;
import com.evolveum.midpoint.xml.ns._public.common.common_2a.WorkItemType;
import com.evolveum.midpoint.xml.ns._public.model.model_context_2.LensContextType;

import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.lang.Validate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import com.evolveum.midpoint.audit.api.AuditEventRecord;
Expand All @@ -46,6 +52,7 @@
import com.evolveum.midpoint.common.InternalsConfig;
import com.evolveum.midpoint.common.crypto.CryptoUtil;
import com.evolveum.midpoint.common.crypto.Protector;
import com.evolveum.midpoint.common.security.Authorization;
import com.evolveum.midpoint.model.ModelObjectResolver;
import com.evolveum.midpoint.model.api.ModelExecuteOptions;
import com.evolveum.midpoint.model.api.ModelInteractionService;
Expand Down Expand Up @@ -221,15 +228,15 @@ public <T extends ObjectType> PrismObject<T> getObject(Class<T> clazz, String oi
result.addParam("class", clazz);

GetOperationOptions rootOptions = SelectorOptions.findRootOptions(options);

try {

ObjectReferenceType ref = new ObjectReferenceType();
ref.setOid(oid);
ref.setType(ObjectTypes.getObjectType(clazz).getTypeQName());
Utils.clearRequestee(task);
object = objectResolver.getObject(clazz, oid, options, task, result).asPrismObject();

resolve(object, options, task, result);
} catch (SchemaException e) {
ModelUtils.recordFatalError(result, e);
Expand All @@ -254,10 +261,12 @@ public <T extends ObjectType> PrismObject<T> getObject(Class<T> clazz, String oi
}

result.cleanupResult();
validateObject(object, rootOptions, result);

AuthorizationEnforcer.authorize(ModelService.AUTZ_READ_URL, object, null, task, result);

validateObject(object, rootOptions, result);
return object;
}


protected void resolve(PrismObject<?> object, Collection<SelectorOptions<GetOperationOptions>> options,
Task task, OperationResult result) throws SchemaException, ObjectNotFoundException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/**
* 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.security;

import java.util.Collection;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;

import com.evolveum.midpoint.common.security.Authorization;
import com.evolveum.midpoint.common.security.AuthorizationConstants;
import com.evolveum.midpoint.common.security.MidPointPrincipal;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.exception.SecurityViolationException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_2a.ObjectType;

/**
* @author Radovan Semancik
*
*/
public class AuthorizationEnforcer {

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

public static <O extends ObjectType, T extends ObjectType> void authorize(String operationUrl,
PrismObject<O> object, PrismObject<T> target, Task task, OperationResult parentResult) throws SecurityViolationException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
throw new SecurityViolationException("No authentication");
}
Object principal = authentication.getPrincipal();
boolean allow = false;
if (principal != null) {
if (principal instanceof MidPointPrincipal) {
MidPointPrincipal midPointPrincipal = (MidPointPrincipal)principal;
Collection<Authorization> authorities = midPointPrincipal.getAuthorities();
if (authorities != null) {
for (GrantedAuthority authority: authorities) {
if (authority instanceof Authorization) {
Authorization autz = (Authorization)authority;
if (!autz.getAction().contains(operationUrl) && !autz.getAction().contains(AuthorizationConstants.AUTZ_ALL_URL)) {
LOGGER.trace("Evaluating authorization {}: not applicable for operation {}", autz, operationUrl);
continue;
}
LOGGER.trace("Evaluating authorization {}: ALLOW operation {}", autz, operationUrl);
allow = true;
break;
} else {
LOGGER.warn("Unknown authority type {} in user {}", authority.getClass(), midPointPrincipal.getUsername());
}
}
}
} else {
LOGGER.warn("Unknown principal type {}", principal.getClass());
}
} else {
LOGGER.warn("Null principal");
}

if (LOGGER.isTraceEnabled()) {
String username = getUsername(authentication);
LOGGER.trace("AUTZ operation {}, principal {}: {}", new Object[]{operationUrl, username, allow});
}
if (!allow) {
String username = getUsername(authentication);
LOGGER.error("User {} not authorized for operation {}", username, operationUrl);
throw new SecurityViolationException("User "+username+" not authorized for operation "+operationUrl+":\n"+((MidPointPrincipal)principal).debugDump());
}
}

private static String getUsername(Authentication authentication) {
String username = "(none)";
Object principal = authentication.getPrincipal();
if (principal != null) {
if (principal instanceof MidPointPrincipal) {
username = "'"+((MidPointPrincipal)principal).getUsername()+"'";
} else {
username = "(unknown:"+principal+")";
}
}
return username;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2013 Evolveum
* 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.
Expand Down Expand Up @@ -91,6 +91,7 @@ public class AbstractInternalModelIntegrationTest extends AbstractModelIntegrati
public static final String SYSTEM_CONFIGURATION_OID = SystemObjectsType.SYSTEM_CONFIGURATION.value();

protected static final String USER_ADMINISTRATOR_FILENAME = COMMON_DIR_NAME + "/user-administrator.xml";
protected static final String USER_ADMINISTRATOR_NAME = "administrator";
protected static final String USER_ADMINISTRATOR_OID = "00000000-0000-0000-0000-000000000002";

protected static final String USER_JACK_FILENAME = COMMON_DIR_NAME + "/user-jack.xml";
Expand Down Expand Up @@ -190,6 +191,7 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti

// Administrator
userAdministrator = repoAddObjectFromFile(USER_ADMINISTRATOR_FILENAME, UserType.class, initResult);
loginSuperUser(userAdministrator.asObjectable().getName().getOrig());

// User Templates
repoAddObjectFromFile(USER_TEMPLATE_FILENAME, ObjectTemplateType.class, initResult);
Expand Down
Loading

0 comments on commit 9b14f94

Please sign in to comment.