summaryrefslogblamecommitdiffstats
path: root/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbLecture.java
blob: c44d40ed98343ecd257c475c82b5d68de84037b7 (plain) (tree)
1
2
3
4
5
6
7



                                              
                           
                        
                      





                                                     
                                             
                                      
                                                         
                                                 

                                                    
                                             


                                                        

                                          



                                                                               

                                                                                                       


                                                                                    

































                                                                                              






                                                                                                              

                                                                                                                   

                                                                                                          
                                                                        

                                                                       
                                             







                                                                              











                                                                                                                              











                                                                                                              












                                                                                                                          
                 








                                                                                                                      
                                                                                       






                                                                                                                                         














                                                                                                     
                                                                       
                                       





                                                                                         





                                                                                                                                 
                                                                                         



























                                                                                                                                
                                                                                           
                                                                               






                                                                              

         











                                                                                                                                          



                                                                                                         



                                                                                                                                       
                                                                                         
                                                                                             









                                                                                                                                

                                                                                  











                                                                            


                                                                   



                                                                                                            



                                                                                                                  
                                                                                        


                                                                                                     
































                                                                                                                              
 








                                                                                  















                                                                                                               
                                                                                                                   
                                                                                                 



                                                                                                             
















                                                                                                                     
 
package org.openslx.bwlp.sat.database.mappers;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

import org.apache.log4j.Logger;
import org.openslx.bwlp.sat.database.Database;
import org.openslx.bwlp.sat.database.MysqlConnection;
import org.openslx.bwlp.sat.database.MysqlStatement;
import org.openslx.bwlp.sat.permissions.User;
import org.openslx.bwlp.sat.util.Json;
import org.openslx.bwlp.thrift.iface.ImageVersionDetails;
import org.openslx.bwlp.thrift.iface.LectureRead;
import org.openslx.bwlp.thrift.iface.LectureSummary;
import org.openslx.bwlp.thrift.iface.LectureWrite;
import org.openslx.bwlp.thrift.iface.NetRule;
import org.openslx.bwlp.thrift.iface.TNotFoundException;
import org.openslx.bwlp.thrift.iface.UserInfo;

import com.google.gson.JsonParseException;

public class DbLecture {

	private static final Logger LOGGER = Logger.getLogger(DbLecture.class);

	private static void setWriteFields(MysqlStatement stmt, String lectureId, LectureWrite lecture,
			UserInfo updatingUser) throws SQLException {
		if (lecture.lectureName.length() > 100) {
			lecture.lectureName = lecture.lectureName.substring(0, 100);
		}
		String nicsJson = null;
		if (lecture.nics != null && !lecture.nics.isEmpty()) {
			for (;;) {
				nicsJson = Json.serialize(lecture.nics);
				if (nicsJson.length() < 200)
					break;
				lecture.nics.remove(0);
			}
		}
		String netruleJson;
		if (lecture.networkExceptions == null) {
			netruleJson = null;
		} else {
			netruleJson = Json.serialize(lecture.networkExceptions);
		}
		stmt.setString("lectureid", lectureId);
		stmt.setString("displayname", lecture.lectureName);
		stmt.setString("description", lecture.description);
		stmt.setString("imageversionid", lecture.imageVersionId);
		stmt.setBoolean("autoupdate", lecture.autoUpdate);
		stmt.setBoolean("isenabled", lecture.isEnabled);
		stmt.setLong("starttime", lecture.startTime);
		stmt.setLong("endtime", lecture.endTime);
		stmt.setString("updaterid", updatingUser.userId);
		stmt.setString("runscript", lecture.runscript);
		stmt.setString("nics", nicsJson);
		stmt.setString("netrules", netruleJson);
		stmt.setBoolean("isexam", lecture.isExam);
		stmt.setBoolean("hasinternetaccess", lecture.hasInternetAccess);
		stmt.setBoolean("caneditdefault", lecture.defaultPermissions.edit);
		stmt.setBoolean("canadmindefault", lecture.defaultPermissions.admin);
	}

	public static String create(UserInfo user, LectureWrite lecture) throws SQLException {
		try (MysqlConnection connection = Database.getConnection()) {
			MysqlStatement stmt = connection.prepareStatement("INSERT INTO lecture"
					+ " (lectureid, displayname, description, imageversionid, autoupdate,"
					+ "  isenabled, starttime, endtime, createtime, updatetime,"
					+ "  ownerid, updaterid, runscript, nics, netrules, isexam,"
					+ "  hasinternetaccess, caneditdefault, canadmindefault)"
					+ "         VALUES             "
					+ " (:lectureid, :displayname, :description, :imageversionid, :autoupdate,"
					+ "  :isenabled, :starttime, :endtime, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(),"
					+ "  :ownerid, :updaterid, :runscript, :nics, :netrules, :isexam,"
					+ "  :hasinternetaccess, :caneditdefault, :canadmindefault)");
			String lectureId = UUID.randomUUID().toString();
			setWriteFields(stmt, lectureId, lecture, user);
			stmt.setString("ownerid", user.userId);
			stmt.executeUpdate();
			connection.commit();
			return lectureId;
		} catch (SQLException e) {
			LOGGER.error("Query failed in DbLecture.create()", e);
			throw e;
		}
	}

	private static void update(MysqlConnection connection, UserInfo user, String lectureId,
			LectureWrite lecture) throws SQLException {
		MysqlStatement stmt = connection.prepareStatement("UPDATE lecture SET "
				+ " displayname = :displayname, description = :description, imageversionid = :imageversionid,"
				+ " autoupdate = :autoupdate, isenabled = :isenabled, starttime = :starttime,"
				+ " endtime = :endtime, updatetime = UNIX_TIMESTAMP(),"
				+ " updaterid = :updaterid, runscript = :runscript, nics = :nics,"
				+ " netrules = :netrules, isexam = :isexam, hasinternetaccess = :hasinternetaccess,"
				+ " caneditdefault = :caneditdefault, canadmindefault = :canadmindefault"
				+ " WHERE lectureid = :lectureid");
		setWriteFields(stmt, lectureId, lecture, user);
		stmt.executeUpdate();
	}

	public static void update(UserInfo user, String lectureId, LectureWrite lecture) throws SQLException {
		try (MysqlConnection connection = Database.getConnection()) {
			update(connection, user, lectureId, lecture);
			connection.commit();
		} catch (SQLException e) {
			LOGGER.error("Query failed in DbLecture.update()", e);
			throw e;
		}
	}

	public static void setOwner(UserInfo user, String lectureId, String newOwnerId) throws SQLException {
		try (MysqlConnection connection = Database.getConnection()) {
			MysqlStatement stmt = connection.prepareStatement("UPDATE lecture"
					+ " SET ownerid = :ownerid, updaterid = :updaterid, updatetime = UNIX_TIMESTAMP()"
					+ " WHERE lectureid = :lectureid");
			stmt.setString("ownerid", newOwnerId);
			stmt.setString("updaterid", user.userId);
			stmt.setString("lectureid", lectureId);
			stmt.executeUpdate();
			connection.commit();
		} catch (SQLException e) {
			LOGGER.error("Query failed in DbLecture.setOwner()", e);
			throw e;
		}
	}

	public static LectureSummary getLectureSummary(UserInfo user, String lectureId) throws SQLException,
			TNotFoundException {
		try (MysqlConnection connection = Database.getConnection()) {
			MysqlStatement stmt = connection.prepareStatement("SELECT"
					+ " l.lectureid, l.displayname AS lecturename, l.imageversionid, l.isenabled,"
					+ " l.starttime, l.endtime, l.lastused, l.usecount, l.ownerid, l.updaterid,"
					+ " l.isexam, l.hasinternetaccess, l.caneditdefault, l.canadmindefault,"
					+ " perm.canedit, perm.canadmin FROM lecture l"
					+ " LEFT JOIN lecturepermission perm ON (perm.lectureid = l.lectureid AND perm.userid = :userid)"
					+ " WHERE lectureid = :lectureid");
			stmt.setString("lectureid", lectureId);
			stmt.setString("userid", user.userId);
			ResultSet rs = stmt.executeQuery();
			if (!rs.next())
				throw new TNotFoundException();
			LectureSummary lecture = new LectureSummary();
			lecture.setLectureId(rs.getString("lectureid"));
			lecture.setLectureName(rs.getString("lecturename"));
			lecture.setImageVersionId(rs.getString("imageversionid"));
			lecture.setIsEnabled(rs.getBoolean("isenabled"));
			lecture.setStartTime(rs.getLong("starttime"));
			lecture.setEndTime(rs.getLong("endtime"));
			lecture.setLastUsed(rs.getLong("lastused"));
			lecture.setUseCount(rs.getInt("usecount"));
			lecture.setOwnerId(rs.getString("ownerid"));
			lecture.setUpdaterId(rs.getString("updaterid"));
			lecture.setIsExam(rs.getBoolean("isexam"));
			lecture.setHasInternetAccess(rs.getBoolean("hasinternetaccess"));
			lecture.setDefaultPermissions(DbLecturePermissions.fromResultSetDefault(rs));
			lecture.setUserPermissions(DbLecturePermissions.fromResultSetUser(rs));
			User.setCombinedUserPermissions(lecture, user);
			return lecture;
		} catch (SQLException e) {
			LOGGER.error("Query failed in DbLecture.getLectureSummary()", e);
			throw e;
		}
	}

	public static List<LectureSummary> getAll(UserInfo user, int page) throws SQLException {
		try (MysqlConnection connection = Database.getConnection()) {
			MysqlStatement stmt = connection.prepareStatement("SELECT"
					+ " l.lectureid, l.displayname AS lecturename, l.imageversionid, i.imagebaseid,"
					+ " l.isenabled, l.starttime, l.endtime, l.lastused, l.usecount, l.ownerid, l.updaterid,"
					+ " l.isexam, l.hasinternetaccess, l.caneditdefault, l.canadmindefault,"
					+ " i.isvalid AS imgvalid, p.canedit, p.canadmin"
					+ "               FROM lecture l                      "
					+ " INNER JOIN imageversion i USING (imageversionid)"
					+ " LEFT JOIN lecturepermission p ON (p.lectureid = l.lectureid AND p.userid = :userid)"
					+ (User.isStudent(user) ? " WHERE i.isrestricted = 0" : ""));
			if (user == null) {
				stmt.setString("userid", "-");
			} else {
				stmt.setString("userid", user.userId);
			}
			ResultSet rs = stmt.executeQuery();
			List<LectureSummary> list = new ArrayList<>(100);
			while (rs.next()) {
				LectureSummary lecture = new LectureSummary();
				lecture.setLectureId(rs.getString("lectureid"));
				lecture.setLectureName(rs.getString("lecturename"));
				lecture.setImageVersionId(rs.getString("imageversionid"));
				lecture.setImageBaseId(rs.getString("imagebaseid"));
				lecture.setIsEnabled(rs.getBoolean("isenabled"));
				lecture.setStartTime(rs.getLong("starttime"));
				lecture.setEndTime(rs.getLong("endtime"));
				lecture.setLastUsed(rs.getLong("lastused"));
				lecture.setUseCount(rs.getInt("usecount"));
				lecture.setOwnerId(rs.getString("ownerid"));
				lecture.setUpdaterId(rs.getString("updaterid"));
				lecture.setIsExam(rs.getBoolean("isexam"));
				lecture.setHasInternetAccess(rs.getBoolean("hasinternetaccess"));
				lecture.setDefaultPermissions(DbLecturePermissions.fromResultSetDefault(rs));
				lecture.setUserPermissions(DbLecturePermissions.fromResultSetUser(rs));
				lecture.setIsImageVersionUsable(rs.getBoolean("imgvalid"));
				User.setCombinedUserPermissions(lecture, user);
				list.add(lecture);
			}
			return list;
		} catch (SQLException e) {
			LOGGER.error("Query failed in DbLecture.getAll()", e);
			throw e;
		}
	}

	protected static List<String> getAllUsingImageVersion(MysqlConnection connection, String imageVersionId)
			throws SQLException {
		MysqlStatement stmt = connection.prepareStatement("SELECT lectureid FROM lecture WHERE imageversionid = :imageversionid");
		stmt.setString("imageversionid", imageVersionId);
		ResultSet rs = stmt.executeQuery();
		List<String> list = new ArrayList<>();
		while (rs.next()) {
			list.add(rs.getString("lectureid"));
		}
		return list;
	}

	public static LectureRead getLectureDetails(UserInfo user, String lectureId) throws SQLException,
			TNotFoundException {
		try (MysqlConnection connection = Database.getConnection()) {
			MysqlStatement stmt = connection.prepareStatement("SELECT"
					+ " l.lectureid, l.displayname AS lecturename, l.description, l.imageversionid, i.imagebaseid,"
					+ " l.autoupdate, l.isenabled, l.starttime, l.endtime, l.lastused, l.usecount, l.createtime,"
					+ " l.updatetime, l.ownerid, l.updaterid, l.runscript, l.nics, l.netrules, l.isexam,"
					+ " l.hasinternetaccess, l.caneditdefault, l.canadmindefault, p.canedit, p.canadmin"
					+ "                   FROM lecture l            "
					+ " INNER JOIN imageversion i USING (imageversionid)"
					+ " LEFT JOIN lecturepermission p ON (l.lectureid = p.lectureid AND p.userid = :userid)"
					+ " WHERE l.lectureid = :lectureid LIMIT 1");
			stmt.setString("userid", user.userId);
			stmt.setString("lectureid", lectureId);
			ResultSet rs = stmt.executeQuery();
			if (!rs.next())
				throw new TNotFoundException();
			LectureRead lecture = new LectureRead();
			lecture.setLectureId(rs.getString("lectureid"));
			lecture.setLectureName(rs.getString("lecturename"));
			lecture.setImageBaseId(rs.getString("imagebaseid"));
			lecture.setImageVersionId(rs.getString("imageversionid"));
			lecture.setDescription(rs.getString("description"));
			lecture.setAutoUpdate(rs.getBoolean("autoupdate"));
			lecture.setIsEnabled(rs.getBoolean("isenabled"));
			lecture.setStartTime(rs.getLong("starttime"));
			lecture.setEndTime(rs.getLong("endtime"));
			lecture.setLastUsed(rs.getLong("lastused"));
			lecture.setUseCount(rs.getInt("usecount"));
			lecture.setCreateTime(rs.getLong("createtime"));
			lecture.setUpdateTime(rs.getLong("updatetime"));
			lecture.setOwnerId(rs.getString("ownerid"));
			lecture.setUpdaterId(rs.getString("updaterid"));
			lecture.setRunscript(rs.getString("runscript"));
			String netrules = rs.getString("netrules");
			if (netrules != null) {
				try {
					NetRule[] rules = Json.deserializeThrift(netrules, NetRule[].class);
					if (rules != null) {
						lecture.setNetworkExceptions(Arrays.asList(rules));
					}
				} catch (JsonParseException e) {
					LOGGER.warn("Could not deserialize netrules for lecture " + lectureId, e);
				}
			}
			lecture.setAllowedUsers(getAllowedUsers(connection, lectureId));
			lecture.setDefaultPermissions(DbLecturePermissions.fromResultSetDefault(rs));
			lecture.setUserPermissions(DbLecturePermissions.fromResultSetUser(rs));
			User.setCombinedUserPermissions(lecture, user);
			return lecture;
		} catch (SQLException e) {
			LOGGER.error("Query failed in DbLecture.getLectureDetails()", e);
			throw e;
		}
	}

	public static List<String> getAllowedUsers(MysqlConnection connection, String lectureId)
			throws SQLException {
		MysqlStatement stmt = connection.prepareStatement("SELECT" + " userlogin FROM lectureuser"
				+ " WHERE lectureid = :lectureid");
		stmt.setString("lectureid", lectureId);
		ResultSet rs = stmt.executeQuery();
		List<String> list = new ArrayList<>();
		while (rs.next()) {
			list.add(rs.getString("userlogin"));
		}
		return list;
	}

	public static boolean delete(String lectureId) throws TNotFoundException, SQLException {
		int affected;
		try (MysqlConnection connection = Database.getConnection()) {
			MysqlStatement stmt = connection.prepareStatement("DELETE FROM lecture WHERE lectureid = :lectureid");
			stmt.setString("lectureid", lectureId);
			affected = stmt.executeUpdate();
			connection.commit();
		} catch (SQLException e) {
			LOGGER.error("Query failed in DbLecture.delete()", e);
			throw e;
		}
		return affected == 1;
	}

	/**
	 * Called when a new version for an image is uploaded. Update all lectures
	 * using the same base image which have the autoUpdate-flag set.
	 * 
	 * @param connection
	 * @param imageBaseId
	 * @param imageVersionId
	 * @throws SQLException
	 */
	protected static void autoUpdateUsedImage(MysqlConnection connection, String imageBaseId,
			String imageVersionId) throws SQLException {
		// TODO: select first so we can email
		MysqlStatement stmt = connection.prepareStatement("UPDATE lecture l, imageversion v SET"
				+ " l.imageversionid = :imageversionid"
				+ " WHERE v.imageversionid = l.imageversionid AND v.imagebaseid = :imagebaseid"
				+ " AND l.autoupdate = 1");
		stmt.setString("imageversionid", imageVersionId);
		stmt.setString("imagebaseid", imageBaseId);
		stmt.executeUpdate();
	}

	/**
	 * Called when an image version is deleted or marked for deletion, so that
	 * linking lectures switch over to other available versions.
	 */
	protected static void forcefullySwitchUsedImage(MysqlConnection connection, ImageVersionDetails oldVersion,
			ImageVersionDetails newVersion) throws TNotFoundException, SQLException {
		if (oldVersion == newVersion
				|| (newVersion != null && newVersion.versionId.equals(oldVersion.versionId)))
			return;
		// First, get list of lectures using the image version to switch away from
		List<String> lectures = getAllUsingImageVersion(connection, oldVersion.versionId);
		if (lectures.isEmpty())
			return;
		// TODO: If there is no new candidate to switch to, send a warning via mail
		if (newVersion == null) {
			// ... email stuff
			return;
		}
		// Update and send info mail
		MysqlStatement stmt = connection.prepareStatement("UPDATE lecture SET imageversionid = :newversionid"
				+ " WHERE imageversionid = :oldversionid");
		stmt.setString("oldversionid", oldVersion.versionId);
		stmt.setString("newversionid", newVersion.versionId);
		stmt.executeUpdate();
		// TODO: Send mails .. Something.sendLectureChangeNotify(lectures, oldVersion, newVersion);
	}

}