/**
* Copyright (c) Codice Foundation
* <p>
* This 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 3 of the
* License, or any later version.
* <p>
* This program 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. A copy of the GNU Lesser General Public License
* is distributed along with this program and can be found at
* <http://www.gnu.org/licenses/lgpl.html>.
*/
package org.codice.ddf.catalog.ui.security;
import static java.util.stream.Stream.concat;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import ddf.catalog.data.impl.types.SecurityAttributes;
import ddf.catalog.data.types.Core;
import ddf.security.permission.CollectionPermission;
import ddf.security.permission.KeyValueCollectionPermission;
import ddf.security.permission.KeyValuePermission;
import ddf.security.policy.extension.PolicyExtension;
public class WorkspacePolicyExtension implements PolicyExtension {
private String systemUserAttribute = Constants.ROLES_CLAIM_URI;
private String systemUserAttributeValue = "admin";
// @formatter:off
private Map<String, String> keyMapping = ImmutableMap.of(
Core.METACARD_OWNER, Constants.EMAIL_ADDRESS_CLAIM_URI,
SecurityAttributes.ACCESS_INDIVIDUALS, Constants.EMAIL_ADDRESS_CLAIM_URI,
SecurityAttributes.ACCESS_GROUPS, Constants.ROLES_CLAIM_URI);
// @formatter:on
private static Predicate<KeyValuePermission> byKeys(Set<String> keys) {
return permission -> keys.contains(permission.getKey());
}
private static Function<KeyValuePermission, KeyValuePermission> remapKeys(
Map<String, String> mapping) {
return permission -> new KeyValuePermission(mapping.get(permission.getKey()),
permission.getValues());
}
private static List<KeyValuePermission> getPermissions(
KeyValueCollectionPermission collection) {
return collection.getPermissionList()
.stream()
.filter(p -> p instanceof KeyValuePermission)
.map(p -> (KeyValuePermission) p)
.collect(Collectors.toList());
}
private Stream<KeyValuePermission> overrides() {
return Stream.of(new KeyValuePermission(systemUserAttribute, ImmutableSet.of(
systemUserAttributeValue)));
}
@Override
public KeyValueCollectionPermission isPermittedMatchAll(CollectionPermission subject,
KeyValueCollectionPermission match) {
List<KeyValuePermission> permissions = getPermissions(match);
Stream<KeyValuePermission> remapped = permissions.stream()
.filter(byKeys(keyMapping.keySet()))
.map(remapKeys(keyMapping));
boolean matched = concat(overrides(), remapped).filter(subject::implies)
.findFirst()
.isPresent();
if (!matched) {
return match;
}
if (isOwnerPermission(getPermissions(match), subject)) {
return new KeyValueCollectionPermission();
}
return new KeyValueCollectionPermission(match.getAction(),
permissions.stream()
.filter(byKeys(keyMapping.keySet()).negate())
.collect(Collectors.toList()));
}
private boolean isOwnerPermission(List<KeyValuePermission> permissions,
CollectionPermission subject) {
Optional<KeyValuePermission> ownerPerm = permissions.stream()
.filter(keyValuePermission -> keyValuePermission.getKey()
.equals(Core.METACARD_OWNER))
.findAny();
if (ownerPerm.isPresent()) {
KeyValuePermission ownerEmailPermission =
new KeyValuePermission(Constants.EMAIL_ADDRESS_CLAIM_URI,
ownerPerm.get()
.getValues());
return subject.implies(ownerEmailPermission);
}
return false;
}
@Override
public KeyValueCollectionPermission isPermittedMatchOne(CollectionPermission subject,
KeyValueCollectionPermission matchOne) {
return matchOne;
}
public String getSystemUserAttribute() {
return systemUserAttribute;
}
public void setSystemUserAttribute(String systemUserAttribute) {
this.systemUserAttribute = systemUserAttribute;
}
public String getSystemUserAttributeValue() {
return systemUserAttributeValue;
}
public void setSystemUserAttributeValue(String systemUserAttributeValue) {
this.systemUserAttributeValue = systemUserAttributeValue;
}
}