/** * Copyright (C) 2016 Envidatec GmbH <info@envidatec.com> * * This file is part of JECommons. * * JECommons 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 in version 3. * * JECommons 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 * JECommons. If not, see <http://www.gnu.org/licenses/>. * * JECommons is part of the OpenJEVis project, further project information are * published at <http://www.OpenJEVis.org/>. */ package org.jevis.commons.user; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jevis.api.JEVisConstants; import org.jevis.api.JEVisDataSource; import org.jevis.api.JEVisRelationship; import org.jevis.api.JEVisUser; /** * * @author fs */ public class UserRightManager { private List<JEVisRelationship> permissions = new ArrayList<>(); private Logger logger = LogManager.getLogger(UserRightManager.class); private final JEVisUser user; private JEVisDataSource ds; private List<Long> readGIDS; private List<Long> createGIDS; private List<Long> deleteGIDS; private List<Long> exeGIDS; private List<Long> writeGIDS; public UserRightManager(JEVisDataSource ds, JEVisUser user, List<JEVisRelationship> permissions) throws Exception { logger.trace("Init UserRightManager for user: [{}]{} {}", user.getUserID(), user.getFirstName(), user.getLastName()); this.user = user; this.ds = ds; this.permissions = permissions; } public boolean isSysAdmin() { return user.isSysAdmin(); } public boolean canRead(long objectID) { return checkMebershipForType(objectID, JEVisConstants.ObjectRelationship.MEMBER_READ); } public boolean canWrite(long objectID) { return checkMebershipForType(objectID, JEVisConstants.ObjectRelationship.MEMBER_WRITE); } public boolean canCreate(long objectID) { return checkMebershipForType(objectID, JEVisConstants.ObjectRelationship.MEMBER_CREATE); } public boolean canExecute(long objectID) { return checkMebershipForType(objectID, JEVisConstants.ObjectRelationship.MEMBER_EXECUTE); } public boolean canDelete(long objectID) { return checkMebershipForType(objectID, JEVisConstants.ObjectRelationship.MEMBER_DELETE); } public boolean canDeleteClass(String jclass) { return user.isSysAdmin(); } public List<Long> getGroupsRead() { getGroupPermissions(); return readGIDS; } public List<Long> getAllObjectID(List<JEVisRelationship> rels) { List<Long> ids = new ArrayList<Long>(); for (JEVisRelationship rel : rels) { if (!ids.contains(rel.getEndID())) { ids.add(rel.getEndID()); } if (!ids.contains(rel.getStartID())) { ids.add(rel.getStartID()); } } return ids; } public List<JEVisRelationship> filterRelationships() { Long start = new Date().getTime(); logger.trace("filterRelationships() total: {}", permissions.size()); List<JEVisRelationship> filterd = new ArrayList<JEVisRelationship>(); List<Long> owned = new ArrayList<Long>(); getGroupPermissions(); logger.trace("Groups: {}", Arrays.toString(getGroupsRead().toArray())); //find all the object for all Groups(where the user is Memeber) for (JEVisRelationship rel : permissions) { try { if (rel.getType() == JEVisConstants.ObjectRelationship.OWNER && getGroupsRead().contains(rel.getEndID())) { owned.add(rel.getStartID()); } } catch (Exception ex) { } } logger.trace("Owned Objects: {}", owned.size()); //Find all Relationships which are oned by the user(Goups) for (JEVisRelationship rel : permissions) { try { if (owned.contains(rel.getStartID()) || owned.contains(rel.getEndID())) { filterd.add(rel); } else if (rel.getType() >= JEVisConstants.ObjectRelationship.MEMBER_READ && rel.getType() <= JEVisConstants.ObjectRelationship.MEMBER_DELETE && getGroupsRead().contains(rel.getEndID())) { //for the local UserRightsManager to work we need also the membership Relationships filterd.add(rel); // logger.info("---> add Membership Relationships: {}", rel); } } catch (Exception ex) { } } logger.trace("after filter {}", filterd.size()); logger.trace("Time for Filter: {}ms", ((new Date().getTime()) - start)); return filterd; } public void reload() { try { logger.info("----------------------------- Reload"); permissions = ds.getRelationships(); readGIDS = null; } catch (Exception ex) { logger.catching(ex); } } private void getGroupPermissions() { if (readGIDS == null) { logger.debug("reload userrights"); readGIDS = new ArrayList<Long>(); createGIDS = new ArrayList<Long>(); writeGIDS = new ArrayList<Long>(); deleteGIDS = new ArrayList<Long>(); exeGIDS = new ArrayList<Long>(); for (JEVisRelationship or : permissions) { try { //from user to group if (or.getStartID() == user.getUserID()) { switch (or.getType()) { case JEVisConstants.ObjectRelationship.MEMBER_READ: readGIDS.add(or.getEndID()); break; case JEVisConstants.ObjectRelationship.MEMBER_WRITE: writeGIDS.add(or.getEndID()); break; case JEVisConstants.ObjectRelationship.MEMBER_DELETE: deleteGIDS.add(or.getEndID()); break; case JEVisConstants.ObjectRelationship.MEMBER_EXECUTE: exeGIDS.add(or.getEndID()); break; case JEVisConstants.ObjectRelationship.MEMBER_CREATE: createGIDS.add(or.getEndID()); break; } } } catch (Exception ex) { } } logger.trace("Groups (Read,Write,Del,Exe,Cre): {},{},{},{},{}", readGIDS, writeGIDS, deleteGIDS, exeGIDS, createGIDS); } } /** * * @param object Object to check the permission for * @param type type of the membership(read,write,exe...) * @return */ private boolean checkMebershipForType(long object, int type) { logger.trace("CheckMembership user:{} object:{} type:{}", user.getUserID(), object, type); if (isSysAdmin()) { //Sys Admins can do everything wihout questions return true; } try { getGroupPermissions(); boolean can = false; //User Object is a special case // - User can Read him self // - User can edit all attributes except "Sys Admin" and Enabled are protectet // - User cannot remame the object for now // - What is with the right to create relationships?! if (user.getUserID() == object) { if (type == JEVisConstants.ObjectRelationship.MEMBER_READ || type == JEVisConstants.ObjectRelationship.MEMBER_WRITE) { // logger.info("----> is userobject: o:{} u:{}", object, user); return true; } } //Common userrights for (JEVisRelationship or : permissions) { try { // logger.debug("---------------> PerRel: {}", or); if (or.getType() == JEVisConstants.ObjectRelationship.OWNER && or.getStartID() == object) { logger.info("----> Ownership: {}", or); switch (type) { case JEVisConstants.ObjectRelationship.MEMBER_READ: if (readGIDS.contains(or.getEndID())) { can = true; } break; case JEVisConstants.ObjectRelationship.MEMBER_DELETE: if (deleteGIDS.contains(or.getEndID())) { can = true; } break; case JEVisConstants.ObjectRelationship.MEMBER_EXECUTE: if (exeGIDS.contains(or.getEndID())) { can = true; } break; case JEVisConstants.ObjectRelationship.MEMBER_WRITE: if (writeGIDS.contains(or.getEndID())) { can = true; } break; case JEVisConstants.ObjectRelationship.MEMBER_CREATE: if (createGIDS.contains(or.getEndID())) { can = true; } break; } if (can) {//end loop if the user can return can; } } } catch (Exception ex) { logger.catching(ex); } } return can; } catch (Exception ne) { logger.debug("Error while checking Memberships: {}", ne);//ToDO there is some error here } return false; } }