All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.spotify.helios.servicescommon.RuleBasedZooKeeperAclProvider Maven / Gradle / Ivy

There is a newer version: 0.9.9
Show newest version
/*
 * Copyright (c) 2016 Spotify AB.
 *
 * Licensed 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 com.spotify.helios.servicescommon;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import org.apache.curator.framework.api.ACLProvider;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * A ZooKeeper ACLProvider that uses regular expression-based rules to determine what ACLs govern
 * created nodes.
 * 

* The permissions for all rules that match a path apply. For example if there * are two rules: *

    *
  1. "/foo.*", DELETE, usr1
  2. *
  3. "/foo/bar", CREATE, user1
  4. *
* Then ACLs will be set so that user1 can create and delete nodes on the /foo/bar node, but he can * not delete nodes under the /foo node. */ public class RuleBasedZooKeeperAclProvider implements ACLProvider { private final ImmutableList defaultAcl; private final ImmutableList rules; public static Builder builder() { return new Builder(); } private RuleBasedZooKeeperAclProvider(final ImmutableList rules, final ImmutableList defaultAcl) { this.rules = rules; this.defaultAcl = defaultAcl; } @Override public List getDefaultAcl() { return defaultAcl; } @Override public List getAclForPath(final String path) { // id -> permissions final Map matching = Maps.newHashMap(); for (final Rule rule : rules) { if (rule.matches(path)) { final int existingPerms = matching.containsKey(rule.id) ? matching.get(rule.id) : 0; matching.put(rule.id, rule.perms | existingPerms); } } if (matching.isEmpty()) { return null; } final List acls = Lists.newArrayList(); for (final Map.Entry e : matching.entrySet()) { acls.add(new ACL(e.getValue(), e.getKey())); } return acls; } private static class Rule { private final Pattern pattern; private final Id id; private final int perms; Rule(final String regex, final int perms, final Id id) { this.pattern = Pattern.compile(regex); this.perms = perms; this.id = id; } boolean matches(final String path) { return pattern.matcher(path).matches(); } } public static class Builder { private final List rules = Lists.newArrayList(); private ImmutableList defaultAcl = ImmutableList.copyOf(ZooDefs.Ids.READ_ACL_UNSAFE); Builder defaultAcl(final ACL... acls) { return defaultAcl(Arrays.asList(acls)); } Builder defaultAcl(final List defaultAcl) { this.defaultAcl = ImmutableList.copyOf(defaultAcl); return this; } Builder rule(final String pathRegex, final int permissions, final Id id) { rules.add(new Rule(pathRegex, permissions, id)); return this; } RuleBasedZooKeeperAclProvider build() { return new RuleBasedZooKeeperAclProvider(ImmutableList.copyOf(rules), defaultAcl); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy