blob: 9d81b00f60a98276c7d779b755c565457b90d9cf [file] [log] [blame]
/*
* 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.accumulo.testing.randomwalk.security;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.security.SystemPermission;
import org.apache.accumulo.core.security.TablePermission;
import org.apache.accumulo.testing.randomwalk.RandWalkEnv;
import org.apache.accumulo.testing.randomwalk.State;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class WalkingSecurity {
State state = null;
RandWalkEnv env = null;
private static final Logger log = LoggerFactory.getLogger(WalkingSecurity.class);
private static final String tableName = "SecurityTableName";
private static final String namespaceName = "SecurityNamespaceName";
private static final String userName = "UserName";
private static final String userPass = "UserPass";
private static final String userExists = "UserExists";
private static final String tableExists = "TableExists";
private static final String namespaceExists = "NamespaceExists";
private static final String connector = "UserConnection";
private static final String authsMap = "authorizationsCountMap";
private static final String lastKey = "lastMutationKey";
private static final String filesystem = "securityFileSystem";
private static WalkingSecurity instance = null;
public WalkingSecurity(State state2, RandWalkEnv env2) {
this.state = state2;
this.env = env2;
}
public static WalkingSecurity get(State state, RandWalkEnv env) {
if (instance == null || instance.state != state) {
instance = new WalkingSecurity(state, env);
state.set(tableExists, Boolean.toString(false));
state.set(namespaceExists, Boolean.toString(false));
state.set(authsMap, new HashMap<String,Integer>());
}
return instance;
}
public void changeAuthorizations(String user, Authorizations authorizations)
throws AccumuloSecurityException {
state.set(user + "_auths", authorizations);
state.set("Auths-" + user + '-' + "time", System.currentTimeMillis());
}
public boolean ambiguousAuthorizations(String userName) {
Long setTime = state.getLong("Auths-" + userName + '-' + "time");
if (setTime == null)
throw new RuntimeException("Auths-" + userName + '-' + "time is null");
if (System.currentTimeMillis() < (setTime + 1000))
return true;
return false;
}
public void createUser(String principal, AuthenticationToken token)
throws AccumuloSecurityException {
state.set(principal + userExists, Boolean.toString(true));
changePassword(principal, token);
cleanUser(principal);
}
public void dropUser(String user) throws AccumuloSecurityException {
state.set(user + userExists, Boolean.toString(false));
cleanUser(user);
if (user.equals(getTabUserName()))
state.set("table" + connector, null);
}
public void changePassword(String principal, AuthenticationToken token)
throws AccumuloSecurityException {
state.set(principal + userPass, token);
state.set(principal + userPass + "time", System.currentTimeMillis());
}
public boolean userExists(String user) {
return Boolean.parseBoolean(state.getString(user + userExists));
}
public boolean hasSystemPermission(String user, SystemPermission permission)
throws AccumuloSecurityException {
boolean res = Boolean.parseBoolean(state.getString("Sys-" + user + '-' + permission.name()));
return res;
}
public boolean hasTablePermission(String user, String table, TablePermission permission)
throws AccumuloSecurityException, TableNotFoundException {
return Boolean.parseBoolean(state.getString("Tab-" + user + '-' + permission.name()));
}
public void grantSystemPermission(String user, SystemPermission permission)
throws AccumuloSecurityException {
setSysPerm(state, user, permission, true);
}
public void revokeSystemPermission(String user, SystemPermission permission)
throws AccumuloSecurityException {
setSysPerm(state, user, permission, false);
}
public void grantTablePermission(String user, String table, TablePermission permission)
throws AccumuloSecurityException, TableNotFoundException {
setTabPerm(state, user, permission, table, true);
}
private static void setSysPerm(State state, String userName, SystemPermission tp, boolean value) {
log.debug((value ? "Gave" : "Took") + " the system permission " + tp.name()
+ (value ? " to" : " from") + " user " + userName);
state.set("Sys-" + userName + '-' + tp.name(), Boolean.toString(value));
}
private void setTabPerm(State state, String userName, TablePermission tp, String table,
boolean value) {
if (table.equals(userName))
throw new RuntimeException("Something went wrong: table is equal to userName: " + userName);
log.debug((value ? "Gave" : "Took") + " the table permission " + tp.name()
+ (value ? " to" : " from") + " user " + userName);
state.set("Tab-" + userName + '-' + tp.name(), Boolean.toString(value));
if (tp.equals(TablePermission.READ) || tp.equals(TablePermission.WRITE))
state.set("Tab-" + userName + '-' + tp.name() + '-' + "time", System.currentTimeMillis());
}
public void revokeTablePermission(String user, String table, TablePermission permission)
throws AccumuloSecurityException, TableNotFoundException {
setTabPerm(state, user, permission, table, false);
}
public void cleanTablePermissions(String table)
throws AccumuloSecurityException, TableNotFoundException {
for (String user : new String[] {getSysUserName(), getTabUserName()}) {
for (TablePermission tp : TablePermission.values()) {
revokeTablePermission(user, table, tp);
}
}
state.set(tableExists, Boolean.toString(false));
}
public void cleanUser(String user) throws AccumuloSecurityException {
if (getTableExists())
for (TablePermission tp : TablePermission.values())
try {
revokeTablePermission(user, getTableName(), tp);
} catch (TableNotFoundException e) {
// ignore
}
for (SystemPermission sp : SystemPermission.values())
revokeSystemPermission(user, sp);
}
public String getTabUserName() {
return state.getString("table" + userName);
}
public String getSysUserName() {
return state.getString("system" + userName);
}
public void setTabUserName(String name) {
state.set("table" + userName, name);
state.set(name + userExists, Boolean.toString(false));
}
public void setSysUserName(String name) {
state.set("system" + userName, name);
}
public String getTableName() {
return state.getString(tableName);
}
public String getNamespaceName() {
return state.getString(namespaceName);
}
public boolean getTableExists() {
return Boolean.parseBoolean(state.getString(tableExists));
}
public boolean getNamespaceExists() {
return Boolean.parseBoolean(state.getString(namespaceExists));
}
public AuthenticationToken getSysToken() {
return new PasswordToken(getSysPassword());
}
public AuthenticationToken getTabToken() {
return new PasswordToken(getTabPassword());
}
public byte[] getUserPassword(String user) {
Object obj = state.get(user + userPass);
if (obj instanceof PasswordToken) {
return ((PasswordToken) obj).getPassword();
}
return null;
}
public byte[] getSysPassword() {
Object obj = state.get(getSysUserName() + userPass);
if (obj instanceof PasswordToken) {
return ((PasswordToken) obj).getPassword();
}
return null;
}
public byte[] getTabPassword() {
Object obj = state.get(getTabUserName() + userPass);
if (obj instanceof PasswordToken) {
return ((PasswordToken) obj).getPassword();
}
return null;
}
public boolean userPassTransient(String user) {
return System.currentTimeMillis() - state.getLong(user + userPass + "time") < 1000;
}
public void setTableName(String tName) {
state.set(tableName, tName);
}
public void setNamespaceName(String nsName) {
state.set(namespaceName, nsName);
}
public void initTable(String table) throws AccumuloSecurityException {
state.set(tableExists, Boolean.toString(true));
state.set(tableName, table);
}
public String[] getAuthsArray() {
return new String[] {"Fishsticks", "PotatoSkins", "Ribs", "Asparagus", "Paper", "Towels",
"Lint", "Brush", "Celery"};
}
public boolean inAmbiguousZone(String userName, TablePermission tp) {
if (tp.equals(TablePermission.READ) || tp.equals(TablePermission.WRITE)) {
Long setTime = state.getLong("Tab-" + userName + '-' + tp.name() + '-' + "time");
if (setTime == null)
throw new RuntimeException("Tab-" + userName + '-' + tp.name() + '-' + "time is null");
if (System.currentTimeMillis() < (setTime + 1000))
return true;
}
return false;
}
@SuppressWarnings("unchecked")
public Map<String,Integer> getAuthsMap() {
return (Map<String,Integer>) state.get(authsMap);
}
public String getLastKey() {
return state.getString(lastKey);
}
public void increaseAuthMap(String s, int increment) {
Integer curVal = getAuthsMap().get(s);
if (curVal == null) {
curVal = Integer.valueOf(0);
getAuthsMap().put(s, curVal);
}
curVal += increment;
}
public FileSystem getFs() {
FileSystem fs = null;
try {
fs = (FileSystem) state.get(filesystem);
} catch (RuntimeException re) {}
if (fs == null) {
try {
fs = FileSystem.get(new Configuration());
} catch (IOException e) {
throw new RuntimeException(e);
}
state.set(filesystem, fs);
}
return fs;
}
public static void clearInstance() {
instance = null;
}
}