001package systems.dmx.core.service.accesscontrol; 002 003import systems.dmx.core.Association; 004import systems.dmx.core.DMXObject; 005import systems.dmx.core.RelatedTopic; 006import systems.dmx.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 /** 115 * Returns the username that is associated with a session. 116 * 117 * @return the username, or <code>null</code> if no user is associated with the session. 118 */ 119 String username(HttpSession session); 120 121 122 123 // === Workspaces / Memberships === 124 125 /** 126 * Returns a workspace by URI. 127 * <p> 128 * This is a privileged method: it works also if the current user has no READ permission for the workspace. 129 * 130 * @return The workspace (a topic of type "Workspace"). 131 * 132 * @throws RuntimeException If no workspace exists for the given URI. 133 */ 134 Topic getWorkspace(String uri); 135 136 // --- 137 138 /** 139 * Returns the ID of the "DMX" workspace. 140 */ 141 long getDMXWorkspaceId(); 142 143 /** 144 * Returns the ID of the "Administration" workspace. 145 */ 146 long getAdministrationWorkspaceId(); 147 148 /** 149 * Returns the ID of the "System" workspace. 150 */ 151 long getSystemWorkspaceId(); 152 153 // --- 154 155 /** 156 * Returns the ID of the workspace a topic or association is assigned to. 157 * 158 * @param objectId a topic ID, or an association ID 159 * 160 * @return The workspace ID, or <code>-1</code> if no workspace is assigned. 161 */ 162 long getAssignedWorkspaceId(long objectId); 163 164 /** 165 * Performs the initial workspace assignment for an object. 166 * <p> 167 * Use this method only for objects which have no workspace assignment already, that is e.g. objects 168 * created in a migration or objects created while workspace assignment is deliberately suppressed. 169 */ 170 void assignToWorkspace(DMXObject object, long workspaceId); 171 172 /** 173 * Checks if an association represents a workspace assignment. 174 * <p> 175 * This is a privileged method: it works also if the current user has no READ permission for the potential 176 * workspace. 177 */ 178 boolean isWorkspaceAssignment(Association assoc); 179 180 // --- 181 182 /** 183 * Runs a code block while suppressing the standard workspace assignment for all topics/associations 184 * created within that code block. 185 */ 186 <V> V runWithoutWorkspaceAssignment(Callable<V> callable) throws Exception; 187 188 /** 189 * Returns true if standard workspace assignment is currently suppressed for the current thread. 190 */ 191 boolean workspaceAssignmentIsSuppressed(); 192 193 194 195 // === Topicmaps === 196 197 void deleteAssociationMapcontext(Association assoc); 198 199 200 201 // === Config Service === 202 203 /** 204 * Returns the configuration topic of the given type for the given topic. 205 * <p> 206 * This is a privileged method, it bypasses the access control system. 207 * 208 * @throws RuntimeException if no such configuration topic exists. 209 */ 210 RelatedTopic getConfigTopic(String configTypeUri, long topicId); 211 212 213 214 // === Email Addresses === 215 216 /** 217 * Returns the username for the given email address. 218 * <p> 219 * The username is determined by traversing from the Email Address topic along a 220 * <code>org.deepamehta.signup.user_mailbox</code> association. 221 * <p> 222 * This is a privileged method, it bypasses the access control system. 223 * 224 * @throws RuntimeException if no such Email Address topic exists in the DB, or 225 * if more than one such Email Address topics exist in the DB, or 226 * if the Email Address topic is not associated to a Username topic. 227 */ 228 String getUsername(String emailAddress); 229 230 /** 231 * Returns the email address for the given username. 232 * <p> 233 * The email address is determined by traversing from the Username topic along a 234 * <code>org.deepamehta.signup.user_mailbox</code> association. 235 * <p> 236 * This is a privileged method, it bypasses the access control system. 237 * 238 * @throws RuntimeException if no such Username topic exists in the DB, or 239 * if the Username topic is not associated to an Email Address topic. 240 */ 241 String getEmailAddress(String username); 242 243 // --- 244 245 /** 246 * Returns true if an "Email Address" (dmx.contacts.email_address) topic with the given value exists, 247 * false otherwise. 248 * <p> 249 * This is a privileged method, it bypasses the access control system. 250 */ 251 boolean emailAddressExists(String emailAddress); 252}