summaryrefslogblamecommitdiffstats
path: root/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/permissions/User.java
blob: abea5433bcd3a345b17227f23781d86a25915239 (plain) (tree)
1
2
3
4
5
6
7
8
9




                                                     
                                                       
                                                            

                                                              
                                                          
                                           
                                                        
                                                      

                                                      
                                                         


                                                        
                                          
                                               
                                                             
                                                          




                                                        





                                                                                                      
                                                      
                                                               

         
                                                        
                                                                 








                                                          
                                                                   






                                                                     
                                                                                
           
                                                                  
                                                                   




                                                                                                
                                                                        

                                                                                              
                                                                       

                                                         
                                    




                                                                                               
                                            

                                                                                 



                                          
                                                        
         
 
           

                                                                               
           
                                                                                  
           



                                                                                               


           


                                                                                 


                             
                                     
                                       
                                          
           
                                                                                                                 
                                                                     

                                                                               

                                                                                           



                 


                                                                                    


                                
                                     
                                       
                                          
           
                                                                                          
                                                                                                  
                     
                                                                                                    
                                          
                                                         
                 


           


                                                                                    


                                
                                          
                                     
                                       
           
                                                                                            
                                                                                                  



                                                                                                                    
                                                         
                 






                                                                                                             

                                                       
                               





                                                                                                                       


                                                                                   

         







                                                                                                               
                                                                                                                  
                                                                                                  

                                       



                                                                                            
                                          
                                                         
                 

                                                     
                                       









                                                                                                      









                                                                                                 

         
           

                                                                                  



                             
                                       


                                                                                        
                                                                         

                                                                               

         
           

                                                                                  
           

                             
                                       
                                     
                                                                        
           
                                                                                           
                                                                                                  


                                                                                           

         
                                                                                       
                                                                                                  

                                                                                                 

                                                                               
                                                                                           

                                                                               

         
                                                                                                             
                                                                     




                                                                                      
                                                    


                                                                                           

         
                                                                                        
                                                                         




                                                                                           
                                                                                                  





                                                                                           
                                                                                             
                                                                                                  

                                                                                                 





                                                                                           

                                                                                                                
                                           







                                                                                           



                                                                                           
                                                                                              
                                         
                                                                                           





                                                                                                   









                                                                                                     
                                                                                                  

                                                                           


                                                                                           

         





                                                                                                         








                                                                                                                            




















                                                                                                                                           

















                                                                                                  











                                                                                           
                                                                                                      













                                                                                              
                                                                                                      

         





























                                                                                                                

                                                                                



                                 















                                                                                               
                                                                         


                                                                          
                                                         


                 








                                                                                                            
                                                                                       
                                                                         


                                                                            
                                                         

                 
 
package org.openslx.bwlp.sat.permissions;

import java.sql.SQLException;

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.models.LocalOrganization;
import org.openslx.bwlp.sat.database.models.LocalUser;
import org.openslx.bwlp.sat.thrift.cache.OrganizationList;
import org.openslx.bwlp.sat.util.Sanitizer;
import org.openslx.bwlp.thrift.iface.AuthorizationError;
import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
import org.openslx.bwlp.thrift.iface.ImagePermissions;
import org.openslx.bwlp.thrift.iface.ImageSummaryRead;
import org.openslx.bwlp.thrift.iface.ImageVersionDetails;
import org.openslx.bwlp.thrift.iface.LecturePermissions;
import org.openslx.bwlp.thrift.iface.LectureRead;
import org.openslx.bwlp.thrift.iface.LectureSummary;
import org.openslx.bwlp.thrift.iface.Role;
import org.openslx.bwlp.thrift.iface.ShareMode;
import org.openslx.bwlp.thrift.iface.TAuthorizationException;
import org.openslx.bwlp.thrift.iface.TInvocationException;
import org.openslx.bwlp.thrift.iface.TNotFoundException;
import org.openslx.bwlp.thrift.iface.UserInfo;

public class User {

	private static final ImagePermissions imageSu = new ImagePermissions(true, true, true, true);

	private static final LecturePermissions lectureSu = new LecturePermissions(true, true);

	private static final LecturePermissions lectureNothing = new LecturePermissions(false, false);

	public static boolean isTutor(UserInfo user) {
		return user != null && user.role == Role.TUTOR;
	}

	public static boolean isStudent(UserInfo user) {
		return user != null && user.role == Role.STUDENT;
	}

	/**
	 * Check if given user is a local super user.
	 * 
	 * @param user
	 * @return
	 */
	public static boolean isSuperUser(UserInfo user) {
		LocalUser localData = LocalData.getLocalUser(user);
		return localData != null && localData.isSuperUser;
	}

	/**
	 * Check if given user is allowed to login to this satellite.
	 * 
	 * @param user user to check login permission for
	 * @return null if user is allowed, {@link AuthorizationError} otherwise
	 */
	public static AuthorizationError canLogin(UserInfo user) {
		LocalUser localData = LocalData.getLocalUser(user);
		if (localData != null) {
			if (localData.canLogin)
				return null; // User locally known, use user-specific permission
			return AuthorizationError.ACCOUNT_SUSPENDED;
		}
		// User unknown, check per-organization login permission
		LocalOrganization local = LocalData.getLocalOrganization(user.organizationId);
		if (local == null && OrganizationList.find(user.organizationId) == null)
			return AuthorizationError.INVALID_ORGANIZATION;
		// Organization known an allowed to login
		if (local != null && local.canLogin)
			return null;
		// Special case: If user is not allowed to login, check if there are no allowed
		// organizations yet. If so, automatically allow the organization of this user.
		try {
			if (DbOrganization.getLoginAllowedOrganizations().isEmpty()) {
				DbOrganization.setCanLogin(user.organizationId, true);
				return null;
			} else {
				return AuthorizationError.ORGANIZATION_SUSPENDED;
			}
		} catch (SQLException e) {
			// Ignore
		}
		return AuthorizationError.GENERIC_ERROR;
	}

	/**
	 * Checks whether the given user is allowed to create new images.
	 * Throws {@link TAuthorizationException} if permission is not granted.
	 * 
	 * @param user {@link UserInfo} instance representing the user in question
	 */
	public static void canCreateImageOrFail(UserInfo user) throws TAuthorizationException {
		if (!isTutor(user))
			throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
					"No permission to create new image");
	}

	/**
	 * 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
	 * @throws TNotFoundException
	 * @throws TInvocationException
	 * @throws TAuthorizationException
	 */
	public static void canEditBaseImageOrFail(UserInfo user, String imageBaseId) throws TInvocationException,
			TNotFoundException, TAuthorizationException {
		ImageSummaryRead image = getImageFromBaseId(user, imageBaseId);
		if (!image.userPermissions.edit) {
			throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
					"No permission to edit this image");
		}
	}

	/**
	 * 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
	 * @throws TNotFoundException
	 * @throws TInvocationException
	 * @throws TAuthorizationException
	 */
	public static void canEditImageVersionOrFail(UserInfo user, String imageVersionId)
			throws TInvocationException, TNotFoundException, TAuthorizationException {
		try {
			canEditBaseImageOrFail(user, DbImage.getBaseIdForVersionId(imageVersionId));
		} catch (SQLException e) {
			throw new TInvocationException();
		}
	}

	/**
	 * 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
	 * @throws TAuthorizationException
	 * @throws TNotFoundException
	 * @throws TInvocationException
	 */
	public static void canDeleteImageVersionOrFail(UserInfo user, String imageVersionId)
			throws TInvocationException, TNotFoundException, TAuthorizationException {
		ImageDetailsRead imageDetails;
		try {
			imageDetails = DbImage.getImageDetails(user, DbImage.getBaseIdForVersionId(imageVersionId));
		} catch (SQLException e) {
			throw new TInvocationException();
		}
		// Do not allow deleting remote images if share mode is set to "auto download" and
		// the version to delete is the latest
		if (imageDetails.shareMode == ShareMode.DOWNLOAD
				&& imageDetails.latestVersionId.equals(imageVersionId)) {
			throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
					"Cannot delete latest version of image if auto-download is enabled");
		}
		// Check user permissions
		if (imageDetails.userPermissions.admin)
			return;
		// User uploaded the image version in question and has edit permissions - allow
		if (imageDetails.userPermissions.edit) {
			for (ImageVersionDetails version : imageDetails.versions) {
				if (version.versionId.equals(imageVersionId) && version.uploaderId.equals(user.userId))
					return;
			}
		}
		throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
				"No permission to delete this image version");
	}

	public static void canDeleteImageOrFail(ImageDetailsRead imageDetails) throws TAuthorizationException {
		// Check user permissions
		if (imageDetails.userPermissions.admin)
			return;
		throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
				"No permission to delete this image");
	}

	public static void canDownloadImageVersionOrFail(UserInfo user, String imageBaseId, String imageVersionId)
			throws TAuthorizationException, TNotFoundException, TInvocationException {
		ImageDetailsRead image;
		try {
			if (imageBaseId == null) {
				imageBaseId = DbImage.getBaseIdForVersionId(imageVersionId);
			}
			image = DbImage.getImageDetails(user, imageBaseId);
		} catch (SQLException e) {
			throw new TInvocationException();
		}
		if (image.userPermissions.download) {
			if (isTutor(user))
				return;
			// User is unknown role or student, check version's restricted flag
			for (ImageVersionDetails version : image.versions) {
				if (!version.isRestricted && version.versionId.equals(imageVersionId))
					return;
			}
		}
		throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
				"No permission to download this image version");
	}

	/**
	 * 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");
	}

	/**
	 * Checks whether the given user can edit the permission list of the image
	 * identified by the given image base id.
	 * 
	 * @param user
	 * @param imageBaseId
	 * @return
	 * @throws TInvocationException
	 * @throws TNotFoundException
	 */
	public static boolean canEditImagePermissions(UserInfo user, String imageBaseId)
			throws TInvocationException, TNotFoundException {
		ImageSummaryRead image = getImageFromBaseId(user, imageBaseId);
		return image.userPermissions.admin;
	}

	/**
	 * Checks whether the given user can edit the permission list of the image
	 * identified by the given image base id.
	 * 
	 * @param user
	 * @param imageBaseId
	 * @throws TInvocationException
	 * @throws TNotFoundException
	 * @throws TAuthorizationException if permission is not granted.
	 */
	public static void canEditImagePermissionsOrFail(UserInfo user, String imageBaseId)
			throws TAuthorizationException, TInvocationException, TNotFoundException {
		if (!canEditImagePermissions(user, imageBaseId))
			throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
					"No permission to edit this image's permissions");
	}

	public static void canChangeImageOwnerOrFail(UserInfo user, String imageBaseId)
			throws TAuthorizationException, TInvocationException, 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
		ImageSummaryRead image = getImageFromBaseId(user, imageBaseId);
		if (!image.userPermissions.admin) {
			throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
					"No permission to change image owner");
		}
	}

	public static void canEditLectureOrFail(UserInfo user, String lectureId) throws TInvocationException,
			TNotFoundException, TAuthorizationException {
		canEditLectureOrFail(user, getLectureFromId(user, lectureId));
	}

	public static void canEditLectureOrFail(UserInfo user, LectureSummary lecture)
			throws TAuthorizationException {
		if (!lecture.userPermissions.edit) {
			throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
					"No permission to edit this image");
		}
	}

	public static boolean canEditLecturePermissions(UserInfo user, String lectureId)
			throws TNotFoundException, TInvocationException {
		LectureSummary lecture = getLectureFromId(user, lectureId);
		return lecture.userPermissions.admin;
	}

	public static void canEditLecturePermissionsOrFail(UserInfo user, String lectureId)
			throws TAuthorizationException, TNotFoundException, TInvocationException {
		if (!canEditLecturePermissions(user, lectureId)) {
			throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
					"No permission to edit permissions");
		}
	}

	public static void canChangeLectureOwnerOrFail(UserInfo user, LectureSummary lecture)
			throws TAuthorizationException, TNotFoundException, TInvocationException {
		// 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 (!lecture.userPermissions.admin) {
			throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
					"No permission to change lecture owner");
		}
	}

	public static void canLinkToImageOrFail(UserInfo user, String imageVersionId) throws TNotFoundException,
			TInvocationException, TAuthorizationException {
		if (imageVersionId == null)
			return;
		ImageSummaryRead image = getImageFromVersionId(user, imageVersionId);
		if (!image.userPermissions.link) {
			throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
					"No permission to link to this image");
		}
	}

	public static boolean canListImages(UserInfo user) throws TAuthorizationException {
		return isTutor(user);
	}

	public static void canListImagesOrFail(UserInfo user) throws TAuthorizationException {
		if (!canListImages(user))
			throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
					"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 image details");
	}

	public static void canSeeLectureDetailsOrFail(UserInfo user) throws TAuthorizationException {
		if (!isTutor(user))
			throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
					"No permission to see lecture details");
	}

	public static void canDeleteLectureOrFail(UserInfo user, String lectureId)
			throws TAuthorizationException, TInvocationException, TNotFoundException {
		LectureSummary lecture = getLectureFromId(user, lectureId);
		if (!lecture.userPermissions.admin) {
			throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
					"No permission to delete this lecture");
		}
	}

	public static void canChangeImageExpireDateOrFail(UserInfo user) throws TAuthorizationException {
		if (!isSuperUser(user))
			throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
					"Only the super user can change the expire date of images");
	}

	public static void canUploadToMasterOrFail(UserInfo user, ImageSummaryRead imgBase) throws TAuthorizationException {
		if (isSuperUser(user))
			return;
		if (imgBase.userPermissions.admin)
			return;
		throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
				"You need to be image admin to upload to master server");
	}

	public static void canTriggerReplicationOrFail(UserInfo user, String imageVersionId)
			throws TAuthorizationException, TInvocationException {
		if (isTutor(user)) {
			ImageSummaryRead image;
			try {
				image = getImageFromVersionId(user, imageVersionId);
			} catch (TNotFoundException e) {
				// If the image is not known locally, allow replication
				return;
			}
			// If it's a remote image, or if the user has edit permissions, allow
			if (image.shareMode == ShareMode.DOWNLOAD || image.shareMode == ShareMode.FROZEN
					|| image.userPermissions.edit)
				return;
			throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
					"You cannot trigger downloading an image to the satellite server that is not in replication mode");
		}
		throw new TAuthorizationException(AuthorizationError.NO_PERMISSION,
				"Only tutors can trigger image replication");
	}

	public static void setCombinedUserPermissions(ImageSummaryRead image, UserInfo user) {
		if (hasAllImagePermissions(user, image.ownerId)) {
			image.userPermissions = imageSu;
			return;
		}
		image.userPermissions = calculateUserImagePermissions(user, image.userPermissions,
				image.defaultPermissions);
	}

	public static void setCombinedUserPermissions(ImageDetailsRead image, UserInfo user) {
		if (hasAllImagePermissions(user, image.ownerId)) {
			image.userPermissions = imageSu;
			return;
		}
		image.userPermissions = calculateUserImagePermissions(user, image.userPermissions,
				image.defaultPermissions);
	}

	public static void setCombinedUserPermissions(LectureRead lecture, UserInfo user) {
		if (user == null || user.role == Role.STUDENT) {
			lecture.userPermissions = lectureNothing;
			return;
		}
		if (hasAllLecturePermissions(user, lecture.ownerId)) {
			lecture.userPermissions = lectureSu;
			return;
		}
		if (lecture.userPermissions == null) {
			lecture.userPermissions = lecture.defaultPermissions;
		}
		lecture.userPermissions = Sanitizer.handleLecturePermissions(lecture.userPermissions);
	}

	public static void setCombinedUserPermissions(LectureSummary lecture, UserInfo user) {
		if (user == null || user.role == Role.STUDENT) {
			lecture.userPermissions = lectureNothing;
			return;
		}
		if (hasAllLecturePermissions(user, lecture.ownerId)) {
			lecture.userPermissions = lectureSu;
			return;
		}
		if (lecture.userPermissions == null) {
			lecture.userPermissions = lecture.defaultPermissions;
		}
		lecture.userPermissions = Sanitizer.handleLecturePermissions(lecture.userPermissions);
	}

	private static boolean hasAllImagePermissions(UserInfo user, String imageOwnerId) {
		if (user != null && user.role == Role.TUTOR) {
			// Check for owner
			if (user.userId.equals(imageOwnerId)) {
				return true;
			}
			// Check for super user
			LocalUser localUser = LocalData.getLocalUser(user);
			if (localUser != null && localUser.isSuperUser) {
				return true;
			}
		}
		return false;
	}

	private static ImagePermissions calculateUserImagePermissions(UserInfo user, ImagePermissions userPerms,
			ImagePermissions defPerms) {
		// Standard combining logic
		if (userPerms == null)
			userPerms = defPerms;
		// Reduce student's permissions to be safe
		if (user == null || user.role == Role.STUDENT) {
			if (userPerms.link || userPerms.admin || userPerms.edit) {
				if (userPerms == defPerms) {
					userPerms = new ImagePermissions(defPerms);
				}
				userPerms.link = false;
				userPerms.edit = false;
				userPerms.admin = false;
			}
		} else {
			userPerms = Sanitizer.handleImagePermissions(userPerms);
		}
		return userPerms;
	}

	private static boolean hasAllLecturePermissions(UserInfo user, String lectureOwnerId) {
		if (user != null && user.role == Role.TUTOR) {
			// Check for owner
			if (user.userId.equals(lectureOwnerId)) {
				return true;
			}
			// Check for super user
			LocalUser localUser = LocalData.getLocalUser(user);
			if (localUser != null && localUser.isSuperUser) {
				return true;
			}
		}
		return false;
	}

	private static ImageSummaryRead getImageFromBaseId(UserInfo user, String imageBaseId)
			throws TNotFoundException, TInvocationException {
		try {
			return DbImage.getImageSummary(user, imageBaseId);
		} catch (SQLException e) {
			throw new TInvocationException();
		}
	}

	private static ImageSummaryRead getImageFromVersionId(UserInfo user, String imageVersionId)
			throws TNotFoundException, TInvocationException {
		try {
			return DbImage.getImageSummary(user, DbImage.getBaseIdForVersionId(imageVersionId));
		} catch (SQLException e) {
			throw new TInvocationException();
		}
	}

	private static LectureSummary getLectureFromId(UserInfo user, String lectureId)
			throws TNotFoundException, TInvocationException {
		try {
			return DbLecture.getLectureSummary(user, lectureId);
		} catch (SQLException e) {
			throw new TInvocationException();
		}
	}
}