All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.osgi.service.application.ApplicationAdminPermission Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) OSGi Alliance (2004, 2013). All Rights Reserved.
 * 
 * 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 org.osgi.service.application;

import java.security.Permission;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;

/**
 * This class implements permissions for manipulating applications and their
 * instances.
 * 

* ApplicationAdminPermission can be targeted to applications that matches the * specified filter. *

* ApplicationAdminPermission may be granted for different actions: * {@code lifecycle}, {@code schedule} and {@code lock}. The permission * {@code schedule} implies the permission {@code lifecycle}. * * @author $Id: c8c799ae29ff5bb6095e22d201b47a3445eb42cb $ */ public class ApplicationAdminPermission extends Permission { private static final long serialVersionUID = 1L; /** * Allows the lifecycle management of the target applications. */ public static final String LIFECYCLE_ACTION = "lifecycle"; /** * Allows scheduling of the target applications. The permission to schedule * an application implies that the scheduler can also manage the lifecycle * of that application i.e. {@code schedule} implies {@code lifecycle} */ public static final String SCHEDULE_ACTION = "schedule"; /** * Allows setting/unsetting the locking state of the target applications. */ public static final String LOCK_ACTION = "lock"; private ApplicationDescriptor applicationDescriptor; /** * Constructs an ApplicationAdminPermission. The {@code filter} specifies * the target application. The {@code filter} is an LDAP-style filter, the * recognized properties are {@code signer} and {@code pid}. The pattern * specified in the {@code signer} is matched with the Distinguished Name * chain used to sign the application. Wildcards in a DN are not matched * according to the filter string rules, but according to the rules defined * for a DN chain. The attribute {@code pid} is matched with the PID of the * application according to the filter string rules. *

* If the {@code filter} is {@code null} then it matches {@code "*"}. If * {@code actions} is {@code "*"} then it identifies all the possible * actions. * * @param filter filter to identify application. The value {@code null} is * equivalent to {@code "*"} and it indicates "all application". * @param actions comma-separated list of the desired actions granted on the * applications or "*" means all the actions. It must not be * {@code null}. The order of the actions in the list is not * significant. * @throws InvalidSyntaxException is thrown if the specified {@code filter} * is not syntactically correct. * * @exception NullPointerException is thrown if the actions parameter is * {@code null} * * @see ApplicationDescriptor * @see org.osgi.framework.AdminPermission */ public ApplicationAdminPermission(String filter, String actions) throws InvalidSyntaxException { super(filter == null ? "*" : filter); if (filter == null) filter = "*"; if (actions == null) throw new NullPointerException("Action string cannot be null!"); this.applicationDescriptor = null; this.filter = (filter == null ? "*" : filter); this.actions = actions; if (!filter.equals("*") && !filter.equals("<>")) FrameworkUtil.createFilter(this.filter); // check if the filter is // valid init(); } /** * This contructor should be used when creating * {@code ApplicationAdminPermission} instance for {@code checkPermission} * call. * * @param application the tareget of the operation, it must not be * {@code null} * @param actions the required operation. it must not be {@code null} * @throws NullPointerException if any of the arguments is null. */ public ApplicationAdminPermission(ApplicationDescriptor application, String actions) { super(application.getApplicationId()); if (application == null || actions == null) throw new NullPointerException("ApplicationDescriptor and action string cannot be null!"); this.filter = application.getApplicationId(); this.applicationDescriptor = application; this.actions = actions; init(); } /** * This method can be used in the {@link java.security.ProtectionDomain} * implementation in the {@code implies} method to insert the application ID * of the current application into the permission being checked. This * enables the evaluation of the {@code <>} pseudo targets. * * @param applicationId the ID of the current application. * @return the permission updated with the ID of the current application */ public ApplicationAdminPermission setCurrentApplicationId(String applicationId) { ApplicationAdminPermission newPerm = null; if (this.applicationDescriptor == null) { try { newPerm = new ApplicationAdminPermission(this.filter, this.actions); } catch (InvalidSyntaxException e) { throw new RuntimeException(e); /* this can never happen */ } } else newPerm = new ApplicationAdminPermission(this.applicationDescriptor, this.actions); newPerm.applicationID = applicationId; return newPerm; } /** * Checks if the specified {@code permission} is implied by this permission. * The method returns true under the following conditions: *

    *
  • This permission was created by specifying a filter (see * {@link #ApplicationAdminPermission(String, String)})
  • *
  • The implied {@code otherPermission} was created for a particular * {@link ApplicationDescriptor} (see * {@link #ApplicationAdminPermission(ApplicationDescriptor, String)})
  • *
  • The {@code filter} of this permission mathes the * {@code ApplicationDescriptor} specified in the {@code otherPermission}. * If the filter in this permission is the {@code <>} pseudo target, * then the currentApplicationId set in the {@code otherPermission} is * compared to the application Id of the target * {@code ApplicationDescriptor}.
  • *
  • The list of permitted actions in this permission contains all actions * required in the {@code otherPermission}
  • *
* Otherwise the method returns false. * * @param otherPermission the implied permission * @return true if this permission implies the {@code otherPermission}, * false otherwise. */ public boolean implies(Permission otherPermission) { if (otherPermission == null) return false; if (!(otherPermission instanceof ApplicationAdminPermission)) return false; ApplicationAdminPermission other = (ApplicationAdminPermission) otherPermission; if (!filter.equals("*")) { if (other.applicationDescriptor == null) return false; if (filter.equals("<>")) { if (other.applicationID == null) return false; /* it cannot be, this might be a bug */ if (!other.applicationID.equals(other.applicationDescriptor.getApplicationId())) return false; } else { Hashtable props = new Hashtable(); props.put("pid", other.applicationDescriptor.getApplicationId()); props.put("signer", new SignerWrapper(other.applicationDescriptor)); Filter flt = getFilter(); if (flt == null) return false; if (!flt.match(props)) return false; } } if (!actionsVector.containsAll(other.actionsVector)) return false; return true; } public boolean equals(Object with) { if (with == null || !(with instanceof ApplicationAdminPermission)) return false; ApplicationAdminPermission other = (ApplicationAdminPermission) with; // Compare actions: if (other.actionsVector.size() != actionsVector.size()) return false; for (int i = 0; i != actionsVector.size(); i++) if (!other.actionsVector.contains(actionsVector.get(i))) return false; return equal(this.filter, other.filter) && equal(this.applicationDescriptor, other.applicationDescriptor) && equal(this.applicationID, other.applicationID); } /** * Compares parameters for equality. If both object are null, they are * considered equal. * * @param a object to compare * @param b other object to compare * @return true if both objects are equal or both are null */ private static boolean equal(Object a, Object b) { // This equation is true if both references are null or both point // to the same object. In both cases they are considered as equal. if (a == b) { return true; } return a.equals(b); } public int hashCode() { int hc = 0; for (int i = 0; i != actionsVector.size(); i++) hc ^= ((String) actionsVector.get(i)).hashCode(); hc ^= (null == this.filter) ? 0 : this.filter.hashCode(); hc ^= (null == this.applicationDescriptor) ? 0 : this.applicationDescriptor.hashCode(); hc ^= (null == this.applicationID) ? 0 : this.applicationID.hashCode(); return hc; } /** * Returns the actions of this permission. * * @return the actions specified when this permission was created */ public String getActions() { return actions; } private String applicationID; private static final Vector ACTIONS = new Vector(); private Vector actionsVector; private final String filter; private final String actions; private Filter appliedFilter = null; static { ACTIONS.add(LIFECYCLE_ACTION); ACTIONS.add(SCHEDULE_ACTION); ACTIONS.add(LOCK_ACTION); } private static Vector actionsVector(String actions) { Vector v = new Vector(); StringTokenizer t = new StringTokenizer(actions.toUpperCase(), ","); while (t.hasMoreTokens()) { String action = t.nextToken().trim(); v.add(action.toLowerCase()); } if (v.contains(SCHEDULE_ACTION) && !v.contains(LIFECYCLE_ACTION)) v.add(LIFECYCLE_ACTION); return v; } private static class SignerWrapper extends Object { private String pattern; private ApplicationDescriptor appDesc; /** * @param pattern */ public SignerWrapper(String pattern) { this.pattern = pattern; } SignerWrapper(ApplicationDescriptor appDesc) { this.appDesc = appDesc; } public boolean equals(Object o) { if (!(o instanceof SignerWrapper)) return false; SignerWrapper other = (SignerWrapper) o; ApplicationDescriptor matchAppDesc = appDesc != null ? appDesc : other.appDesc; String matchPattern = appDesc != null ? other.pattern : pattern; return matchAppDesc.matchDNChain(matchPattern); } } private void init() { actionsVector = actionsVector(actions); if (actions.equals("*")) actionsVector = actionsVector(LIFECYCLE_ACTION + "," + SCHEDULE_ACTION + "," + LOCK_ACTION); else if (!ACTIONS.containsAll(actionsVector)) throw new IllegalArgumentException("Illegal action!"); applicationID = null; } private Filter getFilter() { if (appliedFilter == null) { try { appliedFilter = FrameworkUtil.createFilter(filter); } catch (InvalidSyntaxException e) { // we will return null } } return appliedFilter; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy