http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-common/src/main/java/com/xasecure/authorization/utils/StringUtil.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/com/xasecure/authorization/utils/StringUtil.java b/agents-common/src/main/java/com/xasecure/authorization/utils/StringUtil.java deleted file mode 100644 index 7e3dccd..0000000 --- a/agents-common/src/main/java/com/xasecure/authorization/utils/StringUtil.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * 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 com.xasecure.authorization.utils; - -import java.util.Calendar; -import java.util.Collection; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.List; -import java.util.TimeZone; - -public class StringUtil { - - private static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT+0"); - - public static boolean equals(String str1, String str2) { - boolean ret = false; - - if(str1 == null) { - ret = str2 == null; - } else if(str2 == null) { - ret = false; - } else { - ret = str1.equals(str2); - } - - return ret; - } - - public static boolean equalsIgnoreCase(String str1, String str2) { - boolean ret = false; - - if(str1 == null) { - ret = str2 == null; - } else if(str2 == null) { - ret = false; - } else { - ret = str1.equalsIgnoreCase(str2); - } - - return ret; - } - - public static boolean equals(Collection<String> set1, Collection<String> set2) { - boolean ret = false; - - if(set1 == null) { - ret = set2 == null; - } else if(set2 == null) { - ret = false; - } else if(set1.size() == set2.size()) { - ret = set1.containsAll(set2); - } - - return ret; - } - - public static boolean equalsIgnoreCase(Collection<String> set1, Collection<String> set2) { - boolean ret = false; - - if(set1 == null) { - ret = set2 == null; - } else if(set2 == null) { - ret = false; - } else if(set1.size() == set2.size()) { - int numFound = 0; - - for(String str1 : set1) { - boolean str1Found = false; - - for(String str2 : set2) { - if(equalsIgnoreCase(str1, str2)) { - str1Found = true; - - break; - } - } - - if(str1Found) { - numFound++; - } else { - break; - } - } - - ret = numFound == set1.size(); - } - - return ret; - } - - public static boolean matches(String pattern, String str) { - boolean ret = false; - - if(pattern == null || str == null || pattern.isEmpty() || str.isEmpty()) { - ret = true; - } else { - ret = str.matches(pattern); - } - - return ret; - } - - /* - public static boolean matches(Collection<String> patternSet, Collection<String> strSet) { - boolean ret = false; - - if(patternSet == null || strSet == null || patternSet.isEmpty() || strSet.isEmpty()) { - ret = true; - } else { - boolean foundUnmatched = false; - - for(String str : strSet) { - boolean isMatched = false; - for(String pattern : patternSet) { - isMatched = str.matches(pattern); - - if(isMatched) { - break; - } - } - - foundUnmatched = ! isMatched; - - if(foundUnmatched) { - break; - } - } - - ret = !foundUnmatched; - } - - return ret; - } - */ - - public static boolean contains(String str, String strToFind) { - boolean ret = false; - - if(str != null && strToFind != null) { - ret = str.contains(strToFind); - } - - return ret; - } - - public static boolean containsIgnoreCase(String str, String strToFind) { - boolean ret = false; - - if(str != null && strToFind != null) { - ret = str.toLowerCase().contains(strToFind.toLowerCase()); - } - - return ret; - } - - public static boolean contains(String[] strArr, String str) { - boolean ret = false; - - if(strArr != null && strArr.length > 0 && str != null) { - for(String s : strArr) { - ret = equals(s, str); - - if(ret) { - break; - } - } - } - - return ret; - } - - public static boolean containsIgnoreCase(String[] strArr, String str) { - boolean ret = false; - - if(strArr != null && strArr.length > 0 && str != null) { - for(String s : strArr) { - ret = equalsIgnoreCase(s, str); - - if(ret) { - break; - } - } - } - - return ret; - } - - public static String toString(Iterable<String> iterable) { - String ret = ""; - - if(iterable != null) { - int count = 0; - for(String str : iterable) { - if(count == 0) - ret = str; - else - ret += (", " + str); - count++; - } - } - - return ret; - } - - public static String toString(String[] arr) { - String ret = ""; - - if(arr != null && arr.length > 0) { - ret = arr[0]; - for(int i = 1; i < arr.length; i++) { - ret += (", " + arr[i]); - } - } - - return ret; - } - - public static String toString(List<String> arr) { - String ret = ""; - - if(arr != null && arr.size() > 0) { - ret = arr.get(0); - for(int i = 1; i < arr.size(); i++) { - ret += (", " + arr.get(i)); - } - } - - return ret; - } - - public static boolean isEmpty(String str) { - return str == null || str.trim().isEmpty(); - } - - public static <T> boolean isEmpty(Collection<T> set) { - return set == null || set.isEmpty(); - } - - public static String toLower(String str) { - return str == null ? null : str.toLowerCase(); - } - - public static byte[] getBytes(String str) { - return str == null ? null : str.getBytes(); - } - - public static Date getUTCDate() { - Calendar local = Calendar.getInstance(); - int offset = local.getTimeZone().getOffset(local.getTimeInMillis()); - - GregorianCalendar utc = new GregorianCalendar(gmtTimeZone); - - utc.setTimeInMillis(local.getTimeInMillis()); - utc.add(Calendar.MILLISECOND, -offset); - - return utc.getTime(); - } -}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminClient.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminClient.java b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminClient.java new file mode 100644 index 0000000..a9c2a9a --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminClient.java @@ -0,0 +1,32 @@ +/* + * 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.ranger.admin.client; + + +import org.apache.ranger.admin.client.datatype.GrantRevokeData; + + +public interface RangerAdminClient { + String getPolicies(String repositoryName, long lastModifiedTime, int policyCount, String agentName); + + void grantPrivilege(GrantRevokeData grData) throws Exception; + + void revokePrivilege(GrantRevokeData grData) throws Exception; +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java new file mode 100644 index 0000000..d883dd3 --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java @@ -0,0 +1,389 @@ +/* + * 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.ranger.admin.client; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; + +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.config.ClientConfig; +import com.sun.jersey.api.client.config.DefaultClientConfig; +import com.sun.jersey.client.urlconnection.HTTPSProperties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.ranger.admin.client.datatype.GrantRevokeData; +import org.apache.ranger.admin.client.datatype.RESTResponse; +import org.apache.ranger.authorization.hadoop.config.RangerConfiguration; +import org.apache.ranger.authorization.hadoop.utils.RangerCredentialProvider; +import org.apache.ranger.authorization.utils.StringUtil; + + +public class RangerAdminRESTClient implements RangerAdminClient { + private static final Log LOG = LogFactory.getLog(RangerAdminRESTClient.class); + + public static final String RANGER_PROP_POLICYMGR_URL = "xasecure.policymgr.url"; + public static final String RANGER_PROP_POLICYMGR_SSLCONFIG_FILENAME = "xasecure.policymgr.sslconfig.filename"; + + public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE = "xasecure.policymgr.clientssl.keystore"; + public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_PASSWORD = "xasecure.policymgr.clientssl.keystore.password"; + public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_TYPE = "xasecure.policymgr.clientssl.keystore.type"; + public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_CREDENTIAL = "xasecure.policymgr.clientssl.keystore.credential.file"; + public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_CREDENTIAL_ALIAS = "sslKeyStore"; + public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_TYPE_DEFAULT = "jks"; + + public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE = "xasecure.policymgr.clientssl.truststore"; + public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_PASSWORD = "xasecure.policymgr.clientssl.truststore.password"; + public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_TYPE = "xasecure.policymgr.clientssl.truststore.type"; + public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_CREDENTIAL = "xasecure.policymgr.clientssl.truststore.credential.file"; + public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_CREDENTIAL_ALIAS = "sslTrustStore"; + public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_TYPE_DEFAULT = "jks"; + + public static final String RANGER_SSL_KEYMANAGER_ALGO_TYPE = "SunX509" ; + public static final String RANGER_SSL_TRUSTMANAGER_ALGO_TYPE = "SunX509" ; + public static final String RANGER_SSL_CONTEXT_ALGO_TYPE = "SSL" ; + + public static final String REST_EXPECTED_MIME_TYPE = "application/json" ; + + private static final String REST_URL_PATH_POLICYLIST = "/service/assets/policyList/"; + private static final String REST_URL_PATH_GRANT = "/service/assets/resources/grant"; + private static final String REST_URL_PATH_REVOKE = "/service/assets/resources/revoke"; + private static final String REST_URL_PARAM_LASTUPDATED_TIME = "epoch"; + private static final String REST_URL_PARAM_POLICY_COUNT = "policyCount"; + private static final String REST_URL_PARAM_AGENT_NAME = "agentId"; + + private String mUrl = null; + private String mSslConfigFileName = null; + private boolean mIsSSL = false; + + private String mKeyStoreURL = null; + private String mKeyStoreAlias = null; + private String mKeyStoreFile = null; + private String mKeyStoreType = null; + private String mTrustStoreURL = null; + private String mTrustStoreAlias = null; + private String mTrustStoreFile = null; + private String mTrustStoreType = null; + + + public RangerAdminRESTClient() { + mUrl = RangerConfiguration.getInstance().get(RANGER_PROP_POLICYMGR_URL); + mSslConfigFileName = RangerConfiguration.getInstance().get(RANGER_PROP_POLICYMGR_SSLCONFIG_FILENAME); + + init(); + } + + public RangerAdminRESTClient(String url, String sslConfigFileName) { + mUrl = url; + mSslConfigFileName = sslConfigFileName; + + init(); + } + + @Override + public String getPolicies(String repositoryName, long lastModifiedTime, int policyCount, String agentName) { + String ret = null; + Client client = null; + + try { + client = buildClient(); + + WebResource webResource = client.resource(mUrl + REST_URL_PATH_POLICYLIST + repositoryName) + .queryParam(REST_URL_PARAM_LASTUPDATED_TIME, String.valueOf(lastModifiedTime)) + .queryParam(REST_URL_PARAM_POLICY_COUNT, String.valueOf(policyCount)) + .queryParam(REST_URL_PARAM_AGENT_NAME, agentName); + + ClientResponse response = webResource.accept(REST_EXPECTED_MIME_TYPE).get(ClientResponse.class); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(String.class); + } + } finally { + destroy(client); + } + + return ret; + } + + @Override + public void grantPrivilege(GrantRevokeData grData) throws Exception { + Client client = null; + + try { + client = buildClient(); + + WebResource webResource = client.resource(mUrl + REST_URL_PATH_GRANT); + + ClientResponse response = webResource.accept(REST_EXPECTED_MIME_TYPE).type(REST_EXPECTED_MIME_TYPE).post(ClientResponse.class, grData.toJson()); + + if(response == null || response.getStatus() != 200) { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + } finally { + destroy(client); + } + } + + @Override + public void revokePrivilege(GrantRevokeData grData) throws Exception { + Client client = null; + + try { + client = buildClient(); + + WebResource webResource = client.resource(mUrl + REST_URL_PATH_REVOKE); + + ClientResponse response = webResource.accept(REST_EXPECTED_MIME_TYPE).type(REST_EXPECTED_MIME_TYPE).post(ClientResponse.class, grData.toJson()); + + if(response == null || response.getStatus() != 200) { + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + } finally { + destroy(client); + } + } + private void init() { + mIsSSL = StringUtil.containsIgnoreCase(mUrl, "https"); + + InputStream in = null ; + + try { + Configuration conf = new Configuration() ; + + in = getFileInputStream(mSslConfigFileName) ; + + if (in != null) { + conf.addResource(in); + } + + mKeyStoreURL = conf.get(RANGER_POLICYMGR_CLIENT_KEY_FILE_CREDENTIAL); + mKeyStoreAlias = RANGER_POLICYMGR_CLIENT_KEY_FILE_CREDENTIAL_ALIAS; + mKeyStoreType = conf.get(RANGER_POLICYMGR_CLIENT_KEY_FILE_TYPE, RANGER_POLICYMGR_CLIENT_KEY_FILE_TYPE_DEFAULT); + mKeyStoreFile = conf.get(RANGER_POLICYMGR_CLIENT_KEY_FILE); + + mTrustStoreURL = conf.get(RANGER_POLICYMGR_TRUSTSTORE_FILE_CREDENTIAL); + mTrustStoreAlias = RANGER_POLICYMGR_TRUSTSTORE_FILE_CREDENTIAL_ALIAS; + mTrustStoreType = conf.get(RANGER_POLICYMGR_TRUSTSTORE_FILE_TYPE, RANGER_POLICYMGR_TRUSTSTORE_FILE_TYPE_DEFAULT); + mTrustStoreFile = conf.get(RANGER_POLICYMGR_TRUSTSTORE_FILE); + } + catch(IOException ioe) { + LOG.error("Unable to load SSL Config FileName: [" + mSslConfigFileName + "]", ioe); + } + finally { + close(in, mSslConfigFileName); + } + } + + private synchronized Client buildClient() { + Client client = null; + + if (mIsSSL) { + KeyManager[] kmList = getKeyManagers(); + TrustManager[] tmList = getTrustManagers(); + SSLContext sslContext = getSSLContext(kmList, tmList); + ClientConfig config = new DefaultClientConfig(); + + HostnameVerifier hv = new HostnameVerifier() { + public boolean verify(String urlHostName, SSLSession session) { + return session.getPeerHost().equals(urlHostName); + } + }; + + config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(hv, sslContext)); + + client = Client.create(config); + } + + if(client == null) { + client = Client.create(); + } + + return client; + } + + private KeyManager[] getKeyManagers() { + KeyManager[] kmList = null; + + String keyStoreFilepwd = getCredential(mKeyStoreURL, mKeyStoreAlias); + + if (!StringUtil.isEmpty(mKeyStoreFile) && !StringUtil.isEmpty(keyStoreFilepwd)) { + InputStream in = null ; + + try { + in = getFileInputStream(mKeyStoreFile) ; + + if (in != null) { + KeyStore keyStore = KeyStore.getInstance(mKeyStoreType); + + keyStore.load(in, keyStoreFilepwd.toCharArray()); + + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(RANGER_SSL_KEYMANAGER_ALGO_TYPE); + + keyManagerFactory.init(keyStore, keyStoreFilepwd.toCharArray()); + + kmList = keyManagerFactory.getKeyManagers(); + } else { + LOG.error("Unable to obtain keystore from file [" + mKeyStoreFile + "]"); + } + } catch (KeyStoreException e) { + LOG.error("Unable to obtain from KeyStore", e); + } catch (NoSuchAlgorithmException e) { + LOG.error("SSL algorithm is available in the environment", e); + } catch (CertificateException e) { + LOG.error("Unable to obtain the requested certification ", e); + } catch (FileNotFoundException e) { + LOG.error("Unable to find the necessary SSL Keystore and TrustStore Files", e); + } catch (IOException e) { + LOG.error("Unable to read the necessary SSL Keystore and TrustStore Files", e); + } catch (UnrecoverableKeyException e) { + LOG.error("Unable to recover the key from keystore", e); + } finally { + close(in, mKeyStoreFile); + } + } + + return kmList; + } + + private TrustManager[] getTrustManagers() { + TrustManager[] tmList = null; + + String trustStoreFilepwd = getCredential(mTrustStoreURL, mTrustStoreAlias); + + if (!StringUtil.isEmpty(mTrustStoreFile) && !StringUtil.isEmpty(trustStoreFilepwd)) { + InputStream in = null ; + + try { + in = getFileInputStream(mTrustStoreFile) ; + + if (in != null) { + KeyStore trustStore = KeyStore.getInstance(mTrustStoreType); + + trustStore.load(in, trustStoreFilepwd.toCharArray()); + + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(RANGER_SSL_TRUSTMANAGER_ALGO_TYPE); + + trustManagerFactory.init(trustStore); + + tmList = trustManagerFactory.getTrustManagers(); + } else { + LOG.error("Unable to obtain keystore from file [" + mTrustStoreFile + "]"); + } + } catch (KeyStoreException e) { + LOG.error("Unable to obtain from KeyStore", e); + } catch (NoSuchAlgorithmException e) { + LOG.error("SSL algorithm is available in the environment", e); + } catch (CertificateException e) { + LOG.error("Unable to obtain the requested certification ", e); + } catch (FileNotFoundException e) { + LOG.error("Unable to find the necessary SSL Keystore and TrustStore Files", e); + } catch (IOException e) { + LOG.error("Unable to read the necessary SSL Keystore and TrustStore Files", e); + } finally { + close(in, mTrustStoreFile); + } + } + + return tmList; + } + + private SSLContext getSSLContext(KeyManager[] kmList, TrustManager[] tmList) { + try { + if(kmList != null && tmList != null) { + SSLContext sslContext = SSLContext.getInstance(RANGER_SSL_CONTEXT_ALGO_TYPE); + + sslContext.init(kmList, tmList, new SecureRandom()); + + return sslContext; + } + } catch (NoSuchAlgorithmException e) { + LOG.error("SSL algorithm is available in the environment", e); + } catch (KeyManagementException e) { + LOG.error("Unable to initials the SSLContext", e); + } + + return null; + } + + private String getCredential(String url, String alias) { + char[] credStr = RangerCredentialProvider.getInstance().getCredentialString(url, alias); + + return credStr == null ? null : new String(credStr); + } + + private InputStream getFileInputStream(String fileName) throws IOException { + InputStream in = null ; + + if(! StringUtil.isEmpty(fileName)) { + File f = new File(fileName) ; + + if (f.exists()) { + in = new FileInputStream(f) ; + } + else { + in = ClassLoader.getSystemResourceAsStream(fileName) ; + } + } + + return in ; + } + + private void close(InputStream str, String filename) { + if (str != null) { + try { + str.close() ; + } catch (IOException excp) { + LOG.error("Error while closing file: [" + filename + "]", excp) ; + } + } + } + + private void destroy(Client client) { + if(client != null) { + client.destroy(); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-common/src/main/java/org/apache/ranger/admin/client/datatype/GrantRevokeData.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/admin/client/datatype/GrantRevokeData.java b/agents-common/src/main/java/org/apache/ranger/admin/client/datatype/GrantRevokeData.java new file mode 100644 index 0000000..b9496be --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/admin/client/datatype/GrantRevokeData.java @@ -0,0 +1,272 @@ +/* + * 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.ranger.admin.client.datatype; + + +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; + +import org.apache.ranger.authorization.utils.StringUtil; +import org.codehaus.jackson.JsonGenerationException; +import org.codehaus.jackson.annotate.JsonAutoDetect; +import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.codehaus.jackson.map.JsonMappingException; +import org.codehaus.jackson.map.ObjectMapper; + + +@JsonAutoDetect(getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, fieldVisibility = Visibility.ANY) +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class GrantRevokeData implements java.io.Serializable { + private static final long serialVersionUID = 1L; + + private String grantor; + private String repositoryName; + private String repositoryType; + private String databases; + private String tables; + private String columns; + private String columnFamilies; + private boolean isEnabled; + private boolean isAuditEnabled; + private boolean replacePerm; + private List<PermMap> permMapList = new ArrayList<PermMap>(); + + private static String WILDCARD_ASTERISK = "*"; + + + public GrantRevokeData() { + } + + public String getGrantor() { + return grantor; + } + + public void setGrantor(String grantor) { + this.grantor = grantor; + } + + public String getRepositoryName() { + return repositoryName; + } + + public void setRepositoryName(String repositoryName) { + this.repositoryName = repositoryName; + } + + public String getRepositoryType() { + return repositoryType; + } + + public void setRepositoryType(String repositoryType) { + this.repositoryType = repositoryType; + } + + public String getDatabases() { + return databases; + } + + public void setDatabases(String databases) { + this.databases = databases; + } + + public String getTables() { + return tables; + } + + public void setTables(String tables) { + this.tables = tables; + } + + public String getColumns() { + return columns; + } + + public void setColumns(String columns) { + this.columns = columns; + } + + public String getColumnFamilies() { + return columnFamilies; + } + + public void setColumnFamilies(String columnFamilies) { + this.columnFamilies = columnFamilies; + } + + public List<PermMap> getPermMapList() { + return permMapList; + } + + public void setPermMapList(List<PermMap> permMapList) { + this.permMapList = permMapList; + } + + + public void setHiveData(String grantor, + String repositoryName, + String databases, + String tables, + String columns, + PermMap permMap) { + this.grantor = grantor; + this.repositoryName = repositoryName; + this.repositoryType = "hive"; + this.databases = StringUtil.isEmpty(databases) ? WILDCARD_ASTERISK : databases; + this.tables = StringUtil.isEmpty(tables) ? WILDCARD_ASTERISK : tables; + this.columns = StringUtil.isEmpty(columns) ? WILDCARD_ASTERISK : columns; + this.isAuditEnabled = true; + this.isEnabled = true; + this.replacePerm = false; + this.permMapList.add(permMap); + } + + public void setHBaseData(String grantor, + String repositoryName, + String tables, + String columns, + String columnFamilies, + PermMap permMap) { + this.grantor = grantor; + this.repositoryName = repositoryName; + this.repositoryType = "hbase"; + this.tables = StringUtil.isEmpty(tables) ? WILDCARD_ASTERISK : tables; + this.columns = StringUtil.isEmpty(columns) ? WILDCARD_ASTERISK : columns; + this.columnFamilies = StringUtil.isEmpty(columnFamilies) ? WILDCARD_ASTERISK : columnFamilies; + this.isAuditEnabled = true; + this.isEnabled = true; + this.replacePerm = true; + this.permMapList.add(permMap); + } + + public String toJson() { + try { + ObjectMapper om = new ObjectMapper(); + + return om.writeValueAsString(this); + } catch (JsonGenerationException e) { + e.printStackTrace(); + } catch (JsonMappingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + return ""; + } + + @Override + public String toString() { + return toJson(); + } + + + @JsonAutoDetect(getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, fieldVisibility = Visibility.ANY) + @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public static class PermMap { + private List<String> userList = new ArrayList<String>(); + private List<String> groupList = new ArrayList<String>(); + private List<String> permList = new ArrayList<String>(); + + public PermMap() { + } + + public PermMap(String user, String group, String perm) { + addUser(user); + addGroup(group); + addPerm(perm); + } + + public PermMap(List<String> userList, List<String> groupList, List<String> permList) { + copyList(userList, this.userList); + copyList(groupList, this.groupList); + copyList(permList, this.permList); + } + + public List<String> getUserList() { + return userList; + } + + public List<String> getGroupList() { + return groupList; + } + + public List<String> getPermList() { + return permList; + } + + public void addUser(String user) { + addToList(user, userList); + } + + public void addGroup(String group) { + addToList(group, groupList); + } + + public void addPerm(String perm) { + addToList(perm, permList); + } + + private void addToList(String str, List<String> list) { + if(list != null && !StringUtil.isEmpty(str)) { + list.add(str); + } + } + + private void copyList(List<String> fromList, List<String> toList) { + if(fromList != null && toList != null) { + for(String str : fromList) { + addToList(str, toList); + } + } + } + + public String toJson() { + try { + ObjectMapper om = new ObjectMapper(); + + return om.writeValueAsString(this); + } catch (JsonGenerationException e) { + e.printStackTrace(); + } catch (JsonMappingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + return ""; + } + + @Override + public String toString() { + return toJson(); + } + } + + public static void main(String[] args) { + GrantRevokeData grData = new GrantRevokeData(); + + System.out.println(grData.toString()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-common/src/main/java/org/apache/ranger/admin/client/datatype/RESTResponse.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/admin/client/datatype/RESTResponse.java b/agents-common/src/main/java/org/apache/ranger/admin/client/datatype/RESTResponse.java new file mode 100644 index 0000000..6f0547f --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/admin/client/datatype/RESTResponse.java @@ -0,0 +1,208 @@ +/** + * + * 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.ranger.admin.client.datatype; + +import java.util.List; + +import org.apache.log4j.Logger; +import org.apache.ranger.authorization.utils.StringUtil; +import org.codehaus.jackson.annotate.JsonAutoDetect; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.annotate.JsonSerialize; + +import com.sun.jersey.api.client.ClientResponse; + + +@JsonAutoDetect(getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, fieldVisibility = Visibility.ANY) +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class RESTResponse { + private static Logger LOG = Logger.getLogger(RESTResponse.class); + + private int httpStatusCode; + private int statusCode; + private String msgDesc; + private List<Message> messageList; + + + public int getHttpStatusCode() { + return httpStatusCode; + } + + public void setHttpStatusCode(int httpStatusCode) { + this.httpStatusCode = httpStatusCode; + } + + public int getStatusCode() { + return statusCode; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + + public String getMsgDesc() { + return msgDesc; + } + + public void setMsgDesc(String msgDesc) { + this.msgDesc = msgDesc; + } + + public List<Message> getMessageList() { + return messageList; + } + + public void setMessageList(List<Message> messageList) { + this.messageList = messageList; + } + + public String getMessage() { + return StringUtil.isEmpty(msgDesc) ? ("HTTP " + httpStatusCode) : msgDesc; + } + + public static RESTResponse fromClientResponse(ClientResponse response) { + RESTResponse ret = null; + + String jsonString = response == null ? null : response.getEntity(String.class); + int httpStatus = response == null ? 0 : response.getStatus(); + + if(! StringUtil.isEmpty(jsonString)) { + ret = RESTResponse.fromJson(jsonString); + } + + if(ret == null) { + ret = new RESTResponse(); + } + + ret.setHttpStatusCode(httpStatus); + + return ret; + } + + public String toJson() { + try { + ObjectMapper om = new ObjectMapper(); + + return om.writeValueAsString(this); + } catch (Exception e) { + if(LOG.isDebugEnabled()) { + LOG.debug("toJson() failed", e); + } + } + + return ""; + } + + public static RESTResponse fromJson(String jsonString) { + try { + ObjectMapper om = new ObjectMapper(); + + return om.readValue(jsonString, RESTResponse.class); + } catch (Exception e) { + if(LOG.isDebugEnabled()) { + LOG.debug("fromJson('" + jsonString + "') failed", e); + } + } + + return null; + } + + @Override + public String toString() { + return toJson(); + } + + @JsonAutoDetect(getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, fieldVisibility = Visibility.ANY) + @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Message { + private String name; + private String rbKey; + private String message; + private Long objectId; + private String fieldName; + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getRbKey() { + return rbKey; + } + public void setRbKey(String rbKey) { + this.rbKey = rbKey; + } + public String getMessage() { + return message; + } + public void setMessage(String message) { + this.message = message; + } + public Long getObjectId() { + return objectId; + } + public void setObjectId(Long objectId) { + this.objectId = objectId; + } + public String getFieldName() { + return fieldName; + } + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public String toJson() { + try { + ObjectMapper om = new ObjectMapper(); + + return om.writeValueAsString(this); + } catch (Exception e) { + if(LOG.isDebugEnabled()) { + LOG.debug("toJson() failed", e); + } + } + + return ""; + } + + public static RESTResponse fromJson(String jsonString) { + try { + ObjectMapper om = new ObjectMapper(); + + return om.readValue(jsonString, RESTResponse.class); + } catch (Exception e) { + if(LOG.isDebugEnabled()) { + LOG.debug("fromJson('" + jsonString + "') failed", e); + } + } + + return null; + } + + @Override + public String toString() { + return toJson(); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/config/RangerConfiguration.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/config/RangerConfiguration.java b/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/config/RangerConfiguration.java new file mode 100644 index 0000000..a959b6b --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/config/RangerConfiguration.java @@ -0,0 +1,164 @@ +/* + * 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.ranger.authorization.hadoop.config; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Properties; + +import org.apache.hadoop.conf.Configuration; +import org.apache.log4j.Logger; +import org.apache.ranger.audit.provider.AuditProviderFactory; +import org.apache.ranger.authorization.hadoop.constants.RangerHadoopConstants; + +public class RangerConfiguration extends Configuration { + + private static final Logger LOG = Logger.getLogger(RangerConfiguration.class) ; + + private static RangerConfiguration config = null; + + private RangerConfiguration() { + super(false) ; + + // + // WorkAround for having all Hadoop Configuration in the CLASSPATH first, even if it is invoked by Hive Engine. + // + // So, we look for "hive-site.xml", if it is available, take the xasecure-audit.xml file from the same location. + // If we do not see "hive-site.xml", we look for "hbase-site.xml", if found, take the xasecure-audit.xml file from the same location. + // If we do not see "hbase-site.xml", we look for "hdfs-site.xml", if found, take the xasecure-audit.xml file from the same location. + // If we do not see, we let the CLASSPATH based search to find xasecure-audit.xml file. + + + URL auditFileLocation = getRangerAuditXMLFileLocation() ; + + if (auditFileLocation != null) { + addResource(auditFileLocation) ; + } + else { + addResourceIfReadable(RangerHadoopConstants.RANGER_AUDIT_FILE) ; + } + addResourceIfReadable(RangerHadoopConstants.RANGER_HDFS_SECURITY_FILE); + addResourceIfReadable(RangerHadoopConstants.RANGER_KNOX_SECURITY_FILE); + addResourceIfReadable(RangerHadoopConstants.RANGER_HBASE_SECURITY_FILE) ; + addResourceIfReadable(RangerHadoopConstants.RANGER_HIVE_SECURITY_FILE) ; + addResourceIfReadable(RangerHadoopConstants.RANGER_STORM_SECURITY_FILE); + + } + + @SuppressWarnings("deprecation") + private void addResourceIfReadable(String aResourceName) { + String fName = getFileLocation(aResourceName) ; + if (fName != null) { + File f = new File(fName) ; + if (f.exists() && f.canRead()) { + URL fUrl = null ; + try { + fUrl = f.toURL() ; + addResource(fUrl) ; + } catch (MalformedURLException e) { + LOG.debug("Unable to find URL for the resource name [" + aResourceName +"]. Ignoring the resource:" + aResourceName); + } + } + } + } + + + public static RangerConfiguration getInstance() { + if (config == null) { + synchronized (RangerConfiguration.class) { + RangerConfiguration temp = config; + if (temp == null) { + config = new RangerConfiguration(); + } + } + } + return config; + } + + public void initAudit(AuditProviderFactory.ApplicationType appType) { + AuditProviderFactory auditFactory = AuditProviderFactory.getInstance(); + + if(auditFactory == null) { + LOG.error("Unable to find the AuditProviderFactory. (null) found") ; + return; + } + + Properties props = getProps(); + + if(props == null) { + return; + } + + if(! auditFactory.isInitDone()) { + auditFactory.init(props, appType); + } + } + + public boolean isAuditInitDone() { + AuditProviderFactory auditFactory = AuditProviderFactory.getInstance(); + + return auditFactory != null && auditFactory.isInitDone(); + } + + + @SuppressWarnings("deprecation") + public URL getRangerAuditXMLFileLocation() { + URL ret = null ; + + try { + for(String cfgFile : new String[] { "hive-site.xml", "hbase-site.xml", "hdfs-site.xml" } ) { + String loc = getFileLocation(cfgFile) ; + if (loc != null) { + if (new File(loc).canRead()) { + File parentFile = new File(loc).getParentFile() ; + ret = new File(parentFile, RangerHadoopConstants.RANGER_AUDIT_FILE).toURL() ; + break ; + } + } + } + } + catch(Throwable t) { + LOG.error("Unable to locate audit file location." , t) ; + ret = null ; + } + + return ret ; + } + + private String getFileLocation(String fileName) { + + String ret = null ; + + URL lurl = RangerConfiguration.class.getClassLoader().getResource(fileName) ; + + if (lurl == null ) { + lurl = RangerConfiguration.class.getClassLoader().getResource("/" + fileName) ; + } + + if (lurl != null) { + ret = lurl.getFile() ; + } + + return ret ; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/413fcb68/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/constants/RangerHadoopConstants.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/constants/RangerHadoopConstants.java b/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/constants/RangerHadoopConstants.java new file mode 100644 index 0000000..d87057d --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/constants/RangerHadoopConstants.java @@ -0,0 +1,89 @@ +/** + * 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.ranger.authorization.hadoop.constants; + +public class RangerHadoopConstants { + + public static final String RANGER_AUDIT_FILE = "xasecure-audit.xml" ; + public static final String RANGER_HDFS_SECURITY_FILE = "xasecure-hdfs-security.xml" ; + public static final String RANGER_KNOX_SECURITY_FILE = "xasecure-knox-security.xml" ; + public static final String RANGER_HBASE_SECURITY_FILE = "xasecure-hbase-security.xml" ; + public static final String RANGER_HIVE_SECURITY_FILE = "xasecure-hive-security.xml" ; + public static final String RANGER_POLICYMGR_SSL_FILE = "xasecure-policymgr-ssl.xml" ; + public static final String RANGER_STORM_SECURITY_FILE = "xasecure-storm-security.xml" ; + + public static final String RANGER_ADD_HDFS_PERMISSION_PROP = "xasecure.add-hadoop-authorization" ; + public static final boolean RANGER_ADD_HDFS_PERMISSION_DEFAULT = false ; + public static final String READ_ACCCESS_TYPE = "read"; + public static final String WRITE_ACCCESS_TYPE = "write"; + public static final String EXECUTE_ACCCESS_TYPE = "execute"; + + public static final String HDFS_ROOT_FOLDER_PATH_ALT = ""; + public static final String HDFS_ROOT_FOLDER_PATH = "/"; + + public static final String HDFS_ACCESS_VERIFIER_CLASS_NAME_PROP = "hdfs.authorization.verifier.classname" ; + public static final String HDFS_ACCESS_VERIFIER_CLASS_NAME_DEFAULT_VALUE = "org.apache.ranger.pdp.hdfs.RangerAuthorizer" ; + + public static final String HIVE_ACCESS_VERIFIER_CLASS_NAME_PROP = "hive.authorization.verifier.classname" ; + public static final String HIVE_ACCESS_VERIFIER_CLASS_NAME_DEFAULT_VALUE = "org.apache.ranger.pdp.hive.RangerAuthorizer" ; + + public static final String HIVE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_PROP = "xasecure.hive.update.xapolicies.on.grant.revoke" ; + public static final boolean HIVE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_DEFAULT_VALUE = true; + + public static final String HBASE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_PROP = "xasecure.hbase.update.xapolicies.on.grant.revoke" ; + public static final boolean HBASE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_DEFAULT_VALUE = true; + + public static final String KNOX_ACCESS_VERIFIER_CLASS_NAME_PROP = "knox.authorization.verifier.classname" ; + public static final String KNOX_ACCESS_VERIFIER_CLASS_NAME_DEFAULT_VALUE = "org.apache.ranger.pdp.knox.RangerAuthorizer" ; + + public static final String HBASE_ACCESS_VERIFIER_CLASS_NAME_PROP = "hbase.authorization.verifier.classname" ; + public static final String HBASE_ACCESS_VERIFIER_CLASS_NAME_DEFAULT_VALUE = "org.apache.ranger.pdp.hbase.RangerAuthorizer" ; + + public static final String STORM_ACCESS_VERIFIER_CLASS_NAME_PROP = "storm.authorization.verifier.classname" ; + public static final String STORM_ACCESS_VERIFIER_CLASS_NAME_DEFAULT_VALUE = "org.apache.ranger.pdp.storm.RangerAuthorizer" ; + + // + // Loging constants + // + public static final String AUDITLOG_FIELD_DELIMITER_PROP = "xasecure.auditlog.fieldDelimiterString"; + public static final String AUDITLOG_RANGER_MODULE_ACL_NAME_PROP = "xasecure.auditlog.xasecureAcl.name" ; + public static final String AUDITLOG_HADOOP_MODULE_ACL_NAME_PROP = "xasecure.auditlog.hadoopAcl.name" ; + + public static final String DEFAULT_LOG_FIELD_DELIMITOR = "|" ; + public static final String DEFAULT_RANGER_MODULE_ACL_NAME = "xasecure-acl" ; + public static final String DEFAULT_HADOOP_MODULE_ACL_NAME = "hadoop-acl" ; + + + public static final String AUDITLOG_FIELDINFO_VISIBLE_PROP = "xasecure.auditlog.fieldInfoVisible" ; + public static final boolean DEFAULT_AUDITLOG_FIELDINFO_VISIBLE = false ; + + public static final String AUDITLOG_ACCESS_GRANTED_TEXT_PROP = "xasecure.auditlog.accessgranted.text" ; + public static final String AUDITLOG_ACCESS_DENIED_TEXT_PROP = "xasecure.auditlog.accessdenied.text" ; + + public static final String DEFAULT_ACCESS_GRANTED_TEXT = "granted" ; + public static final String DEFAULT_ACCESS_DENIED_TEXT = "denied" ; + + public static final String AUDITLOG_EMPTY_STRING = "" ; + + public static final String AUDITLOG_HDFS_EXCLUDE_LIST_PROP = "xasecure.auditlog.hdfs.excludeusers" ; + public static final String AUDITLOG_REPOSITORY_NAME_PROP = "xasecure.audit.repository.name" ; + public static final String AUDITLOG_IS_ENABLED_PROP = "xasecure.audit.is.enabled" ; + + public static final String KEYMGR_URL_PROP = "hdfs.keymanager.url" ; +}
