HBASE-2263 [stargate] multiuser mode: authenticator for zookeeper
git-svn-id: https://svn.apache.org/repos/asf/hadoop/hbase/trunk@916545 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
68aeb1831d
commit
0f39b8f477
|
@ -411,6 +411,7 @@ Release 0.21.0 - Unreleased
|
||||||
HBASE-2070 Collect HLogs and delete them after a period of time
|
HBASE-2070 Collect HLogs and delete them after a period of time
|
||||||
HBASE-2221 MR to copy a table
|
HBASE-2221 MR to copy a table
|
||||||
HBASE-2257 [stargate] multiuser mode
|
HBASE-2257 [stargate] multiuser mode
|
||||||
|
HBASE-2263 [stargate] multiuser mode: authenticator for zookeeper
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
HBASE-410 [testing] Speed up the test suite
|
HBASE-410 [testing] Speed up the test suite
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 The Apache Software Foundation
|
||||||
|
*
|
||||||
|
* 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.hadoop.hbase.stargate.auth;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.hbase.util.Bytes;
|
||||||
|
import org.apache.hadoop.hbase.zookeeper.ZooKeeperWrapper;
|
||||||
|
import org.apache.zookeeper.CreateMode;
|
||||||
|
import org.apache.zookeeper.KeeperException;
|
||||||
|
import org.apache.zookeeper.WatchedEvent;
|
||||||
|
import org.apache.zookeeper.Watcher;
|
||||||
|
import org.apache.zookeeper.ZooKeeper;
|
||||||
|
import org.apache.zookeeper.ZooDefs.Ids;
|
||||||
|
import org.apache.zookeeper.data.Stat;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple authenticator module for ZooKeeper.
|
||||||
|
* <pre>
|
||||||
|
* /stargate/
|
||||||
|
* users/
|
||||||
|
* <token></pre>
|
||||||
|
* Where <tt><token></tt> is a JSON formatted user record with the keys
|
||||||
|
* 'name' (String, required), 'token' (String, optional), 'admin' (boolean,
|
||||||
|
* optional), and 'disabled' (boolean, optional).
|
||||||
|
*/
|
||||||
|
public class ZooKeeperAuthenticator extends Authenticator {
|
||||||
|
|
||||||
|
static final String USERS_ROOT_ZNODE = "/stargate/users";
|
||||||
|
|
||||||
|
ZooKeeperWrapper wrapper;
|
||||||
|
|
||||||
|
private boolean ensureParentExists(final String znode) {
|
||||||
|
int index = znode.lastIndexOf("/");
|
||||||
|
if (index <= 0) { // Parent is root, which always exists.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return ensureExists(znode.substring(0, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean ensureExists(final String znode) {
|
||||||
|
ZooKeeper zk = wrapper.getZooKeeper();
|
||||||
|
try {
|
||||||
|
Stat stat = zk.exists(znode, false);
|
||||||
|
if (stat != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
zk.create(znode, new byte[0], Ids.OPEN_ACL_UNSAFE,
|
||||||
|
CreateMode.PERSISTENT);
|
||||||
|
return true;
|
||||||
|
} catch (KeeperException.NodeExistsException e) {
|
||||||
|
return true; // ok, move on.
|
||||||
|
} catch (KeeperException.NoNodeException e) {
|
||||||
|
return ensureParentExists(znode) && ensureExists(znode);
|
||||||
|
} catch (KeeperException e) {
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param conf
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public ZooKeeperAuthenticator(Configuration conf) throws IOException {
|
||||||
|
this(new ZooKeeperWrapper(conf, new Watcher() {
|
||||||
|
public void process(WatchedEvent event) { }
|
||||||
|
}));
|
||||||
|
ensureExists(USERS_ROOT_ZNODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param wrapper
|
||||||
|
*/
|
||||||
|
public ZooKeeperAuthenticator(ZooKeeperWrapper wrapper) {
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User getUserForToken(String token) throws IOException {
|
||||||
|
ZooKeeper zk = wrapper.getZooKeeper();
|
||||||
|
try {
|
||||||
|
byte[] data = zk.getData(USERS_ROOT_ZNODE + "/" + token, null, null);
|
||||||
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONObject o = new JSONObject(Bytes.toString(data));
|
||||||
|
if (!o.has("name")) {
|
||||||
|
throw new IOException("invalid record, missing 'name'");
|
||||||
|
}
|
||||||
|
String name = o.getString("name");
|
||||||
|
boolean admin = false;
|
||||||
|
if (o.has("admin")) { admin = o.getBoolean("admin"); }
|
||||||
|
boolean disabled = false;
|
||||||
|
if (o.has("disabled")) { disabled = o.getBoolean("disabled"); }
|
||||||
|
return new User(name, token, admin, disabled);
|
||||||
|
} catch (KeeperException.NoNodeException e) {
|
||||||
|
return null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 The Apache Software Foundation
|
||||||
|
*
|
||||||
|
* 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.hadoop.hbase.stargate.auth;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hbase.stargate.MiniClusterTestBase;
|
||||||
|
import org.apache.hadoop.hbase.util.Bytes;
|
||||||
|
|
||||||
|
import org.apache.zookeeper.CreateMode;
|
||||||
|
import org.apache.zookeeper.ZooKeeper;
|
||||||
|
import org.apache.zookeeper.ZooDefs.Ids;
|
||||||
|
|
||||||
|
import org.json.JSONStringer;
|
||||||
|
|
||||||
|
public class TestZooKeeperAuthenticator extends MiniClusterTestBase {
|
||||||
|
|
||||||
|
static final String UNKNOWN_TOKEN = "00000000000000000000000000000000";
|
||||||
|
static final String ADMIN_TOKEN = "e998efffc67c49c6e14921229a51b7b3";
|
||||||
|
static final String ADMIN_USERNAME = "testAdmin";
|
||||||
|
static final String USER_TOKEN = "da4829144e3a2febd909a6e1b4ed7cfa";
|
||||||
|
static final String USER_USERNAME = "testUser";
|
||||||
|
static final String DISABLED_TOKEN = "17de5b5db0fd3de0847bd95396f36d92";
|
||||||
|
static final String DISABLED_USERNAME = "disabledUser";
|
||||||
|
|
||||||
|
ZooKeeperAuthenticator authenticator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
authenticator = new ZooKeeperAuthenticator(conf);
|
||||||
|
ZooKeeper zk = authenticator.wrapper.getZooKeeper();
|
||||||
|
if (zk.exists(ZooKeeperAuthenticator.USERS_ROOT_ZNODE + "/" +
|
||||||
|
ADMIN_TOKEN, null) == null) {
|
||||||
|
zk.create(ZooKeeperAuthenticator.USERS_ROOT_ZNODE + "/" + ADMIN_TOKEN,
|
||||||
|
Bytes.toBytes(new JSONStringer()
|
||||||
|
.object()
|
||||||
|
.key("name").value(ADMIN_USERNAME)
|
||||||
|
.key("admin").value(true)
|
||||||
|
.endObject().toString()),
|
||||||
|
Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
|
||||||
|
}
|
||||||
|
if (zk.exists(ZooKeeperAuthenticator.USERS_ROOT_ZNODE + "/" +
|
||||||
|
USER_TOKEN, null) == null) {
|
||||||
|
zk.create(ZooKeeperAuthenticator.USERS_ROOT_ZNODE + "/" + USER_TOKEN,
|
||||||
|
Bytes.toBytes(new JSONStringer()
|
||||||
|
.object()
|
||||||
|
.key("name").value(USER_USERNAME)
|
||||||
|
.key("disabled").value(false)
|
||||||
|
.endObject().toString()),
|
||||||
|
Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
|
||||||
|
}
|
||||||
|
if (zk.exists(ZooKeeperAuthenticator.USERS_ROOT_ZNODE + "/" +
|
||||||
|
DISABLED_TOKEN, null) == null) {
|
||||||
|
zk.create(ZooKeeperAuthenticator.USERS_ROOT_ZNODE + "/" +DISABLED_TOKEN,
|
||||||
|
Bytes.toBytes(new JSONStringer()
|
||||||
|
.object()
|
||||||
|
.key("name").value(DISABLED_USERNAME)
|
||||||
|
.key("admin").value(false)
|
||||||
|
.key("disabled").value(true)
|
||||||
|
.endObject().toString()),
|
||||||
|
Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUserUnknown() throws Exception {
|
||||||
|
User user = authenticator.getUserForToken(UNKNOWN_TOKEN);
|
||||||
|
assertNull(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetAdminUser() throws Exception {
|
||||||
|
User user = authenticator.getUserForToken(ADMIN_TOKEN);
|
||||||
|
assertNotNull(user);
|
||||||
|
assertEquals(user.getName(), ADMIN_USERNAME);
|
||||||
|
assertTrue(user.isAdmin());
|
||||||
|
assertFalse(user.isDisabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetPlainUser() throws Exception {
|
||||||
|
User user = authenticator.getUserForToken(USER_TOKEN);
|
||||||
|
assertNotNull(user);
|
||||||
|
assertEquals(user.getName(), USER_USERNAME);
|
||||||
|
assertFalse(user.isAdmin());
|
||||||
|
assertFalse(user.isDisabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetDisabledUser() throws Exception {
|
||||||
|
User user = authenticator.getUserForToken(DISABLED_TOKEN);
|
||||||
|
assertNotNull(user);
|
||||||
|
assertEquals(user.getName(), DISABLED_USERNAME);
|
||||||
|
assertFalse(user.isAdmin());
|
||||||
|
assertTrue(user.isDisabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue