Mercurial Hosting > nabble
view src/nabble/view/lib/Permissions.java @ 21:aba8ed4c8a06
semiprivate
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sat, 13 Jun 2020 22:30:48 -0600 |
parents | 18cf4872fd7f |
children |
line wrap: on
line source
package nabble.view.lib; import fschmidt.db.Listener; import fschmidt.db.ListenerList; import fschmidt.util.java.Filter; import nabble.model.Db; import nabble.model.Init; import nabble.model.Node; import nabble.model.Person; import nabble.model.Site; import nabble.model.User; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; public final class Permissions { private Permissions() {} // never private static String encode(String s) { StringBuilder buf = new StringBuilder(); int n = s.length(); for( int i=0; i<n; i++ ) { char c = s.charAt(i); if( c == '\'' ) buf.append('\''); buf.append(c); } return buf.toString(); } private static void dbCheck(Site site) { if( !site.getDb().isInTransaction() ) throw new RuntimeException("not in transaction"); } public static boolean isInGroup(User user,String group) { return user.getSite().hasTags(null,user, "label='group:" + encode(group) + "'" ); } public static void addToGroup(User user,String group) { Site site = user.getSite(); dbCheck(site); site.addTag( null, user, "group:" + group ); groupChangeListeners.event(site); } public static void removeFromGroup(User user,String group) { Site site = user.getSite(); dbCheck(site); user.getSite().deleteTags(null,user, "label='group:" + encode(group) + "'" ); groupChangeListeners.event(site); } public static void removeGroup(Site site,String group) { site.deleteTags( "node_id is null and user_id is not null and label='group:" + encode(group) + "'" ); groupChangeListeners.event(site); } public static void removeGroups(User user) { user.getSite().deleteTags(null,user, "label like 'group:%'" ); groupChangeListeners.event(user.getSite()); } private static List<String> getGroups(Site site,String sqlCondition) { List<String> list = new ArrayList<String>(); for( String label : site.findTagLabels(sqlCondition) ) { list.add( label.substring(6) ); } return list; } public static List<String> getGroups(User user) { return getGroups( user.getSite(), "node_id is null and user_id=" + user.getId() + " and label like 'group:%'" ); } public static List<String> getGroups(Site site) { return getGroups( site, "node_id is null and user_id is not null and label like 'group:%'" ); } public static List<User> getUsersInGroup(Site site,String group) { return site.findTagUsers( "node_id is null and user_id is not null and label='group:" + encode(group) + "'" ); } public static void addPermission(Node node,String permission) { Site site = node.getSite(); dbCheck(site); site.addTag( node, null, "permission:" + permission ); permissionChangeListeners.event(site); } public static void addPermission(Node node,String permission,String group) { Site site = node.getSite(); dbCheck(site); if( !nodeHasPermission(node,permission) ) addPermission(node,permission); site.addTag( node, null, "permission:" + permission + ":" + group ); permissionChangeListeners.event(site); } public static void addPermission(Site site,String permission,String group) { dbCheck(site); if( !siteHasPermission(site,permission) ) site.addTag( null, null, "permission:" + permission ); site.addTag( null, null, "permission:" + permission + ":" + group ); permissionChangeListeners.event(site); } public static void removePermission(Node node,String permission,String group) { Site site = node.getSite(); dbCheck(site); site.deleteTags(node,null, "label='permission:" + encode(permission) + ":" + encode(group) + "'" ); permissionChangeListeners.event(site); } public static void removePermission(Node node,String permission) { Site site = node.getSite(); site.deleteTags(node,null, "(label = 'permission:" + encode(permission) + "'" + " or label like 'permission:" + encode(permission) + ":%')" ); permissionChangeListeners.event(site); } public static void removePermissions(Node node) { Site site = node.getSite(); dbCheck(site); site.deleteTags(node,null, "label like 'permission:%'" ); permissionChangeListeners.event(site); } public static boolean isPermissionVersion(Site site,String version) { return site.hasTags(null,null, "label='permission-version:" + version + "'" ); } public static void setPermissionVersion(Site site,String version) { dbCheck(site); deletePermissionVersion(site); site.addTag( null, null, "permission-version:" + version ); } public static void deletePermissionVersion(Site site) { site.deleteTags(null,null, "(label like 'permission:%' or label like 'site_default_permission:%' or label like 'permission-version:%')" ); } private static String query(Node node) { return node==null ? "node_id is null" : "node_id=" + node.getId(); } private static boolean siteHasPermission(Site site,String permission) { return site.hasTags(null,null, "label='permission:" + encode(permission) + "'" ); } public static boolean nodeHasPermission(Node node,String permission) { return node.getSite().hasTags(node,null, "label='permission:" + encode(permission) + "'" ); } public static Node getPermissionNode(Node node,String permission) { for( Node n : node.getAncestors() ) { if( nodeHasPermission(n,permission) ) return n; } return null; } public static List<String> getGroupsWithPermission(Node node,String permission) { Site site = node.getSite(); node = getPermissionNode(node,permission); if( node == null && !siteHasPermission(site,permission) ) return Collections.emptyList(); List<String> list = new ArrayList<String>(); String labelStart = "permission:" + encode(permission) + ":"; int i = labelStart.length(); for( String label : site.findTagLabels( query(node) + " and user_id is null and label like '" + labelStart + "%'" ) ) { list.add( label.substring(i) ); } return list; } public static boolean hasGroupsWithPermission(Node node,String permission) { Site site = node.getSite(); node = getPermissionNode(node,permission); if( node == null && !siteHasPermission(site,permission) ) return false; return site.hasTags(node,null, "label like 'permission:" + encode(permission) + ":%'" ); } public static final String ANYONE_GROUP = "Anyone"; public static final String AUTHOR_GROUP = "Authors"; public static final String ADMINISTRATORS_GROUP = "Administrators"; public static List<String> getPersonGroups(User user) { if( user==null || !user.isRegistered() ) return new ArrayList<String>(); List<String> groups = getGroups(user); groups.add(ANYONE_GROUP); return groups; } public static boolean hasPermission(Node permissionNode,Node targetNode,User user,String permission) { Person owner = targetNode.getOwner(); Site site = permissionNode.getSite(); permissionNode = getPermissionNode(permissionNode,permission); if( permissionNode == null && !siteHasPermission(site,permission) ) return false; String s = "label='permission:" + encode(permission) + ":"; List<String> groups = getPersonGroups(user); if( owner.equals(user) ) groups.add(AUTHOR_GROUP); for( String group : groups ) { if( site.hasTags(permissionNode,null, s + encode(group) + "'" ) ) { return true; } } return false; } public static boolean hasPermission(Node node,String group,String permission) { Site site = node.getSite(); node = getPermissionNode(node,permission); if( node == null && !siteHasPermission(site,permission) ) return false; return hasPermission(site,node,group,permission); } private static boolean hasPermission(Site site,Node node,String group,String permission) { return site.hasTags(node,null, "label='permission:" + encode(permission) + ":" + encode(group) + "'" ); } public static boolean hasPermission(Site site,String group,String permission) { return siteHasPermission(site,permission) && site.hasTags(null,null, "label='permission:" + encode(permission) + ":" + encode(group) + "'" ); } public static List<User> getUsersWithPermission(Node node,String permission) { Site site = node.getSite(); node = getPermissionNode(node,permission); if( node == null && !siteHasPermission(site,permission) ) return Collections.emptyList(); if (hasPermission(site, node, ANYONE_GROUP,permission)) return site.getUsers("registered is not null"); String labelStart = "permission:" + encode(permission) + ":"; int i = labelStart.length(); return site.findTagUsers( "node_id is null and user_id is not null and label in (" + "select 'group:' || substring(label," + (i+1) + ") from tag where " + query(node) + " and user_id is null and label like '" + labelStart + "%'" +")" ); } public static final String VIEW_PERMISSION = "View"; public static boolean isPrivate(Node node) { return getPrivateNode(node) != null; } public static boolean canBeViewedByParentViewers(Node node) { if( node.getKind() != Node.Kind.APP ) return true; if( !nodeHasPermission(node,VIEW_PERMISSION) ) return true; Node parent = node.getParent(); if( parent != null ) parent = getPrivateNode(parent); if( parent == null && !siteHasPermission(node.getSite(),VIEW_PERMISSION) ) return !isPrivate(node); return !node.getSite().hasTags(parent,null, "label like 'permission:View:%'" +" and label not in (select label from tag where node_id=" + node.getId() + " and user_id is null and label like 'permission:View:%')" ); } public static final Filter<Node> canBeViewedByParentViewersFilter = new Filter<Node>() { public boolean ok(Node node) { return canBeViewedByParentViewers(node); } }; public static boolean canBeViewedByPerson(Node node,User user) { if( user != null ) { if( isSysAdmin(user) ) return true; if( isInGroup(user,ADMINISTRATORS_GROUP) ) return true; } if( node.getSite().getRootNode().getOwner().equals(user) ) return true; Node permissionNode = node.getApp(); if( permissionNode==null ) permissionNode = node.getSite().getRootNode(); return hasPermission(permissionNode,node,user,VIEW_PERMISSION); } public static final Filter<Node> canBeViewedByPersonFilter(final User user) { return new Filter<Node>() { public boolean ok(Node node) { return canBeViewedByPerson(node,user); } }; } public static Node getPrivateNode(Node node) { node = getPermissionNode(node,VIEW_PERMISSION); return node==null || hasPermission(node.getSite(),node,ANYONE_GROUP,VIEW_PERMISSION) ? null : node; } public static Node getPrivateNodeForSearch(Node node) { node = getPrivateNode(node); while( node != null && canBeViewedByParentViewers(node) ) { node = getPrivateNode(node.getParent()); } return node; } // Banning ------------------------------------------------------ public static boolean isBanned(User user) { return user.getSite().hasTags(null,user,"label='banned'"); } public static void ban(User user) { user.getSite().addTag(null, user, "banned"); } public static void unban(User user) { user.getSite().deleteTags(null,user,"label='banned'"); } public static List<User> getBannedUsers(Site site) { return site.findTagUsers( "node_id is null and user_id is not null and label='banned'" ); } private static final Set<String> sysadmins = Init.get("sysadmins",Collections.<String>emptySet()); public static boolean isSysAdmin(User user) { return sysadmins.contains(user.getEmail()); } // site permissions public static void addSitePermission(Site site,String permission) { dbCheck(site); site.addTag( null, null, "site_permission:" + permission ); } public static void addSiteDefaultPermission(Site site,String permission) { dbCheck(site); site.addTag( null, null, "site_default_permission:" + permission ); } private static boolean hasSitePermission(Site site,String permission) { return site.hasTags(null,null, "label='site_permission:" + encode(permission) + "'" ); } public static boolean siteHasSitePermission(Site site,String permission) { return hasSitePermission(site,permission); } private static boolean hasSiteDefaultPermission(Site site,String permission) { return site.hasTags(null,null, "label='site_default_permission:" + encode(permission) + "'" ); } public static void addSitePermission(Site site,String permission,String group) { dbCheck(site); if( !hasSitePermission(site,permission) ) site.addTag( null, null, "site_permission:" + permission ); site.addTag( null, null, "site_permission:" + permission + ":" + group ); } public static void addSiteDefaultPermission(Site site,String permission,String group) { dbCheck(site); if( !hasSiteDefaultPermission(site,permission) ) site.addTag( null, null, "site_default_permission:" + permission ); site.addTag( null, null, "site_default_permission:" + permission + ":" + group ); } public static void removeSitePermission(Site site,String permission,String group) { dbCheck(site); site.deleteTags(null,null, "label='site_permission:" + encode(permission) + ":" + encode(group) + "'" ); } public static void removeSitePermission(Site site,String permission) { site.deleteTags(null,null, "(label = 'site_permission:" + encode(permission) + "'" + " or label like 'site_permission:" + encode(permission) + ":%')" ); } public static void removeSitePermissions(Site site) { dbCheck(site); site.deleteTags(null,null, "label like 'site_permission:%'" ); } private static String sitePermissionLabel(Site site,String permission) { if( hasSitePermission(site,permission) ) return "site_permission:" + encode(permission); else if( hasSiteDefaultPermission(site,permission) ) return "site_default_permission:" + encode(permission); else return null; } public static List<String> getGroupsWithSitePermission(Site site,String permission) { String labelStart = sitePermissionLabel(site,permission); if( labelStart == null ) return Collections.emptyList(); List<String> list = new ArrayList<String>(); int i = labelStart.length(); for( String label : site.findTagLabels( "node_id is null and user_id is null and label like '" + labelStart + ":%'" ) ) { list.add( label.substring(i) ); } return list; } public static boolean hasGroupsWithSitePermission(Site site,String permission) { String labelStart = sitePermissionLabel(site,permission); if( labelStart == null ) return false; return site.hasTags(null,null, "label like '" + labelStart + ":%'" ); } public static boolean hasSitePermission(Site site,User user,String permission) { String labelStart = sitePermissionLabel(site,permission); if( labelStart == null ) return false; String s = "label='" + labelStart + ":"; List<String> groups = getPersonGroups(user); for( String group : groups ) { if( site.hasTags(null,null, s + encode(group) + "'" ) ) return true; } return false; } public static boolean hasSitePermission(Site site,String group,String permission) { String labelStart = sitePermissionLabel(site,permission); if( labelStart == null ) return false; return site.hasTags(null,null, "label='" + labelStart + ":" + encode(group) + "'" ); } public static boolean hasSiteDefaultPermission(Site site,String group,String permission) { return hasSiteDefaultPermission(site,permission) && site.hasTags(null,null, "label='site_default_permission:" + encode(permission) + ":" + encode(group) + "'" ); } private static final ListenerList<Site> groupChangeListeners = new ListenerList<Site>(); public static void addGroupChangeListener(final Listener<Site> listener) { groupChangeListeners.add(listener); } private static final ListenerList<Site> permissionChangeListeners = new ListenerList<Site>(); public static void addPermissionChangeListener(final Listener<Site> listener) { permissionChangeListeners.add(listener); } }