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-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
|
||||
|
|
|
@ -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