diff options
author | Simon Rettberg | 2015-06-30 18:21:47 +0200 |
---|---|---|
committer | Simon Rettberg | 2015-06-30 18:21:47 +0200 |
commit | a3cb5ed720dec67fd01759c631e69d6a988e3313 (patch) | |
tree | b47ffce0f885112950752d2462ec4cd92c3ea4e9 /dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions | |
parent | Fixed some comments and variable names (diff) | |
download | tutor-module-a3cb5ed720dec67fd01759c631e69d6a988e3313.tar.gz tutor-module-a3cb5ed720dec67fd01759c631e69d6a988e3313.tar.xz tutor-module-a3cb5ed720dec67fd01759c631e69d6a988e3313.zip |
[server] Refactored permission checking classes a bit
Diffstat (limited to 'dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions')
3 files changed, 339 insertions, 197 deletions
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/LocalData.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/LocalData.java new file mode 100644 index 00000000..3468d69a --- /dev/null +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/LocalData.java @@ -0,0 +1,65 @@ +package org.openslx.bwlp.sat.permissions; + +import java.sql.SQLException; +import java.util.Map; + +import org.openslx.bwlp.sat.database.mappers.DbOrganization; +import org.openslx.bwlp.sat.database.mappers.DbUser; +import org.openslx.bwlp.sat.database.models.LocalOrganization; +import org.openslx.bwlp.sat.database.models.LocalUser; +import org.openslx.bwlp.thrift.iface.UserInfo; +import org.openslx.util.TimeoutHashMap; + +public class LocalData { + + /** + * Cache local user data, might be called quite often. + */ + private static final Map<String, LocalUser> localUserCache = new TimeoutHashMap<>(60000); + + protected static LocalUser getLocalUser(UserInfo user) { + synchronized (localUserCache) { + LocalUser local = localUserCache.get(user.userId); + if (local != null) + return local; + } + LocalUser localData; + try { + localData = DbUser.getLocalData(user); + } catch (SQLException e) { + return null; + } + if (localData == null) + return null; + synchronized (localUserCache) { + localUserCache.put(user.userId, localData); + } + return localData; + } + + /** + * Cache local organization data, might be called quite often. + */ + private static final Map<String, LocalOrganization> localOrganizationCache = new TimeoutHashMap<>(60000); + + protected static LocalOrganization getLocalOrganization(String organizationId) { + synchronized (localOrganizationCache) { + LocalOrganization local = localOrganizationCache.get(organizationId); + if (local != null) + return local; + } + LocalOrganization localData; + try { + localData = DbOrganization.getLocalData(organizationId); + } catch (SQLException e) { + return null; + } + if (localData == null) + return null; + synchronized (localOrganizationCache) { + localOrganizationCache.put(organizationId, localData); + } + return localData; + } + +} diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/PermCheck.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/PermCheck.java new file mode 100644 index 00000000..6b4af039 --- /dev/null +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/PermCheck.java @@ -0,0 +1,175 @@ +package org.openslx.bwlp.sat.permissions; + +import java.sql.SQLException; + +import org.apache.log4j.Logger; +import org.openslx.bwlp.sat.database.mappers.DbImage; +import org.openslx.bwlp.sat.database.mappers.DbLecture; +import org.openslx.bwlp.thrift.iface.AuthorizationError; +import org.openslx.bwlp.thrift.iface.ImagePermissions; +import org.openslx.bwlp.thrift.iface.ImageSummaryRead; +import org.openslx.bwlp.thrift.iface.LecturePermissions; +import org.openslx.bwlp.thrift.iface.LectureSummary; +import org.openslx.bwlp.thrift.iface.TAuthorizationException; +import org.openslx.bwlp.thrift.iface.TInternalServerError; +import org.openslx.bwlp.thrift.iface.TNotFoundException; +import org.openslx.bwlp.thrift.iface.UserInfo; + +public class PermCheck { + + public static enum Permission { + LINK, + DOWNLOAD, + EDIT, + ADMIN + } + + private static final Logger LOGGER = Logger.getLogger(Permission.class); + + protected static boolean canActionImage(UserInfo user, Permission checkPerm, + ImagePermissions... imagePermissions) { + for (ImagePermissions perm : imagePermissions) { + if (perm == null) + continue; + if (checkPerm == Permission.LINK) + return perm.link; + if (checkPerm == Permission.DOWNLOAD) + return perm.download; + if (checkPerm == Permission.EDIT) + return perm.edit; + if (checkPerm == Permission.ADMIN) + return perm.admin; + } + return false; + } + + protected static boolean canActionLecture(UserInfo user, Permission checkPerm, + LecturePermissions... lecturePermissions) { + if (checkPerm == Permission.DOWNLOAD || checkPerm == Permission.LINK) { + LOGGER.warn("Invalid permission check for lecture: " + checkPerm, new RuntimeException( + "Here's your stack trace")); + return false; + } + for (LecturePermissions perm : lecturePermissions) { + if (perm == null) + continue; + if (checkPerm == Permission.EDIT) + return perm.edit; + if (checkPerm == Permission.ADMIN) + return perm.admin; + } + return false; + } + + /** + * Check if the given user has the given permission for the image identified + * by the given image base id. + * + * @param user + * @param imageBaseId + * @param permission + * @throws TInternalServerError + * @throws TNotFoundException + */ + protected static boolean hasImageBasePermission(UserInfo user, String imageBaseId, Permission permission) + throws TInternalServerError, TNotFoundException { + // Check general permissions + ImageSummaryRead localImage; + try { + localImage = DbImage.getImageSummary(user, imageBaseId); + } catch (SQLException e) { + throw new TInternalServerError(); + } + // Owner has all permissions + if (localImage.ownerId.equals(user.userId)) + return true; + return canActionImage(user, permission, localImage.userPermissions, localImage.defaultPermissions) + || User.isSuperUser(user); + } + + /** + * Check if the given user has the given permission for the image identified + * by the given image base id. + * + * @param user + * @param imageBaseId + * @param permission + * @throws TAuthorizationException + * @throws TInternalServerError + * @throws TNotFoundException + */ + protected static void hasImageBasePermissionOrFail(UserInfo user, String imageBaseId, Permission permission) + throws TAuthorizationException, TInternalServerError, TNotFoundException { + if (!hasImageBasePermission(user, imageBaseId, permission)) { + throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, "Required permission: " + + permission.toString()); + } + } + + /** + * Check if the given user has the given permission for the image identified + * by the given image version id. + * + * @param user + * @param imageVersionId + * @param permission + * @throws TInternalServerError + * @throws TNotFoundException + */ + protected static boolean hasImageVersionPermission(UserInfo user, String imageVersionId, + Permission permission) throws TInternalServerError, TNotFoundException { + try { + String imageBaseId = DbImage.getBaseIdForVersionId(imageVersionId); + if (imageBaseId == null) + throw new TNotFoundException(); + return hasImageBasePermission(user, imageBaseId, permission); + } catch (SQLException e) { + throw new TInternalServerError(); + } + } + + /** + * Check if the given user has the given permission for the image identified + * by the given image version id. + * + * @param user + * @param imageVersionId + * @param permission + * @throws TAuthorizationException + * @throws TInternalServerError + * @throws TNotFoundException + */ + protected static void hasImageVersionPermissionOrFail(UserInfo user, String imageVersionId, + Permission permission) throws TAuthorizationException, TInternalServerError, TNotFoundException { + if (!hasImageVersionPermission(user, imageVersionId, permission)) { + throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, "Required image permission: " + + permission.toString()); + } + } + + protected static boolean hasLecturePermission(UserInfo user, String lectureId, Permission permission) + throws TInternalServerError, TNotFoundException { + // Check general permissions + LectureSummary lecture; + try { + lecture = DbLecture.getLectureSummary(user, lectureId); + } catch (SQLException e) { + throw new TInternalServerError(); + } + // Owner has all permissions + if (lecture.ownerId.equals(user.userId)) + return true; + return canActionLecture(user, permission, lecture.userPermissions, lecture.defaultPermissions) + || User.isSuperUser(user); + } + + protected static void hasLecturePermissionOrFail(UserInfo user, String lectureId, Permission permission) + throws TAuthorizationException, TInternalServerError, TNotFoundException { + if (!hasLecturePermission(user, lectureId, permission)) { + throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, + "Required lecture permission: " + permission.toString()); + } + } + + +} diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java index 2ffd281a..74c9a441 100644 --- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java +++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java @@ -1,121 +1,27 @@ package org.openslx.bwlp.sat.permissions; import java.sql.SQLException; -import java.util.Map; -import org.apache.log4j.Logger; import org.openslx.bwlp.sat.database.mappers.DbImage; -import org.openslx.bwlp.sat.database.mappers.DbLecture; import org.openslx.bwlp.sat.database.mappers.DbOrganization; -import org.openslx.bwlp.sat.database.mappers.DbUser; import org.openslx.bwlp.sat.database.models.LocalOrganization; import org.openslx.bwlp.sat.database.models.LocalUser; +import org.openslx.bwlp.sat.permissions.PermCheck.Permission; import org.openslx.bwlp.thrift.iface.AuthorizationError; -import org.openslx.bwlp.thrift.iface.ImagePermissions; -import org.openslx.bwlp.thrift.iface.ImageSummaryRead; -import org.openslx.bwlp.thrift.iface.LecturePermissions; -import org.openslx.bwlp.thrift.iface.LectureSummary; import org.openslx.bwlp.thrift.iface.Role; import org.openslx.bwlp.thrift.iface.TAuthorizationException; import org.openslx.bwlp.thrift.iface.TInternalServerError; import org.openslx.bwlp.thrift.iface.TNotFoundException; import org.openslx.bwlp.thrift.iface.UserInfo; -import org.openslx.util.TimeoutHashMap; public class User { - private static final Logger LOGGER = Logger.getLogger(User.class); - - public static enum Permission { - LINK, - DOWNLOAD, - EDIT, - ADMIN - } - - private static boolean canActionImage(UserInfo user, Permission checkPerm, - ImagePermissions... imagePermissions) { - for (ImagePermissions perm : imagePermissions) { - if (perm == null) - continue; - if (checkPerm == Permission.LINK) - return perm.link; - if (checkPerm == Permission.DOWNLOAD) - return perm.download; - if (checkPerm == Permission.EDIT) - return perm.edit; - if (checkPerm == Permission.ADMIN) - return perm.admin; - } - return false; - } - - private static boolean canActionLecture(UserInfo user, Permission checkPerm, - LecturePermissions... lecturePermissions) { - if (checkPerm == Permission.DOWNLOAD || checkPerm == Permission.LINK) { - LOGGER.warn("Invalid permission check for lecture: " + checkPerm, new RuntimeException( - "Here's your stack trace")); - return false; - } - for (LecturePermissions perm : lecturePermissions) { - if (perm == null) - continue; - if (checkPerm == Permission.EDIT) - return perm.edit; - if (checkPerm == Permission.ADMIN) - return perm.admin; - } - return false; - } - - /** - * Cache local user data, might be called quite often. - */ - private static final Map<String, LocalUser> localUserCache = new TimeoutHashMap<>(60000); - - private static LocalUser getLocalUser(UserInfo user) { - synchronized (localUserCache) { - LocalUser local = localUserCache.get(user.userId); - if (local != null) - return local; - } - LocalUser localData; - try { - localData = DbUser.getLocalData(user); - } catch (SQLException e) { - return null; - } - if (localData == null) - return null; - synchronized (localUserCache) { - localUserCache.put(user.userId, localData); - } - return localData; + public static boolean isTutor(UserInfo user) { + return user.role == Role.TUTOR; } - /** - * Cache local organization data, might be called quite often. - */ - private static final Map<String, LocalOrganization> localOrganizationCache = new TimeoutHashMap<>(60000); - - private static LocalOrganization getLocalOrganization(String organizationId) { - synchronized (localOrganizationCache) { - LocalOrganization local = localOrganizationCache.get(organizationId); - if (local != null) - return local; - } - LocalOrganization localData; - try { - localData = DbOrganization.getLocalData(organizationId); - } catch (SQLException e) { - return null; - } - if (localData == null) - return null; - synchronized (localOrganizationCache) { - localOrganizationCache.put(organizationId, localData); - } - return localData; + public static boolean isStudent(UserInfo user) { + return user.role == Role.STUDENT; } /** @@ -125,7 +31,7 @@ public class User { * @return */ public static boolean isSuperUser(UserInfo user) { - LocalUser localData = getLocalUser(user); + LocalUser localData = LocalData.getLocalUser(user); return localData != null && localData.isSuperUser; } @@ -136,10 +42,10 @@ public class User { * @return true if user is allowed to login to this satellite */ public static boolean canLogin(UserInfo user) { - LocalUser localData = getLocalUser(user); + LocalUser localData = LocalData.getLocalUser(user); if (localData != null) return localData.canLogin; // User locally known, use user-specific permission - LocalOrganization local = getLocalOrganization(user.organizationId); + LocalOrganization local = LocalData.getLocalOrganization(user.organizationId); // User unknown, check per-organization login permission if (local == null) return false; @@ -159,150 +65,146 @@ public class User { } /** - * Check if the given user has the given permission for the image identified - * by the given image base id. + * Checks whether the given user is allowed to create new images. + * Throws {@link TAuthorizationException} if permission is not granted. * - * @param user - * @param imageBaseId - * @param permission - * @throws TInternalServerError - * @throws TNotFoundException + * @param user {@link UserInfo} instance representing the user in question */ - public static boolean hasImageBasePermission(UserInfo user, String imageBaseId, Permission permission) - throws TInternalServerError, TNotFoundException { - // Students can download only, so return false right away if we're not checking for download - if (user.role == Role.STUDENT && permission != Permission.DOWNLOAD) - return false; - // Check general permissions - ImageSummaryRead localImage; - try { - localImage = DbImage.getImageSummary(user, imageBaseId); - } catch (SQLException e) { - throw new TInternalServerError(); - } - // Owner has all permissions - if (localImage.ownerId.equals(user.userId)) - return true; - return canActionImage(user, permission, localImage.userPermissions, localImage.defaultPermissions) - || isSuperUser(user); + public static void canCreateImageOrFail(UserInfo user) throws TAuthorizationException { + if (!isTutor(user)) + throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, + "No permission to create new image"); } /** - * Check if the given user has the given permission for the image identified - * by the given image base id. + * Is given user allowed to edit/update the image identified by the given + * image base id? Throws {@link TAuthorizationException} if permission is + * not granted. * * @param user * @param imageBaseId - * @param permission - * @throws TAuthorizationException - * @throws TInternalServerError * @throws TNotFoundException + * @throws TInternalServerError + * @throws TAuthorizationException */ - public static void hasImageBasePermissionOrFail(UserInfo user, String imageBaseId, Permission permission) - throws TAuthorizationException, TInternalServerError, TNotFoundException { - if (!hasImageBasePermission(user, imageBaseId, permission)) { - throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, "Required permission: " - + permission.toString()); + public static void canEditBaseImageOrFail(UserInfo user, String imageBaseId) throws TInternalServerError, + TNotFoundException, TAuthorizationException { + if (!isTutor(user) || !PermCheck.hasImageBasePermission(user, imageBaseId, Permission.EDIT)) { + throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, + "No permission to edit this image"); } } /** - * Check if the given user has the given permission for the image identified - * by the given image version id. + * Is given user allowed to edit/update the image identified by the given + * image version id? Throws {@link TAuthorizationException} if permission is + * not granted. * * @param user * @param imageVersionId - * @param permission - * @throws TInternalServerError * @throws TNotFoundException + * @throws TInternalServerError + * @throws TAuthorizationException */ - public static boolean hasImageVersionPermission(UserInfo user, String imageVersionId, - Permission permission) throws TInternalServerError, TNotFoundException { + public static void canEditImageVersionOrFail(UserInfo user, String imageVersionId) + throws TInternalServerError, TNotFoundException, TAuthorizationException { try { - String imageBaseId = DbImage.getBaseIdForVersionId(imageVersionId); - if (imageBaseId == null) - throw new TNotFoundException(); - return hasImageBasePermission(user, imageBaseId, permission); + canEditBaseImageOrFail(user, DbImage.getBaseIdForVersionId(imageVersionId)); } catch (SQLException e) { throw new TInternalServerError(); } } /** - * Check if the given user has the given permission for the image identified - * by the given image version id. + * Is given user allowed to delete the image identified by the given + * image version id? Throws {@link TAuthorizationException} if permission is + * not granted. * * @param user * @param imageVersionId - * @param permission * @throws TAuthorizationException - * @throws TInternalServerError * @throws TNotFoundException + * @throws TInternalServerError */ - public static void hasImageVersionPermissionOrFail(UserInfo user, String imageVersionId, - Permission permission) throws TAuthorizationException, TInternalServerError, TNotFoundException { - if (!hasImageVersionPermission(user, imageVersionId, permission)) { - throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, "Required image permission: " - + permission.toString()); - } + public static void canDeleteImageVersionOrFail(UserInfo user, String imageVersionId) + throws TInternalServerError, TNotFoundException, TAuthorizationException { + // Currently, editing an image also means we can delete it, but let's + // keep this a separate function in case we want to change it some time. + canEditImageVersionOrFail(user, imageVersionId); } - public static boolean hasLecturePermission(UserInfo user, String lectureId, Permission permission) - throws TInternalServerError, TNotFoundException { - if (user.role != Role.TUTOR) - return false; - // Check general permissions - LectureSummary lecture; - try { - lecture = DbLecture.getLectureSummary(user, lectureId); - } catch (SQLException e) { - throw new TInternalServerError(); - } - // Owner has all permissions - if (lecture.ownerId.equals(user.userId)) - return true; - return canActionLecture(user, permission, lecture.userPermissions, lecture.defaultPermissions) - || isSuperUser(user); + /** + * Checks whether the given user is allowed to create new lectures. + * Throws {@link TAuthorizationException} if permission is not granted. + * + * @param user {@link UserInfo} instance representing the user in question + */ + public static void canCreateLectureOrFail(UserInfo user) throws TAuthorizationException { + if (!isTutor(user)) + throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, + "No permission to create new lecture"); } - public static void hasLecturePermissionOrFail(UserInfo user, String lectureId, Permission permission) - throws TAuthorizationException, TInternalServerError, TNotFoundException { - if (!hasLecturePermission(user, lectureId, permission)) { - throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, - "Required lecture permission: " + permission.toString()); - } + /** + * Checks whether the given user can edit the image identified by the given + * image base id + * + * @param user + * @param imageBaseId + * @return + * @throws TInternalServerError + * @throws TNotFoundException + */ + public static boolean canEditImagePermissions(UserInfo user, String imageBaseId) + throws TInternalServerError, TNotFoundException { + return isTutor(user) && PermCheck.hasImageBasePermission(user, imageBaseId, Permission.ADMIN); } /** - * Checks whether the given user is allowed to create new images. + * Checks whether the given user can edit the image identified by the given + * image base id. + * Throws {@link TAuthorizationException} if permission is not granted. * - * @param user {@link UserInfo} instance representing the user in question - * @return true or false + * @param user + * @param imageBaseId + * @throws TInternalServerError + * @throws TNotFoundException */ - public static boolean canCreateImage(UserInfo user) { - return user.role == Role.TUTOR; + public static void canEditImagePermissionsOrFail(UserInfo user, String imageBaseId) + throws TAuthorizationException, TInternalServerError, TNotFoundException { + if (!canEditImagePermissions(user, imageBaseId)) + throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, + "No permission to edit this image's permissions"); } - public static void canCreateImageOrFail(UserInfo user) throws TAuthorizationException { - if (!canCreateImage(user)) + public static void canChangeImageOwnerOrFail(UserInfo user, String imageBaseId) + throws TAuthorizationException, TInternalServerError, TNotFoundException { + // TODO: Who should be allowed to change the owner? Any admin, or just the owner? + // Currently it's every admin, but this is open for discussion + if (!isTutor(user) || PermCheck.hasImageBasePermission(user, imageBaseId, Permission.ADMIN)) { throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, - "No permission to create new image"); + "No permission to change image owner"); + } } - /** - * Checks whether the given user is allowed to create new lectures. - * - * @param user {@link UserInfo} instance representing the user in question - * @return true or false - */ - public static boolean canCreateLecture(UserInfo user) { - return user.role == Role.TUTOR; + public static void canEditLectureOrFail(UserInfo user, String lectureId) throws TInternalServerError, + TNotFoundException, TAuthorizationException { + if (!isTutor(user) || !PermCheck.hasLecturePermission(user, lectureId, Permission.EDIT)) { + throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, + "No permission to edit this image"); + } } - public static void canCreateLectureOrFail(UserInfo user) throws TAuthorizationException { - if (!canCreateLecture(user)) + public static void canListImagesOrFail(UserInfo user) throws TAuthorizationException { + if (!isTutor(user)) throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, - "No permission to create new lecture"); + "No permission to see list of images"); + } + + public static void canSeeImageDetailsOrFail(UserInfo user) throws TAuthorizationException { + if (!isTutor(user)) + throw new TAuthorizationException(AuthorizationError.NO_PERMISSION, + "No permission to see list of images"); } } |