View Javadoc

1   /*
2    * Copyright 2015 Data Archiving and Networked Services (an institute of
3    * Koninklijke Nederlandse Akademie van Wetenschappen), King's College London,
4    * Georg-August-Universitaet Goettingen Stiftung Oeffentlichen Rechts
5    *
6    * Licensed under the EUPL, Version 1.1 or – as soon they will be approved by
7    * the European Commission - subsequent versions of the EUPL (the "Licence");
8    * You may not use this work except in compliance with the Licence.
9    * You may obtain a copy of the Licence at:
10   *
11   * https://joinup.ec.europa.eu/software/page/eupl
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the Licence is distributed on an "AS IS" basis,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the Licence for the specific language governing
17   * permissions and limitations under the Licence.
18   */
19  
20  package eu.ehri.project.acl;
21  
22  import com.google.common.base.Preconditions;
23  import com.tinkerpop.frames.FramedGraph;
24  import eu.ehri.project.core.GraphManager;
25  import eu.ehri.project.core.GraphManagerFactory;
26  import eu.ehri.project.exceptions.AccessDenied;
27  import eu.ehri.project.exceptions.ItemNotFound;
28  import eu.ehri.project.exceptions.PermissionDenied;
29  import eu.ehri.project.models.ContentType;
30  import eu.ehri.project.models.EntityClass;
31  import eu.ehri.project.models.base.Accessible;
32  import eu.ehri.project.models.base.Accessor;
33  import eu.ehri.project.models.base.PermissionScope;
34  import eu.ehri.project.models.utils.ClassUtils;
35  
36  import java.util.Optional;
37  
38  /**
39   * Messy stopgap class to hold a bunch of sort-of view/sort-of acl functions.
40   */
41  public final class PermissionUtils {
42  
43      private final FramedGraph<?> graph;
44      private final PermissionScope scope;
45      private final AclManager acl;
46      private final GraphManager manager;
47  
48      public PermissionUtils(FramedGraph<?> graph) {
49          this(graph, SystemScope.getInstance());
50      }
51  
52      public PermissionUtils(FramedGraph<?> graph, PermissionScope scope) {
53          Preconditions.checkNotNull(scope);
54          this.graph = graph;
55          this.acl = new AclManager(graph, scope);
56          this.scope = scope;
57          this.manager = GraphManagerFactory.getInstance(graph);
58      }
59  
60      /**
61       * Check permissions for a given type.
62       *
63       * @param accessor       The user/group
64       * @param contentType    The content type
65       * @param permissionType The permission type
66       */
67      public void checkContentPermission(Accessor accessor, ContentTypes contentType,
68              PermissionType permissionType) throws PermissionDenied {
69          if (!acl.hasPermission(contentType, permissionType, accessor)) {
70              throw new PermissionDenied(accessor.getId(), contentType.toString(), permissionType.toString(), scope.getId());
71          }
72      }
73  
74      /**
75       * Check permissions for a given entity.
76       *
77       * @param entity         The item
78       * @param accessor       The user/group
79       * @param permissionType The permission type
80       */
81      public void checkEntityPermission(Accessible entity,
82              Accessor accessor, PermissionType permissionType) throws PermissionDenied {
83          if (!acl.hasPermission(entity, permissionType, accessor)) {
84              throw new PermissionDenied(accessor.getId(), entity.getId(),
85                      permissionType.toString(), scope.getId());
86          }
87      }
88  
89      /**
90       * Ensure an item is readable by the given accessor
91       *
92       * @param entity   The item
93       * @param accessor The accessor/group
94       */
95      public void checkReadAccess(Accessible entity, Accessor accessor)
96              throws AccessDenied {
97          if (!acl.canAccess(entity, accessor)) {
98              // Using 'fake' permission 'read'
99              throw new AccessDenied(accessor.getId(), entity.getId());
100         }
101     }
102 
103     /**
104      * Get the content type node with the given id.
105      *
106      * @param entityClass The entity class
107      * @return A vertex framed as a content entityClass
108      */
109     public ContentType getContentTypeNode(EntityClass entityClass) {
110         try {
111             return manager.getEntity(entityClass.getName(), ContentType.class);
112         } catch (ItemNotFound e) {
113             throw new RuntimeException(
114                     String.format("No content entityClass node found for entityClass: '%s'",
115                             entityClass.getName()), e);
116         }
117     }
118 
119     /**
120      * Get the content type enum value with the given id.
121      *
122      * @param cls The frame class
123      * @return A vertex framed as a content type
124      */
125     public ContentTypes getContentTypeEnum(Class<?> cls) {
126         return ContentTypes.withName(ClassUtils.getEntityType(cls).getName());
127     }
128 
129     /**
130      * Set the scope under which ACL and permission operations will take place.
131      * This is, for example, an Repository instance, where the objects being
132      * manipulated are DocumentaryUnits. The given scope is used to compare
133      * against the scope relation on PermissionGrants.
134      *
135      * @param scope The new scope
136      * @return A new view helper
137      */
138     public PermissionUtils setScope(PermissionScope scope) {
139         return new PermissionUtils(graph,
140                 Optional.ofNullable(scope).orElse(SystemScope.INSTANCE));
141     }
142 }