001package de.deepamehta.core.service.accesscontrol; 002 003import de.deepamehta.core.Association; 004import de.deepamehta.core.DeepaMehtaObject; 005import de.deepamehta.core.RelatedTopic; 006import de.deepamehta.core.Topic; 007 008import javax.servlet.http.HttpServletRequest; 009import javax.servlet.http.HttpSession; 010 011import java.util.concurrent.Callable; 012 013 014 015public interface AccessControl { 016 017 018 019 // === Permissions === 020 021 /** 022 * Checks if a user is permitted to perform an operation on an object (topic or association). 023 * 024 * @param username the logged in user, or <code>null</code> if no user is logged in. 025 * @param objectId a topic ID, or an association ID. 026 * 027 * @return <code>true</code> if permission is granted, <code>false</code> otherwise. 028 */ 029 boolean hasPermission(String username, Operation operation, long objectId); 030 031 // --- 032 033 boolean hasReadPermission(String username, long workspaceId); 034 035 boolean hasWritePermission(String username, long workspaceId); 036 037 038 039 // === User Accounts === 040 041 /** 042 * Checks if the given credentials are valid. 043 * 044 * @return the corresponding Username topic if the credentials are valid, or <code>null</code> otherwise. 045 */ 046 Topic checkCredentials(Credentials cred); 047 048 /** 049 * Changes the password of an existing user account. 050 * <p> 051 * This is a privileged method: it works also if the respective user is not logged in. 052 * 053 * @param cred the username and new password. 054 * An user account with the given username must exist. (The username can't be changed.) 055 */ 056 void changePassword(Credentials cred); 057 058 // --- 059 060 /** 061 * Returns the Username topic that corresponds to a username. 062 * 063 * @return the Username topic, or <code>null</code> if no such Username topic exists. 064 */ 065 Topic getUsernameTopic(String username); 066 067 /** 068 * Returns the private workspace of the given user. 069 * <p> 070 * Note: a user can have more than one private workspace. 071 * This method returns only the first one. 072 * <p> 073 * This is a privileged method, it bypasses the access control system. 074 * 075 * @throws RuntimeException if the user has no private workspace. 076 * 077 * @return The user's private workspace (a topic of type "Workspace"). 078 */ 079 Topic getPrivateWorkspace(String username); 080 081 /** 082 * Checks if a user is a member of a given workspace. 083 * 084 * @param username the logged in user, or <code>null</code> if no user is logged in. 085 */ 086 boolean isMember(String username, long workspaceId); 087 088 /** 089 * Returns the creator of a topic or an association. 090 * 091 * @return The username of the creator, or <code>null</code> if no creator is set. 092 */ 093 String getCreator(long objectId); 094 095 096 097 // === Session === 098 099 /** 100 * Returns the username that is associated with a request. 101 * 102 * @return the username, or <code>null</code> if no user is associated with the request. 103 */ 104 String getUsername(HttpServletRequest request); 105 106 /** 107 * Convenience method that returns the Username topic that corresponds to a request. 108 * Basically it calls <code>getUsernameTopic(getUsername(request))</code>. 109 * 110 * @return the Username topic, or <code>null</code> if no user is associated with the request. 111 */ 112 Topic getUsernameTopic(HttpServletRequest request); 113 114 String username(HttpSession session); 115 116 117 118 // === Workspaces / Memberships === 119 120 /** 121 * Returns a workspace by URI. 122 * <p> 123 * This is a privileged method: it works also if the current user has no READ permission for the workspace. 124 * 125 * @return The workspace (a topic of type "Workspace"). 126 * 127 * @throws RuntimeException If no workspace exists for the given URI. 128 */ 129 Topic getWorkspace(String uri); 130 131 // --- 132 133 /** 134 * Returns the ID of the "DeepaMehta" workspace. 135 */ 136 long getDeepaMehtaWorkspaceId(); 137 138 /** 139 * Returns the ID of the "Administration" workspace. 140 */ 141 long getAdministrationWorkspaceId(); 142 143 /** 144 * Returns the ID of the "System" workspace. 145 */ 146 long getSystemWorkspaceId(); 147 148 // --- 149 150 /** 151 * Returns the ID of the workspace a topic or association is assigned to. 152 * 153 * @param objectId a topic ID, or an association ID 154 * 155 * @return The workspace ID, or <code>-1</code> if no workspace is assigned. 156 */ 157 long getAssignedWorkspaceId(long objectId); 158 159 /** 160 * Performs the initial workspace assignment for an object. 161 * <p> 162 * Use this method only for objects which have no workspace assignment already, that is e.g. objects 163 * created in a migration or objects created while workspace assignment is deliberately suppressed. 164 */ 165 void assignToWorkspace(DeepaMehtaObject object, long workspaceId); 166 167 /** 168 * Checks if an association represents a workspace assignment. 169 * <p> 170 * This is a privileged method: it works also if the current user has no READ permission for the potential 171 * workspace. 172 */ 173 boolean isWorkspaceAssignment(Association assoc); 174 175 // --- 176 177 /** 178 * Runs a code block while suppressing the standard workspace assignment for all topics/associations 179 * created within that code block. 180 */ 181 <V> V runWithoutWorkspaceAssignment(Callable<V> callable) throws Exception; 182 183 /** 184 * Returns true if standard workspace assignment is currently suppressed for the current thread. 185 */ 186 boolean workspaceAssignmentIsSuppressed(); 187 188 189 190 // === Topicmaps === 191 192 void deleteAssociationMapcontext(Association assoc); 193 194 195 196 // === Config Service === 197 198 /** 199 * Returns the configuration topic of the given type for the given topic. 200 * <p> 201 * This is a privileged method, it bypasses the access control system. 202 * 203 * @throws RuntimeException if no such configuration topic exists. 204 */ 205 RelatedTopic getConfigTopic(String configTypeUri, long topicId); 206 207 208 209 // === Email Addresses === 210 211 /** 212 * Returns the username for the given email address. 213 * <p> 214 * The username is determined by traversing from the Email Address topic along a 215 * <code>org.deepamehta.signup.user_mailbox</code> association. 216 * <p> 217 * This is a privileged method, it bypasses the access control system. 218 * 219 * @throws RuntimeException if no such Email Address topic exists in the DB, or 220 * if more than one such Email Address topics exist in the DB, or 221 * if the Email Address topic is not associated to a Username topic. 222 */ 223 String getUsername(String emailAddress); 224 225 /** 226 * Returns the email address for the given username. 227 * <p> 228 * The email address is determined by traversing from the Username topic along a 229 * <code>org.deepamehta.signup.user_mailbox</code> association. 230 * <p> 231 * This is a privileged method, it bypasses the access control system. 232 * 233 * @throws RuntimeException if no such Username topic exists in the DB, or 234 * if the Username topic is not associated to an Email Address topic. 235 */ 236 String getEmailAddress(String username); 237 238 // --- 239 240 /** 241 * Returns true if an "Email Address" (dm4.contacts.email_address) topic with the given value exists, 242 * false otherwise. 243 * <p> 244 * This is a privileged method, it bypasses the access control system. 245 */ 246 boolean emailAddressExists(String emailAddress); 247}