📄 grouppermission.java
字号:
* <p> * GroupPermissions can only imply other GroupPermissions; no other * permission types are implied. One GroupPermission implies another if its * actions if three conditions are met: * </p> * <ol> * <li>The other GroupPermission’s wiki is equal to, or a subset of, that * of this permission. This permission’s wiki is considered a superset of * the other if it contains a matching prefix plus a wildcard, or a wildcard * followed by a matching suffix.</li> * <li>The other GroupPermission’s target is equal to, or a subset of, the * target specified by this permission. This permission’s target is * considered a superset of the other if it contains a matching prefix plus * a wildcard, or a wildcard followed by a matching suffix.</li> * <li>All of other GroupPermission’s actions are equal to, or a subset of, * those of this permission</li> * </ol> * @param permission the Permission to examine * @return <code>true</code> if the GroupPermission implies the * supplied Permission; <code>false</code> otherwise * @see java.security.Permission#implies(java.security.Permission) */ public final boolean implies( Permission permission ) { // Permission must be a GroupPermission if ( !( permission instanceof GroupPermission ) ) { return false; } // Build up an "implied mask" GroupPermission p = (GroupPermission) permission; int impliedMask = impliedMask( m_mask ); // If actions aren't a proper subset, return false if ( ( impliedMask & p.m_mask ) != p.m_mask ) { return false; } // See if the tested permission's wiki is implied boolean impliedWiki = PagePermission.isSubset( m_wiki, p.m_wiki ); // If this page is "*", the tested permission's // group is implied, unless implied permission has <groupmember> token boolean impliedGroup; if ( MEMBER_TOKEN.equals( p.m_group ) ) { impliedGroup = MEMBER_TOKEN.equals( m_group ); } else { impliedGroup = PagePermission.isSubset( m_group, p.m_group ); } // See if this permission is <groupmember> and Subject possesses // GroupPrincipal matching the implied GroupPermission's group boolean impliedMember = impliesMember( p ); return impliedWiki && ( impliedGroup || impliedMember ); } /** * Prints a human-readable representation of this permission. * @return the string * @see java.lang.Object#toString() */ public final String toString() { String wiki = ( m_wiki == null ) ? "" : m_wiki; return "(\"" + this.getClass().getName() + "\",\"" + wiki + WIKI_SEPARATOR + m_group + "\",\"" + getActions() + "\")"; } /** * Creates an “implied mask” based on the actions originally assigned: for * example, delete implies edit; edit implies view. * @param mask binary mask for actions * @return binary mask for implied actions */ protected static final int impliedMask( int mask ) { if ( ( mask & DELETE_MASK ) > 0 ) { mask |= EDIT_MASK; } if ( ( mask & EDIT_MASK ) > 0 ) { mask |= VIEW_MASK; } return mask; } /** * Protected method that creates a binary mask based on the actions specified. * This is used by {@link #implies(Permission)}. * @param actions the actions for this permission, separated by commas * @return the binary actions mask */ protected static final int createMask( String actions ) { if ( actions == null || actions.length() == 0 ) { throw new IllegalArgumentException( "Actions cannot be blank or null" ); } int mask = 0; String[] actionList = actions.split( ACTION_SEPARATOR ); for( String action : actionList ) { if ( action.equalsIgnoreCase( VIEW_ACTION ) ) { mask |= VIEW_MASK; } else if ( action.equalsIgnoreCase( EDIT_ACTION ) ) { mask |= EDIT_MASK; } else if ( action.equalsIgnoreCase( DELETE_ACTION ) ) { mask |= DELETE_MASK; } else { throw new IllegalArgumentException( "Unrecognized action: " + action ); } } return mask; } /** * <p> * Returns <code>true</code> if this GroupPermission was created with the * token <code><groupmember></code> * <em>and</em> the current * thread’s Subject is a member of the Group indicated by the implied * GroupPermission. Thus, a GroupPermission with the group * <code><groupmember></code> implies GroupPermission for group * "TestGroup" only if the Subject is a member of TestGroup. * </p> * <p> * We make this determination by obtaining the current {@link Thread}’s * {@link java.security.AccessControlContext} and requesting the * {@link javax.security.auth.SubjectDomainCombiner}. If the combiner is * not <code>null</code>, then we know that the access check was * requested using a {@link javax.security.auth.Subject}; that is, that an * upstream caller caused a Subject to be associated with the Thread’s * ProtectionDomain by executing a * {@link javax.security.auth.Subject#doAs(Subject, java.security.PrivilegedAction)} * operation. * </p> * <p> * If a SubjectDomainCombiner exists, determining group membership is * simple: just iterate through the Subject’s Principal set and look for all * Principals of type {@link com.ecyrd.jspwiki.auth.GroupPrincipal}. If the * name of any Principal matches the value of the implied Permission’s * {@link GroupPermission#getGroup()} value, then the Subject is a member of * this group -- and therefore this <code>impliesMember</code> call * returns <code>true</code>. * </p> * <p> * This may sound complicated, but it really isn’t. Consider the following * examples: * </p> * <table border="1"> <thead> * <tr> * <th width="25%">This object</th> * <th width="25%"><code>impliesMember</code> parameter</th> * <th width="25%">Calling Subject’s Principals * <th width="25%">Result</th> * </tr> * <tr> * <td><code>GroupPermission ("<groupmember>")</code></td> * <td><code>GroupPermission ("*:TestGroup")</code></td> * <td><code>WikiPrincipal ("Biff"),<br/>GroupPrincipal ("TestGroup")</code></td> * <td><code>true</code></td> * </tr> * <tr> * <td><code>GroupPermission ("*:TestGroup")</code></td> * <td><code>GroupPermission ("*:TestGroup")</code></td> * <td><code>WikiPrincipal ("Biff"),<br/>GroupPrincipal ("TestGroup")</code></td> * <td><code>false</code> - this object does not contain * <code><groupmember></code></td> * </tr> * <tr> * <td><code>GroupPermission ("<groupmember>")</code></td> * <td><code>GroupPermission ("*:TestGroup")</code></td> * <td><code>WikiPrincipal ("Biff"),<br/>GroupPrincipal ("FooGroup")</code></td> * <td><code>false</code> - Subject does not contain GroupPrincipal * matching implied Permission’s group (TestGroup)</td> * </tr> * <tr> * <td><code>GroupPermission ("<groupmember>")</code></td> * <td><code>WikiPermission ("*:createGroups")</code></td> * <td><code>WikiPrincipal ("Biff"),<br/>GroupPrincipal ("TestGroup")</code></td> * <td><code>false</code> - implied permission not of type * GroupPermission</td> * </tr> * <tr> * <td><code>GroupPermission ("<groupmember>")</code></td> * <td><code>GroupPermission ("*:TestGroup")</code></td> * <td>-</td> * <td><code>false</code> - <code>Subject.doAs()</code> not called * upstream</td> * </tr> * </table> * <p> * Note that JSPWiki’s access control checks are made inside of * {@link com.ecyrd.jspwiki.auth.AuthorizationManager#checkPermission(com.ecyrd.jspwiki.WikiSession, Permission)}, * which performs a <code>Subject.doAs()</code> call. Thus, this * Permission functions exactly the way it should during normal * operations. * </p> * @param permission the implied permission * @return <code>true</code> if the calling Thread’s Subject contains a * GroupPrincipal matching the implied GroupPermission’s group; * <code>false</code> otherwise */ protected final boolean impliesMember( Permission permission ) { if ( !( permission instanceof GroupPermission ) ) { return false; } GroupPermission gp = (GroupPermission) permission; if ( !MEMBER_TOKEN.equals( m_group ) ) { return false; } // For the current thread, retrieve the SubjectDomainCombiner // (if one was used to create current AccessControlContext ) AccessControlContext acc = AccessController.getContext(); DomainCombiner dc = acc.getDomainCombiner(); if ( dc != null && dc instanceof SubjectDomainCombiner ) { // <member> implies permission if subject possesses // GroupPrincipal with same name as target Subject subject = ( (SubjectDomainCombiner) dc ).getSubject(); Set<GroupPrincipal> principals = subject.getPrincipals( GroupPrincipal.class ); for( Principal principal : principals ) { if ( principal.getName().equals( gp.m_group ) ) { return true; } } } return false; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -