| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with this |
| * work for additional information regarding copyright ownership. The ASF |
| * licenses this file to You under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package org.apache.karaf.webconsole.core.security; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.TreeMap; |
| |
| import org.apache.wicket.authorization.strategies.role.Roles; |
| |
| /** |
| * An extension of roles to support hierarchical roles. Hierarchy is created by |
| * splitting dahses in the role names. |
| * |
| * The role checking follow the structure with one exception. If assgidned roles |
| * do not have a "specific" extension then check will pass. For example, if user |
| * have assigned role "test-role" and component requires role "test-role-one" |
| * then user will be authorized. |
| */ |
| public class HierarchicalRoles { |
| |
| /** |
| * Helper class. |
| */ |
| class Node { |
| |
| private Map<String, Node> nodes = new TreeMap<String, Node>(); |
| |
| private String name; |
| |
| public Node(String name) { |
| this.name = name; |
| } |
| |
| public String getName() { |
| return name; |
| } |
| |
| public Map<String, Node> getNodes() { |
| return nodes; |
| } |
| } |
| |
| /** |
| * Assgined roles. |
| */ |
| private Map<String, Node> nodes = new TreeMap<String, Node>(); |
| |
| public HierarchicalRoles(Roles roles) { |
| for (String role : roles) { |
| String[] path = role.split("-"); |
| |
| createNode(nodes, new ArrayList<String>(Arrays.asList(path))); |
| } |
| } |
| |
| public HierarchicalRoles() { |
| this(new Roles()); |
| } |
| |
| public HierarchicalRoles(String roles) { |
| this(new Roles(roles)); |
| } |
| |
| private void createNode(Map<String, Node> nodes, List<String> path) { |
| String name = path.remove(0); |
| |
| if (!nodes.containsKey(name)) { |
| nodes.put(name, new Node(name)); |
| } |
| |
| if (path.size() >= 1) { |
| createNode(nodes.get(name).nodes, path); |
| } |
| } |
| |
| public boolean hasAnyRole(HierarchicalRoles requested) { |
| // |
| if (requested.getNodes().isEmpty()) { |
| return true; |
| } |
| |
| Map<String, Node> requestedNodes = requested.getNodes(); |
| |
| return matchesAny(nodes, requestedNodes); |
| } |
| |
| private static boolean matchesAny(Map<String, Node> assignedNodes, Map<String, Node> requestedNodes) { |
| boolean match = false; |
| for (Node node : requestedNodes.values()) { |
| Node assigned = assignedNodes.get(node.getName()); |
| if (assigned != null) { |
| if (assigned.getNodes().size() > 0) { |
| match = matchesAny(assigned.getNodes(), node.getNodes()); |
| } else { |
| match = true; |
| } |
| } |
| } |
| |
| return match; |
| } |
| |
| public Map<String, Node> getNodes() { |
| return Collections.unmodifiableMap(nodes); |
| } |
| } |
| |