root/trunk/components/server/src/ome/tools/hibernate/SecurityFilter.java
| Revision 1167, 5.3 kB (checked in by jmoore, 2 years ago) | |
|---|---|
|
|
| Line | |
|---|---|
| 1 | /* |
| 2 | * ome.tools.hibernate.SecurityFilter |
| 3 | * |
| 4 | * Copyright 2006 University of Dundee. All rights reserved. |
| 5 | * Use is subject to license terms supplied in LICENSE.txt |
| 6 | */ |
| 7 | |
| 8 | package ome.tools.hibernate; |
| 9 | |
| 10 | // Java imports |
| 11 | import java.util.Collection; |
| 12 | import java.util.Properties; |
| 13 | |
| 14 | // Third-party libraries |
| 15 | import org.springframework.beans.factory.FactoryBean; |
| 16 | import org.springframework.orm.hibernate3.FilterDefinitionFactoryBean; |
| 17 | |
| 18 | // Application-internal dependencies |
| 19 | import ome.conditions.InternalException; |
| 20 | import ome.model.internal.Details; |
| 21 | import ome.model.internal.Permissions; |
| 22 | import ome.model.internal.Permissions.Right; |
| 23 | import ome.model.internal.Permissions.Role; |
| 24 | import static ome.model.internal.Permissions.Role.*; |
| 25 | import static ome.model.internal.Permissions.Right.*; |
| 26 | |
| 27 | /** |
| 28 | * overrides {@link FilterDefinitionFactoryBean} in order to construct our |
| 29 | * security filter in code and not in XML. This allows us to make use of the |
| 30 | * knowledge within {@link Permissions} |
| 31 | * |
| 32 | * @author Josh Moore <a |
| 33 | * href="mailto:josh.moore@gmx.de">josh.moore@gmx.de</a> |
| 34 | * @version 3.0 <small> (<b>Internal version:</b> $Rev$ $Date$) </small> |
| 35 | * @since 3.0 |
| 36 | * @see <a href="https://trac.openmicroscopy.org.uk/omero/ticket/117">ticket117</a> |
| 37 | */ |
| 38 | public class SecurityFilter extends FilterDefinitionFactoryBean { |
| 39 | |
| 40 | static public final String is_admin = "is_admin"; |
| 41 | |
| 42 | static public final String current_user = "current_user"; |
| 43 | |
| 44 | static public final String current_groups = "current_groups"; |
| 45 | |
| 46 | static public final String leader_of_groups = "leader_of_groups"; |
| 47 | |
| 48 | static public final String filterName = "securityFilter"; |
| 49 | |
| 50 | static private final Properties parameterTypes = new Properties(); |
| 51 | |
| 52 | static private String defaultFilterCondition; |
| 53 | static { |
| 54 | parameterTypes.setProperty(is_admin, "java.lang.Boolean"); |
| 55 | parameterTypes.setProperty(current_user, "long"); |
| 56 | parameterTypes.setProperty(current_groups, "long"); |
| 57 | parameterTypes.setProperty(leader_of_groups, "long"); |
| 58 | // This can't be done statically because we need the securitySystem. |
| 59 | defaultFilterCondition = String.format("\n( " + "\n :is_admin OR " |
| 60 | + "\n (group_id in (:leader_of_groups)) OR " |
| 61 | + "\n (owner_id = :current_user AND %s) OR " + // 1st arg U |
| 62 | "\n (group_id in (:current_groups) AND %s) OR " + // 2nd arg G |
| 63 | "\n (%s) " + // 3rd arg W |
| 64 | "\n)\n", isGranted(USER, READ), isGranted(GROUP, READ), |
| 65 | isGranted(WORLD, READ)); |
| 66 | } |
| 67 | |
| 68 | /** |
| 69 | * default constructor which calls all the necessary setters for this |
| 70 | * {@link FactoryBean}. Also constructs the |
| 71 | * {@link #defaultFilterCondition } This query clause must be kept in sync |
| 72 | * with |
| 73 | * {@link #passesFilter(Details, Long, Collection, Collection, boolean)} |
| 74 | * |
| 75 | * @see #passesFilter(Details, Long, Collection, Collection, boolean) |
| 76 | * @see FilterDefinitionFactoryBean#setFilterName(String) |
| 77 | * @see FilterDefinitionFactoryBean#setParameterTypes(Properties) |
| 78 | * @see FilterDefinitionFactoryBean#setDefaultFilterCondition(String) |
| 79 | */ |
| 80 | public SecurityFilter() { |
| 81 | this.setFilterName(filterName); |
| 82 | this.setParameterTypes(parameterTypes); |
| 83 | this.setDefaultFilterCondition(defaultFilterCondition); |
| 84 | } |
| 85 | |
| 86 | /** |
| 87 | * tests that the {@link Details} argument passes the security test that |
| 88 | * this filter defines. The two must be kept in sync. This will be used |
| 89 | * mostly by the |
| 90 | * {@link OmeroInterceptor#onLoad(Object, java.io.Serializable, Object[], String[], org.hibernate.type.Type[])} |
| 91 | * method. |
| 92 | * |
| 93 | * @param d |
| 94 | * Details instance. If null (or if its {@link Permissions} are |
| 95 | * null all {@link Right rights} will be assumed. |
| 96 | * @return true if the object to which this |
| 97 | */ |
| 98 | public static boolean passesFilter(Details d, Long currentUserId, |
| 99 | Collection<Long> memberOfGroups, Collection<Long> leaderOfGroups, |
| 100 | boolean admin) { |
| 101 | if (d == null || d.getPermissions() == null) { |
| 102 | throw new InternalException("Details/Permissions null! " |
| 103 | + "Security system failure -- refusing to continue. " |
| 104 | + "The Permissions should be set to a default value."); |
| 105 | } |
| 106 | |
| 107 | Permissions p = d.getPermissions(); |
| 108 | |
| 109 | Long o = d.getOwner().getId(); |
| 110 | Long g = d.getGroup().getId(); |
| 111 | |
| 112 | // most likely and fastest first |
| 113 | if (p.isGranted(WORLD, READ)) { |
| 114 | return true; |
| 115 | } |
| 116 | |
| 117 | if (currentUserId.equals(o) && p.isGranted(USER, READ)) { |
| 118 | return true; |
| 119 | } |
| 120 | |
| 121 | if (memberOfGroups.contains(g) |
| 122 | && d.getPermissions().isGranted(GROUP, READ)) { |
| 123 | return true; |
| 124 | } |
| 125 | |
| 126 | if (admin) { |
| 127 | return true; |
| 128 | } |
| 129 | |
| 130 | if (leaderOfGroups.contains(g)) { |
| 131 | return true; |
| 132 | } |
| 133 | |
| 134 | return false; |
| 135 | } |
| 136 | |
| 137 | // ~ Helpers |
| 138 | // ========================================================================= |
| 139 | |
| 140 | protected static String isGranted(Role role, Right right) { |
| 141 | String bit = "" + Permissions.bit(role, right); |
| 142 | String isGranted = String |
| 143 | .format( |
| 144 | "(cast(permissions as bit(64)) & cast(%s as bit(64))) = cast(%s as bit(64))", |
| 145 | bit, bit); |
| 146 | return isGranted; |
| 147 | } |
| 148 | |
| 149 | } |
Note: See TracBrowser
for help on using the browser.
