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:
Andrew Kyle Purtell 2010-02-26 03:00:47 +00:00
parent 68aeb1831d
commit 0f39b8f477
3 changed files with 238 additions and 0 deletions

View File

@ -411,6 +411,7 @@ Release 0.21.0 - Unreleased
HBASE-2070 Collect HLogs and delete them after a period of time
HBASE-2221 MR to copy a table
HBASE-2257 [stargate] multiuser mode
HBASE-2263 [stargate] multiuser mode: authenticator for zookeeper
OPTIMIZATIONS
HBASE-410 [testing] Speed up the test suite

View File

@ -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/
* &lt;token&gt;</pre>
* Where <tt>&lt;token&gt;</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);
}
}
}

View File

@ -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());
}
}