From f6f2923e1e179b2784dc6baf539f1edde4abf81c Mon Sep 17 00:00:00 2001 From: jensp Date: Fri, 27 Nov 2015 18:29:45 +0000 Subject: [PATCH] CCM NG: More secured collections (not tested yet) git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3752 8810af33-2d31-482b-a856-94f89814c4df --- .../org/libreccm/security/SecuredEntry.java | 57 +++++++ .../security/SecuredEntryIterator.java | 53 ++++++ .../libreccm/security/SecuredEntrySet.java | 155 +++++++++++++++++ .../org/libreccm/security/SecuredMap.java | 117 +++++++++++++ .../security/SecuredNavigableMap.java | 158 ++++++++++++++++++ .../libreccm/security/SecuredSortedMap.java | 85 ++++++++++ .../libreccm/security/SecuredSortedSet.java | 16 +- 7 files changed, 633 insertions(+), 8 deletions(-) create mode 100644 ccm-core/src/main/java/org/libreccm/security/SecuredEntry.java create mode 100644 ccm-core/src/main/java/org/libreccm/security/SecuredEntryIterator.java create mode 100644 ccm-core/src/main/java/org/libreccm/security/SecuredEntrySet.java create mode 100644 ccm-core/src/main/java/org/libreccm/security/SecuredMap.java create mode 100644 ccm-core/src/main/java/org/libreccm/security/SecuredNavigableMap.java create mode 100644 ccm-core/src/main/java/org/libreccm/security/SecuredSortedMap.java diff --git a/ccm-core/src/main/java/org/libreccm/security/SecuredEntry.java b/ccm-core/src/main/java/org/libreccm/security/SecuredEntry.java new file mode 100644 index 000000000..974d62809 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/security/SecuredEntry.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.security; + +import org.libreccm.core.CcmObject; + +import java.util.Map; + +/** + * + * @author Jens Pelzetter + * @param + * @param + */ +class SecuredEntry implements Map.Entry { + + private final Map.Entry entry; + private final SecuredHelper securedHelper; + + public SecuredEntry(final Map.Entry entry, + final SecuredHelper securedHelper) { + this.entry = entry; + this.securedHelper = securedHelper; + } + + @Override + public K getKey() { + return entry.getKey(); + } + + @Override + public V getValue() { + return securedHelper.canAccess(entry.getValue()); + } + + @Override + public V setValue(final V value) { + return securedHelper.canAccess(entry.setValue(value)); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/security/SecuredEntryIterator.java b/ccm-core/src/main/java/org/libreccm/security/SecuredEntryIterator.java new file mode 100644 index 000000000..488721cba --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/security/SecuredEntryIterator.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.security; + +import org.libreccm.core.CcmObject; + +import java.util.Iterator; +import java.util.Map; + +/** + * + * @author Jens Pelzetter + */ +class SecuredEntryIterator, K, V extends CcmObject> + implements Iterator { + + private final Iterator iterator; + private final SecuredHelper securedHelper; + + public SecuredEntryIterator(final Iterator iterator, + final SecuredHelper securedHelper) { + this.iterator = iterator; + this.securedHelper = securedHelper; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + @SuppressWarnings("unchecked") + public E next() { + return (E) new SecuredEntry<>(iterator.next(), securedHelper); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/security/SecuredEntrySet.java b/ccm-core/src/main/java/org/libreccm/security/SecuredEntrySet.java new file mode 100644 index 000000000..551a341e4 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/security/SecuredEntrySet.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.security; + +import com.arsdigita.util.UncheckedWrapperException; + +import org.libreccm.cdi.utils.CdiLookupException; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.core.CcmObject; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * + * @author Jens Pelzetter + */ +class SecuredEntrySet, K, V extends CcmObject> + implements Set { + + private final Set set; + private final String requiredPrivilege; + private final SecuredHelper securedHelper; + + public SecuredEntrySet(final Set set, + final String requiredPrivilege, + final SecuredHelper securedHelper) { + this.set = set; + this.requiredPrivilege = requiredPrivilege; + this.securedHelper = securedHelper; + } + + @Override + public int size() { + return set.size(); + } + + @Override + public boolean isEmpty() { + return set.isEmpty(); + } + + @Override + public boolean contains(final Object object) { + return set.contains(object); + } + + @Override + public Iterator iterator() { + return new SecuredEntryIterator<>(set.iterator(), securedHelper); + } + + @Override + @SuppressWarnings("unchecked") + public Object[] toArray() { + final PermissionChecker permissionChecker; + final CdiUtil cdiUtil = new CdiUtil(); + try { + permissionChecker = cdiUtil.findBean( + PermissionChecker.class); + } catch (CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } + + final Object[] entries = set.toArray(); + for (int i = 0; i < entries.length; i++) { + final E entry = (E) entries[i]; + if (!permissionChecker.isPermitted(requiredPrivilege, + entry.getValue())) { + entries[i] = securedHelper.generateAccessDeniedObject(); + } + } + + return entries; + } + + @Override + @SuppressWarnings("unchecked") + public T[] toArray(final T[] array) { + final PermissionChecker permissionChecker; + final CdiUtil cdiUtil = new CdiUtil(); + try { + permissionChecker = cdiUtil.findBean( + PermissionChecker.class); + } catch (CdiLookupException ex) { + throw new UncheckedWrapperException(ex); + } + + final E[] entries = (E[]) set.toArray(array); + for (int i = 0; i < entries.length; i++) { + if (!permissionChecker.isPermitted(requiredPrivilege, + entries[i].getValue())) { + entries[i] = (E) securedHelper.generateAccessDeniedObject(); + } + } + + return (T[]) entries; + } + + @Override + public boolean add(final E element) { + return set.add(element); + } + + @Override + public boolean remove(final Object object) { + return set.remove(object); + } + + @Override + public boolean containsAll(final Collection collection) { + return set.containsAll(collection); + } + + @Override + public boolean addAll(final Collection collection) { + return set.addAll(collection); + } + + @Override + public boolean retainAll(final Collection collection) { + return set.retainAll(collection); + } + + @Override + public boolean removeAll(final Collection collection) { + return set.removeAll(collection); + } + + @Override + public void clear() { + set.clear(); + } + + } + + diff --git a/ccm-core/src/main/java/org/libreccm/security/SecuredMap.java b/ccm-core/src/main/java/org/libreccm/security/SecuredMap.java new file mode 100644 index 000000000..31279a38d --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/security/SecuredMap.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.security; + +import com.arsdigita.util.UncheckedWrapperException; + +import org.libreccm.cdi.utils.CdiLookupException; +import org.libreccm.cdi.utils.CdiUtil; +import org.libreccm.core.CcmObject; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * + * @author Jens Pelzetter + * @param + * @param + */ +public class SecuredMap implements Map { + + private final Map map; + private final Class clazz; + private final String requiredPrivilege; + private final SecuredHelper securedHelper; + + public SecuredMap(final Map map, + final Class clazz, + final String requiredPrivilege) { + this.map = map; + this.clazz = clazz; + this.requiredPrivilege = requiredPrivilege; + this.securedHelper = new SecuredHelper<>(clazz, requiredPrivilege); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + + @Override + public boolean containsKey(final Object key) { + return map.containsKey(key); + } + + @Override + public boolean containsValue(final Object value) { + return map.containsValue(value); + } + + @Override + public V get(final Object key) { + return securedHelper.canAccess(map.get(key)); + } + + @Override + public V put(final K key, final V value) { + return map.put(key, value); + } + + @Override + public V remove(final Object key) { + return map.remove(key); + } + + @Override + public void putAll(final Map map) { + this.map.putAll(map); + } + + @Override + public void clear() { + map.clear(); + } + + @Override + public Set keySet() { + return map.keySet(); + } + + @Override + public Collection values() { + return new SecuredCollection<>(map.values(), clazz, requiredPrivilege); + } + + @Override + public Set> entrySet() { + return new SecuredEntrySet<>(map.entrySet(), + requiredPrivilege, + securedHelper); + + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/security/SecuredNavigableMap.java b/ccm-core/src/main/java/org/libreccm/security/SecuredNavigableMap.java new file mode 100644 index 000000000..4a7951e55 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/security/SecuredNavigableMap.java @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.security; + +import org.libreccm.core.CcmObject; + +import java.util.NavigableMap; +import java.util.NavigableSet; + +/** + * + * @author Jens Pelzetter + * @param + * @param + */ +public class SecuredNavigableMap + extends SecuredSortedMap + implements NavigableMap { + + private final NavigableMap navigableMap; + private final Class clazz; + private final String requiredPrivilege; + private final SecuredHelper securedHelper; + + public SecuredNavigableMap(final NavigableMap navigableMap, + final Class clazz, + final String requiredPrivilege) { + super(navigableMap, clazz, requiredPrivilege); + this.navigableMap = navigableMap; + this.clazz = clazz; + this.requiredPrivilege = requiredPrivilege; + securedHelper = new SecuredHelper<>(clazz, requiredPrivilege); + } + + @Override + public Entry lowerEntry(final K key) { + return new SecuredEntry<>(navigableMap.lowerEntry(key), securedHelper); + } + + @Override + public K lowerKey(final K key) { + return navigableMap.lowerKey(key); + } + + @Override + public Entry floorEntry(final K key) { + return new SecuredEntry<>(navigableMap.floorEntry(key), securedHelper); + } + + @Override + public K floorKey(final K key) { + return navigableMap.floorKey(key); + } + + @Override + public Entry ceilingEntry(final K key) { + return new SecuredEntry<>(navigableMap.ceilingEntry(key), securedHelper); + } + + @Override + public K ceilingKey(final K key) { + return navigableMap.ceilingKey(key); + } + + @Override + public Entry higherEntry(final K key) { + return new SecuredEntry<>(navigableMap.higherEntry(key), securedHelper); + } + + @Override + public K higherKey(final K key) { + return navigableMap.higherKey(key); + } + + @Override + public Entry firstEntry() { + return new SecuredEntry<>(navigableMap.firstEntry(), securedHelper); + } + + @Override + public Entry lastEntry() { + return new SecuredEntry<>(navigableMap.lastEntry(), securedHelper); + } + + @Override + public Entry pollFirstEntry() { + return new SecuredEntry<>(navigableMap.pollFirstEntry(), securedHelper); + } + + @Override + public Entry pollLastEntry() { + return new SecuredEntry<>(navigableMap.pollLastEntry(), securedHelper); + } + + @Override + public NavigableMap descendingMap() { + return new SecuredNavigableMap<>(navigableMap.descendingMap(), + clazz, + requiredPrivilege); + } + + @Override + public NavigableSet navigableKeySet() { + return navigableMap.navigableKeySet(); + } + + @Override + public NavigableSet descendingKeySet() { + return navigableMap.descendingKeySet(); + } + + @Override + public NavigableMap subMap(final K fromKey, + final boolean fromInclusive, + final K toKey, + final boolean toInclusive) { + return new SecuredNavigableMap<>(navigableMap.subMap(fromKey, + fromInclusive, + toKey, + toInclusive), + clazz, + requiredPrivilege); + } + + @Override + public NavigableMap headMap(final K toKey, + final boolean inclusive) { + return new SecuredNavigableMap<>(navigableMap.headMap(toKey, inclusive), + clazz, + requiredPrivilege); + } + + @Override + public NavigableMap tailMap(final K fromKey, + final boolean inclusive) { + return new SecuredNavigableMap<>(navigableMap.tailMap(fromKey, + inclusive), + clazz, + requiredPrivilege); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/security/SecuredSortedMap.java b/ccm-core/src/main/java/org/libreccm/security/SecuredSortedMap.java new file mode 100644 index 000000000..7bfd66843 --- /dev/null +++ b/ccm-core/src/main/java/org/libreccm/security/SecuredSortedMap.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2015 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package org.libreccm.security; + +import org.libreccm.core.CcmObject; + +import java.util.Comparator; +import java.util.SortedMap; + +/** + * + * @author Jens Pelzetter + * @param + * @param + */ +public class SecuredSortedMap + extends SecuredMap + implements SortedMap { + + private final SortedMap sortedMap; + private final Class clazz; + private final String requiredPrivilege; + + public SecuredSortedMap(final SortedMap sortedMap, + final Class clazz, + final String requiredPrivilege) { + super(sortedMap, clazz, requiredPrivilege); + this.sortedMap = sortedMap; + this.clazz = clazz; + this.requiredPrivilege = requiredPrivilege; + } + + @Override + public Comparator comparator() { + return sortedMap.comparator(); + } + + @Override + public SortedMap subMap(final K fromKey, final K toKey) { + return new SecuredSortedMap<>(sortedMap.subMap(fromKey, toKey), + clazz, + requiredPrivilege); + } + + @Override + public SortedMap headMap(final K toKey) { + return new SecuredSortedMap<>(sortedMap.headMap(toKey), + clazz, + requiredPrivilege); + } + + @Override + public SortedMap tailMap(final K fromKey) { + return new SecuredSortedMap<>(sortedMap.tailMap(fromKey), + clazz, + requiredPrivilege); + } + + @Override + public K firstKey() { + return sortedMap.firstKey(); + } + + @Override + public K lastKey() { + return sortedMap.lastKey(); + } + +} diff --git a/ccm-core/src/main/java/org/libreccm/security/SecuredSortedSet.java b/ccm-core/src/main/java/org/libreccm/security/SecuredSortedSet.java index 955b5972c..adc379d3c 100644 --- a/ccm-core/src/main/java/org/libreccm/security/SecuredSortedSet.java +++ b/ccm-core/src/main/java/org/libreccm/security/SecuredSortedSet.java @@ -44,7 +44,7 @@ public class SecuredSortedSet this.set = set; this.clazz = clazz; this.requiredPrivilege = requiredPrivilege; - this.securedHelper = new SecuredHelper(clazz, requiredPrivilege); + this.securedHelper = new SecuredHelper<>(clazz, requiredPrivilege); } @Override @@ -53,23 +53,23 @@ public class SecuredSortedSet } @Override - public SortedSet subSet(final E element1, - final E element2) { - return new SecuredSortedSet<>(set.subSet(element1, element2), + public SortedSet subSet(final E fromElement, + final E toElement) { + return new SecuredSortedSet<>(set.subSet(fromElement, toElement), clazz, requiredPrivilege); } @Override - public SortedSet headSet(final E element) { - return new SecuredSortedSet<>(set.headSet(element), + public SortedSet headSet(final E toElement) { + return new SecuredSortedSet<>(set.headSet(toElement), clazz, requiredPrivilege); } @Override - public SortedSet tailSet(final E element) { - return new SecuredSortedSet<>(set.tailSet(element), + public SortedSet tailSet(final E fromElement) { + return new SecuredSortedSet<>(set.tailSet(fromElement), clazz, requiredPrivilege); }