/* This file is part of OpenMyEWB. OpenMyEWB is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenMyEWB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenMyEWB. If not, see <http://www.gnu.org/licenses/>. OpenMyEWB is Copyright 2005-2009 Nicolas Kruchten (nicolas@kruchten.com), Francis Kung, Engineers Without Borders Canada, Michael Trauttmansdorff, Jon Fishbein, David Kadish */ package ca.myewb.frame; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.Vector; import org.apache.log4j.Logger; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import ca.myewb.logic.GroupLogic; import ca.myewb.logic.PageLogic; import ca.myewb.logic.UserLogic; import ca.myewb.model.EventModel; import ca.myewb.model.GroupChapterModel; import ca.myewb.model.GroupModel; import ca.myewb.model.PageModel; import ca.myewb.model.PostModel; import ca.myewb.model.UserModel; import ca.myewb.model.WhiteboardModel; public class Permissions { // Constructor so that Permissions can be added to Helpers Static Class public Permissions() { } public static boolean canManageSubdomainEmails(UserModel user, UserModel targetUser) { if(!targetUser.isMember("Chapter")) { return false; //subdomain is user's chapter } if(user.isAdmin()) { return true; //of course } if(user.isMember("Exec")) { //must be in the same chapter return targetUser.getChapter().equals(user.getChapter()); } return false; } /*** GROUPS ***/ // View list details such as size, description, etc. and public static boolean canReadGroupInfo( UserModel u, GroupModel g ) { return postsCanBeSeenBy(u,g); } // Update group names, descriptions, etc. and contact info for chapters public static boolean canUpdateGroupInfo( UserModel u, GroupModel g ) { return canControlGroup(u, g) && g.getVisible() && !g.isExecList() && !g.getAdmin(); } // View list membership spreadsheets and update member status (member/leader/sender and regular/associate) public static boolean canAdministerGroupMembership( UserModel u, GroupModel g ) { return canControlGroup(u, g) && g.getVisible() && !g.getAdmin(); } // Delete chapters or groups public static boolean canDeleteGroup( UserModel u, GroupModel g ) { return canControlGroup(u, g) && !g.isChapter() && !g.isExecList() && !g.getAdmin() && g.getVisible(); } /*** USERS ***/ // View contact info, work/student info, etc. public static boolean canReadPersonalDetails( UserModel u, UserModel target ) { return canControlUser(u, target); } // Upgrade/downgrade user, Edit exec/NMT titles (as long as 'u' has permission to change exec/NMT titles) public static boolean canUpdateUserStatus( UserModel u, UserModel target ) { return canControlUser(u, target); } /*** POSTS IN A GROUP ***/ // Create new posts for a group public static boolean canPostToGroup( UserModel u, GroupModel g ) { return (u.isAdmin() && g.getVisible()) || postGroups(u).contains(g); } // Send emails to a group public static boolean canSendEmailToGroup( UserModel u, GroupModel g ) { return (canControlGroup(u, g) || u.isSender(g)) && g.getVisible() && g.getId() != 1; } // Read the posts in a group public static boolean canReadPostsInGroup( UserModel u, GroupModel g ) { return postsCanBeSeenBy(u, g); } // Guests can read posts in a group public static boolean guestsCanReadPostsInGroup(GroupModel g) { return canReadPostsInGroup((UserModel)HibernateUtil.currentSession().load(UserModel.class, 1), g); } /*** POSTS ***/ // Reply to a post public static boolean canReplyToPost( UserModel u, PostModel p ) { return postsCanBeSeenBy(u, p.getGroup()) && p.getGroup().getVisible(); } // Read a post public static boolean canReadPost( UserModel u, PostModel p ) { return postsCanBeSeenBy(u, p.getGroup()); } // Delete a post public static boolean canDeletePost( UserModel u, PostModel p ) { return canControlGroup(u,p.getGroup()); } /*** EVENTS ***/ // Update an Event public static boolean canUpdateEvent( UserModel u, EventModel e ) { return canSendToGroup(u, e.getGroup()); } // See an event in the calendar and look at its details public static boolean canReadEvent( UserModel u, EventModel e ) { return postsCanBeSeenBy(u, e.getGroup()); } /*** EVENTS IN A GROUP ***/ // Create new posts for a group public static boolean canUpdateEventInGroup( UserModel u, GroupModel g ) { return canSendToGroup(u, g); } /*** WHITEBOARDS ***/ // Update a whiteboard public static boolean canUpdateWhiteboard( UserModel u, WhiteboardModel w ) { if( w.getParentEvent() != null ) { return w.getParentEvent().getGroup().getVisible() && postsCanBeSeenBy(u, w.getParentEvent().getGroup()); } else if( w.getParentPost() != null ) { return w.getParentPost().getGroup().getVisible() && postsCanBeSeenBy(u, w.getParentPost().getGroup()); } else { return postsCanBeSeenBy(u, w.getParentGroup()) && w.getParentGroup().getVisible(); } } /*** GROUPFILES ***/ // Add/Delete files/folders in group file shares public static boolean canManageFilesInGroup( UserModel u, GroupModel g ) { return canControlGroup(u, g) || u.isSender(g); } // View files/folders in group file shares public static boolean canReadFilesInGroup( UserModel u, GroupModel g ) { return postsCanBeSeenBy(u,g); } ////FUNCTIONS FROM OTHER PLACES //GROUPLOGIC // See posts from group public static boolean postsCanBeSeenBy(UserLogic u, GroupLogic g) { //must at least return true if uLogic.visibleGroups(false).contains(this) //unless that group is an invisible admin group like us //admins also have special viewing powers here that are not reflected in visibleGroups if (!g.getVisible() && g.getAdmin()) { return false; // no one can see invisible admin groups } if ((g.getId() == 1) || g.getPublic() || u.isAdmin()) { return true; } if(u.getId() != 1) //shortcut for guest { if((u.isMember(g) || u.isRecipient(g))) { return true; //you're actually in the group } if ((g.getParent() != null) && u.isLeader(g.getParent())) { return true; //execs can see all private groups in their chapter } if(g.getAdmin() && u.isMember("Exec")) { return true; //execs can see all exec groups } } return false; } // Leader of group or Parent public static boolean canControlGroup(UserLogic u, GroupLogic g) { //isLeader will cover explicit leadership and implicit admin-ship //if getParent==null, we fall back on admin-ship, covered by previous call //if getParent is NOT null, then leaders of the parent chapter can get in return (u.isLeader(g) || ((g.getParent() != null) && u.isLeader(g.getParent()))); } //USERLOGIC // Leader of the chapter that targetUser is in, targetUser is not admin (or admin if adminOverride is true) private static boolean canControlUser(UserLogic u, UserLogic targetUser) { // if admin && override return true if (u.isAdmin()) { return true; } else { // else check that we're in the same chapter and that we're exec and // they're not admin GroupChapterModel chapter = u.getChapter(); GroupChapterModel chapter2 = targetUser.getChapter(); if ((!targetUser.isAdmin()) && (chapter2 != null) && (chapter != null) && chapter2.equals(chapter) && (u.isLeader(chapter))) { return true; } else { Logger.getLogger(Permissions.class.getName()).info(u.getUsername() + " tried to view info of " + targetUser.getUsername() + " with bad privileges!"); return false; } } } public static Set<GroupModel> visibleGroups(UserLogic u, boolean excludeChapters) throws HibernateException { return visibleGroups(u, excludeChapters, true); } // Groups that you can see their posts public static Set<GroupModel> visibleGroups(UserLogic u, boolean excludeChapters, boolean honourExecToggle) throws HibernateException { //GroupLogic.postsCanBeSeenBy(user) must return true for all //groups in the result! Set<GroupModel> theGroups = new HashSet<GroupModel>(); if (u.getUsername().equals("guest")) { theGroups.add(Helpers.getGroup("Org")); } else { theGroups.addAll(u.getGroups()); } if (!excludeChapters) { theGroups.addAll(GroupChapterModel.getChapters()); } if (!u.getUsername().equals("guest")) { boolean isExec = u.isMember("Exec"); GroupChapterModel myChapter = u.getChapter(); if (myChapter != null) { theGroups.addAll(myChapter.getChildGroups(true, isExec)); } if(isExec) { theGroups.add(Helpers.getGroup("Exec")); theGroups.add(Helpers.getGroup("ProChaptersExec")); theGroups.add(Helpers.getGroup("UniChaptersExec")); if(!honourExecToggle || u.isAdmin() || u.getAdminToggle()) { theGroups.addAll(Helpers.getNationalRepLists(true, true)); } } } return theGroups; } // Groups that you can see their posts in your chapter public static List<GroupModel> visibleGroupsInChapter(UserLogic u, GroupChapterModel chapter) { List<GroupModel> chapterGroups = chapter.getChildGroups(true, false); List<GroupModel> chapterPrivateGroups = chapter.getChildGroups(false, true); if (!u.isLeader(chapter)) { // if not exec, only return private groups you're part of chapterPrivateGroups.retainAll(u.getGroups()); } chapterGroups.addAll(chapterPrivateGroups); chapterGroups.add(chapter); return chapterGroups; } // Groups that you can post to public static List<GroupModel> postGroups(UserLogic u) { Session session = HibernateUtil.currentSession(); if (u.isAdmin()) { return (new SafeHibList<GroupModel>(session.createQuery( "FROM GroupModel g WHERE g.visible=true order by admin desc, " + "chapter desc, execList desc, parent.id asc, public desc"))).list(); } else { Query results = session .createQuery( "SELECT r.group FROM RoleModel r " + "WHERE r.user=? AND r.level!='r' " + "AND r.group.visible=true " + "AND r.end IS NULL" ).setEntity(0, u); List<GroupModel> theGroups = (new SafeHibList<GroupModel>(results)).list(); boolean isExec = u.isMember("Exec"); GroupChapterModel chapter = u.getChapter(); if ((chapter != null) && isExec) { List<GroupModel> chapterGroups = chapter.getChildGroups(true, true); chapterGroups.removeAll(theGroups); theGroups.addAll(chapterGroups); } if(isExec) { List<GroupModel> repGroups = Helpers.getNationalRepLists(true, true); repGroups.removeAll(theGroups); theGroups.addAll(repGroups); } return theGroups; } } public static List<GroupModel> visibleGroupsWithRoles(UserLogic u) { Session session = HibernateUtil.currentSession(); String query = "select distinct r.group from RoleModel as r where r.user=:user " + "AND r.end IS NULL AND r.group.visible=true order by r.group.admin desc, " + "r.group.chapter desc, r.group.execList desc, r.group.parent.id asc, r.group.public desc"; return (new SafeHibList<GroupModel>(session.createQuery(query) .setEntity("user", u)).list()); } // Groups that you can send e-mails to public static List<GroupModel> sendGroups(UserLogic u) { Session session = HibernateUtil.currentSession(); if (u.isAdmin()) { return (new SafeHibList<GroupModel>(session.createQuery( "FROM GroupModel g WHERE g.visible=true and g.id!=1 order by admin desc, " + "chapter desc, execList desc, parent.id asc, public desc"))).list(); } else { String query = "select distinct g from GroupModel as g, RoleModel as r " + "where r.user=:user " + "and ((r.group=g and (r.level='l' or r.level='s')) " + "or (r.group=g.parent and r.level='l')) AND r.end IS NULL AND g.visible=true"; return (new SafeHibList<GroupModel>(session.createQuery(query) .setEntity("user", u)).list()); } } public static List<GroupModel> visibleDeletedGroups(UserLogic u) { Session session = HibernateUtil.currentSession(); if (u.isAdmin()) { return (new SafeHibList<GroupModel>(session.createQuery( "FROM GroupModel g WHERE g.visible=false and g.admin=false order by " + "parent.id asc, public desc"))).list(); } else { //old general public groups List<GroupModel> visibleGroups = (new SafeHibList<GroupModel>(session.createQuery( "from GroupModel as g where g.admin=false and g.visible=false and g.public=true " + "and g.parent IS NULL"))) .list(); //old chapter groups, public (and private if exec) GroupChapterModel myChapter = u.getChapter(); if (myChapter != null) { visibleGroups.addAll(myChapter.getChildGroups(true, u.isMember("Exec"), false)); } return visibleGroups; } } public static boolean canSendToGroup(UserLogic u, GroupLogic g) { //must at least return true if uLogic.visibleGroups(false).contains(this) //unless that group is an invisible admin group like us //admins also have special viewing powers here that are not reflected in visibleGroups if (!g.getVisible() || g.getId() == 1 || u.getId() == 1) { return false; //admins can see almost all groups } if ( u.isAdmin() || u.isSender(g) || u.isLeader(g) ) { return true; } if ((g.getParent() != null) && u.isLeader(g.getParent())) { return true; //execs can see all private groups in their chapter } if(g.getAdmin() && u.isMember("Exec")) { return true; //execs can see all exec groups } return false; } // Load a page onto the screen public static boolean canViewPage(UserLogic u, PageLogic p) throws HibernateException { return !(HibernateUtil.currentSession() .createQuery( "from RoleModel as role where role.user=? and (? in elements(role.group.pages) OR ? in elements(role.group.invisiblePages)) AND role.end IS NULL") .setEntity(0, u).setEntity(1, p).setEntity(2, p).list() .isEmpty()); } // Pages that a user can see public static List<PageModel> visiblePages(UserLogic u, String area) throws HibernateException { LinkedHashSet<PageModel> hs = new LinkedHashSet<PageModel>(); hs .addAll((new SafeHibList<PageModel>( HibernateUtil.currentSession() .createQuery( "select p from PageModel as p, RoleModel as r where r.user=? and p in elements(r.group.pages) and p.area=? AND r.end IS NULL ORDER BY p.weight DESC, p.name") .setEntity(0, u).setString(1, area))).list()); List<PageModel> v = new Vector<PageModel>(); for (PageModel p : hs) { v.add(p); } return v; } }