/******************************************************************************* * Copyright (c) 2012 RelationWare, Benno Luthiger * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * RelationWare, Benno Luthiger ******************************************************************************/ package org.ripla.useradmin.admin; import java.util.ArrayList; import java.util.Vector; import org.osgi.service.useradmin.Authorization; import org.osgi.service.useradmin.Role; /** * <p> * The <tt>Authorization</tt> interface encapsulates an authorization context on * which bundles can base authorization decisions, where appropriate. * </p> * <p> * Bundles associate the privilege to access restricted resources or operations * with roles. Before granting access to a restricted resource or operation, a * bundle will check if the <tt>Authorization</tt> object passed to it possesses * the required role, by calling its <tt>hasRole</tt> method. * </p> * <p> * Authorization contexts are instantiated by calling the {@link * RiplaUserAdmin.#getAuthorization(org.osgi.service.useradmin.User)} method. * </p> * <p> * <i>Trusting Authorization objects</i> * </p> * <p> * There are no restrictions regarding the creation of <tt>Authorization</tt> * objects. Hence, a service must only accept <tt>Authorization</tt> objects * from bundles that has been authorized to use the service using code based (or * Java 2) permissions. * * </p> * <p> * In some cases it is useful to use <tt>ServicePermission</tt> to do the code * based access control. A service basing user access control on * <tt>Authorization</tt> objects passed to it, will then require that a calling * bundle has the <tt>ServicePermission</tt> to get the service in question. * This is the most convenient way. The OSGi environment will do the code based * permission check when the calling bundle attempts to get the service from the * service registry. * </p> * <p> * Example: A servlet using a service on a user's behalf. The bundle with the * servlet must be given the <tt>ServicePermission</tt> to get the Http Service. * </p> * <p> * However, in some cases the code based permission checks need to be more * fine-grained. A service might allow all bundles to get it, but require * certain code based permissions for some of its methods. * </p> * <p> * Example: A servlet using a service on a user's behalf, where some service * functionality is open to anyone, and some is restricted by code based * permissions. When a restricted method is called (e.g., one handing over an * <tt>Authorization</tt> object), the service explicitly checks that the * calling bundle has permission to make the call. * </p> * <p> * Authorization example: * </p> * * <pre> * if (!userAdmin.getAuthorization(user).hasRole("my.role")) { * throw new NotAuthorizedException("Not authorized to ...!"); * } * </pre> * * @author Luthiger */ public class RiplaAuthorization implements Authorization { private final transient RiplaUserAdmin userAdmin; private final transient Role user; private final transient String name; /** * @param inUser * @param inRiplaUserAdmin */ public RiplaAuthorization(final RiplaUser inUser, final RiplaUserAdmin inUserAdmin) { userAdmin = inUserAdmin; if (inUser == null) { // anonymous user user = inUserAdmin.getRole(Role.USER_ANYONE); name = null; } else { user = inUser; name = user.getName(); } } /* * (non-Javadoc) * * @see org.osgi.service.useradmin.Authorization#getName() */ @Override public String getName() { userAdmin.checkAlive(); return name; } /* * (non-Javadoc) * * @see org.osgi.service.useradmin.Authorization#hasRole(java.lang.String) */ @Override public boolean hasRole(final String inName) { userAdmin.checkAlive(); synchronized (userAdmin) { final RiplaRole lRole = (RiplaRole) userAdmin.getRole(inName); if (lRole == null) { return false; } return lRole.isImpliedBy(user, new ArrayList<String>()); } } /* * (non-Javadoc) * * @see org.osgi.service.useradmin.Authorization#getRoles() */ @Override public String[] getRoles() { userAdmin.checkAlive(); synchronized (userAdmin) { final int lLength = userAdmin.roles.size(); final Vector<String> lResult = new Vector<String>(lLength); // NOPMD by Luthiger on 07.09.12 00:10 for (final Role lRole : userAdmin.roles) { if (((RiplaRole) lRole).isImpliedBy(user, new ArrayList<String>())) { // NOPMD by Luthiger on 07.09.12 00:10 final String lRoleName = lRole.getName(); if (!lRoleName.equals(Role.USER_ANYONE)) { lResult.add(lRoleName); } } } final int lSize = lResult.size(); if (lSize == 0) { return null; } final String[] out = new String[lSize]; lResult.copyInto(out); return out; } } }