http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/common/util/StrUtils.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/common/util/StrUtils.java b/ranger_solrj/src/main/java/org/apache/solr/common/util/StrUtils.java new file mode 100644 index 0000000..8ac87d7 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/common/util/StrUtils.java @@ -0,0 +1,309 @@ +/* + * 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.solr.common.util; + +import java.util.List; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Locale; +import java.io.IOException; + +import org.apache.solr.common.SolrException; + +/** + * + */ +public class StrUtils { + public static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', + '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + + /** + * Split a string based on a separator, but don't split if it's inside + * a string. Assume '\' escapes the next char both inside and + * outside strings. + */ + public static List<String> splitSmart(String s, char separator) { + ArrayList<String> lst = new ArrayList<>(4); + int pos=0, start=0, end=s.length(); + char inString=0; + char ch=0; + while (pos < end) { + char prevChar=ch; + ch = s.charAt(pos++); + if (ch=='\\') { // skip escaped chars + pos++; + } else if (inString != 0 && ch==inString) { + inString=0; + } else if (ch=='\'' || ch=='"') { + // If char is directly preceeded by a number or letter + // then don't treat it as the start of a string. + // Examples: 50" TV, or can't + if (!Character.isLetterOrDigit(prevChar)) { + inString=ch; + } + } else if (ch==separator && inString==0) { + lst.add(s.substring(start,pos-1)); + start=pos; + } + } + if (start < end) { + lst.add(s.substring(start,end)); + } + + /*** + if (SolrCore.log.isLoggable(Level.FINEST)) { + SolrCore.log.trace("splitCommand=" + lst); + } + ***/ + + return lst; + } + + /** Splits a backslash escaped string on the separator. + * <p> + * Current backslash escaping supported: + * <br> \n \t \r \b \f are escaped the same as a Java String + * <br> Other characters following a backslash are produced verbatim (\c => c) + * + * @param s the string to split + * @param separator the separator to split on + * @param decode decode backslash escaping + */ + public static List<String> splitSmart(String s, String separator, boolean decode) { + ArrayList<String> lst = new ArrayList<>(2); + StringBuilder sb = new StringBuilder(); + int pos=0, end=s.length(); + while (pos < end) { + if (s.startsWith(separator,pos)) { + if (sb.length() > 0) { + lst.add(sb.toString()); + sb=new StringBuilder(); + } + pos+=separator.length(); + continue; + } + + char ch = s.charAt(pos++); + if (ch=='\\') { + if (!decode) sb.append(ch); + if (pos>=end) break; // ERROR, or let it go? + ch = s.charAt(pos++); + if (decode) { + switch(ch) { + case 'n' : ch='\n'; break; + case 't' : ch='\t'; break; + case 'r' : ch='\r'; break; + case 'b' : ch='\b'; break; + case 'f' : ch='\f'; break; + } + } + } + + sb.append(ch); + } + + if (sb.length() > 0) { + lst.add(sb.toString()); + } + + return lst; + } + + /** + * Splits file names separated by comma character. + * File names can contain comma characters escaped by backslash '\' + * + * @param fileNames the string containing file names + * @return a list of file names with the escaping backslashed removed + */ + public static List<String> splitFileNames(String fileNames) { + if (fileNames == null) + return Collections.<String>emptyList(); + + List<String> result = new ArrayList<>(); + for (String file : fileNames.split("(?<!\\\\),")) { + result.add(file.replaceAll("\\\\(?=,)", "")); + } + + return result; + } + + /** + * Creates a backslash escaped string, joining all the items. + * @see #escapeTextWithSeparator + */ + public static String join(List<?> items, char separator) { + StringBuilder sb = new StringBuilder(items.size() << 3); + boolean first=true; + for (Object o : items) { + String item = o.toString(); + if (first) { + first = false; + } else { + sb.append(separator); + } + appendEscapedTextToBuilder(sb, item, separator); + } + return sb.toString(); + } + + + + public static List<String> splitWS(String s, boolean decode) { + ArrayList<String> lst = new ArrayList<>(2); + StringBuilder sb = new StringBuilder(); + int pos=0, end=s.length(); + while (pos < end) { + char ch = s.charAt(pos++); + if (Character.isWhitespace(ch)) { + if (sb.length() > 0) { + lst.add(sb.toString()); + sb=new StringBuilder(); + } + continue; + } + + if (ch=='\\') { + if (!decode) sb.append(ch); + if (pos>=end) break; // ERROR, or let it go? + ch = s.charAt(pos++); + if (decode) { + switch(ch) { + case 'n' : ch='\n'; break; + case 't' : ch='\t'; break; + case 'r' : ch='\r'; break; + case 'b' : ch='\b'; break; + case 'f' : ch='\f'; break; + } + } + } + + sb.append(ch); + } + + if (sb.length() > 0) { + lst.add(sb.toString()); + } + + return lst; + } + + public static List<String> toLower(List<String> strings) { + ArrayList<String> ret = new ArrayList<>(strings.size()); + for (String str : strings) { + ret.add(str.toLowerCase(Locale.ROOT)); + } + return ret; + } + + + + /** Return if a string starts with '1', 't', or 'T' + * and return false otherwise. + */ + public static boolean parseBoolean(String s) { + char ch = s.length()>0 ? s.charAt(0) : 0; + return (ch=='1' || ch=='t' || ch=='T'); + } + + /** how to transform a String into a boolean... more flexible than + * Boolean.parseBoolean() to enable easier integration with html forms. + */ + public static boolean parseBool(String s) { + if( s != null ) { + if( s.startsWith("true") || s.startsWith("on") || s.startsWith("yes") ) { + return true; + } + if( s.startsWith("false") || s.startsWith("off") || s.equals("no") ) { + return false; + } + } + throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "invalid boolean value: "+s ); + } + + /** + * {@link NullPointerException} and {@link SolrException} free version of {@link #parseBool(String)} + * @return parsed boolean value (or def, if s is null or invalid) + */ + public static boolean parseBool(String s, boolean def) { + if( s != null ) { + if( s.startsWith("true") || s.startsWith("on") || s.startsWith("yes") ) { + return true; + } + if( s.startsWith("false") || s.startsWith("off") || s.equals("no") ) { + return false; + } + } + return def; + } + + /** + * URLEncodes a value, replacing only enough chars so that + * the URL may be unambiguously pasted back into a browser. + * <p> + * Characters with a numeric value less than 32 are encoded. + * &,=,%,+,space are encoded. + */ + public static void partialURLEncodeVal(Appendable dest, String val) throws IOException { + for (int i=0; i<val.length(); i++) { + char ch = val.charAt(i); + if (ch < 32) { + dest.append('%'); + if (ch < 0x10) dest.append('0'); + dest.append(Integer.toHexString(ch)); + } else { + switch (ch) { + case ' ': dest.append('+'); break; + case '&': dest.append("%26"); break; + case '%': dest.append("%25"); break; + case '=': dest.append("%3D"); break; + case '+': dest.append("%2B"); break; + default : dest.append(ch); break; + } + } + } + } + + /** + * Creates a new copy of the string with the separator backslash escaped. + * @see #join + */ + public static String escapeTextWithSeparator(String item, char separator) { + StringBuilder sb = new StringBuilder(item.length() * 2); + appendEscapedTextToBuilder(sb, item, separator); + return sb.toString(); + } + + /** + * writes chars from item to out, backslash escaping as needed based on separator -- + * but does not append the seperator itself + */ + public static void appendEscapedTextToBuilder(StringBuilder out, + String item, + char separator) { + for (int i = 0; i < item.length(); i++) { + char ch = item.charAt(i); + if (ch == '\\' || ch == separator) { + out.append('\\'); + } + out.append(ch); + } + } + + +}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/common/util/URLUtil.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/common/util/URLUtil.java b/ranger_solrj/src/main/java/org/apache/solr/common/util/URLUtil.java new file mode 100644 index 0000000..6d273ec --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/common/util/URLUtil.java @@ -0,0 +1,50 @@ +/* + * 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.solr.common.util; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class URLUtil { + + public final static Pattern URL_PREFIX = Pattern.compile("^([a-z]*?://).*"); + + public static String removeScheme(String url) { + Matcher matcher = URL_PREFIX.matcher(url); + if (matcher.matches()) { + return url.substring(matcher.group(1).length()); + } + + return url; + } + + public static boolean hasScheme(String url) { + Matcher matcher = URL_PREFIX.matcher(url); + return matcher.matches(); + } + + public static String getScheme(String url) { + Matcher matcher = URL_PREFIX.matcher(url); + if (matcher.matches()) { + return matcher.group(1); + } + + return null; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/common/util/XML.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/common/util/XML.java b/ranger_solrj/src/main/java/org/apache/solr/common/util/XML.java new file mode 100644 index 0000000..50a6da2 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/common/util/XML.java @@ -0,0 +1,207 @@ +/* + * 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.solr.common.util; + +import java.io.Writer; +import java.io.IOException; +import java.util.Map; + +/** + * + */ +public class XML { + + // + // copied from some of my personal code... -YCS + // table created from python script. + // only have to escape quotes in attribute values, and don't really have to escape '>' + // many chars less than 0x20 are *not* valid XML, even when escaped! + // for example, <foo>�<foo> is invalid XML. + private static final String[] chardata_escapes= + {"#0;","#1;","#2;","#3;","#4;","#5;","#6;","#7;","#8;",null,null,"#11;","#12;",null,"#14;","#15;","#16;","#17;","#18;","#19;","#20;","#21;","#22;","#23;","#24;","#25;","#26;","#27;","#28;","#29;","#30;","#31;",null,null,null,null,null,null,"&",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"<",null,">"}; + + private static final String[] attribute_escapes= + {"#0;","#1;","#2;","#3;","#4;","#5;","#6;","#7;","#8;",null,null,"#11;","#12;",null,"#14;","#15;","#16;","#17;","#18;","#19;","#20;","#21;","#22;","#23;","#24;","#25;","#26;","#27;","#28;","#29;","#30;","#31;",null,null,""",null,null,null,"&",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"<"}; + + + + /***************************************** + #Simple python script used to generate the escape table above. -YCS + # + #use individual char arrays or one big char array for better efficiency + # or byte array? + #other={'&':'amp', '<':'lt', '>':'gt', "'":'apos', '"':'quot'} + # + other={'&':'amp', '<':'lt'} + + maxi=ord(max(other.keys()))+1 + table=[None] * maxi + #NOTE: invalid XML chars are "escaped" as #nn; *not* &#nn; because + #a real XML escape would cause many strict XML parsers to choke. + for i in range(0x20): table[i]='#%d;' % i + for i in '\n\r\t ': table[ord(i)]=None + for k,v in other.items(): + table[ord(k)]='&%s;' % v + + result="" + for i in range(maxi): + val=table[i] + if not val: val='null' + else: val='"%s"' % val + result += val + ',' + + print result + ****************************************/ + + +/********* + * + * @throws IOException If there is a low-level I/O error. + */ + public static void escapeCharData(String str, Writer out) throws IOException { + escape(str, out, chardata_escapes); + } + + public static void escapeAttributeValue(String str, Writer out) throws IOException { + escape(str, out, attribute_escapes); + } + + public static void escapeAttributeValue(char [] chars, int start, int length, Writer out) throws IOException { + escape(chars, start, length, out, attribute_escapes); + } + + + public final static void writeXML(Writer out, String tag, String val) throws IOException { + out.write('<'); + out.write(tag); + if (val == null) { + out.write('/'); + out.write('>'); + } else { + out.write('>'); + escapeCharData(val,out); + out.write('<'); + out.write('/'); + out.write(tag); + out.write('>'); + } + } + + /** does NOT escape character data in val, must already be valid XML */ + public final static void writeUnescapedXML(Writer out, String tag, String val, Object... attrs) throws IOException { + out.write('<'); + out.write(tag); + for (int i=0; i<attrs.length; i++) { + out.write(' '); + out.write(attrs[i++].toString()); + out.write('='); + out.write('"'); + out.write(attrs[i].toString()); + out.write('"'); + } + if (val == null) { + out.write('/'); + out.write('>'); + } else { + out.write('>'); + out.write(val); + out.write('<'); + out.write('/'); + out.write(tag); + out.write('>'); + } + } + + /** escapes character data in val */ + public final static void writeXML(Writer out, String tag, String val, Object... attrs) throws IOException { + out.write('<'); + out.write(tag); + for (int i=0; i<attrs.length; i++) { + out.write(' '); + out.write(attrs[i++].toString()); + out.write('='); + out.write('"'); + escapeAttributeValue(attrs[i].toString(), out); + out.write('"'); + } + if (val == null) { + out.write('/'); + out.write('>'); + } else { + out.write('>'); + escapeCharData(val,out); + out.write('<'); + out.write('/'); + out.write(tag); + out.write('>'); + } + } + + /** escapes character data in val */ + public static void writeXML(Writer out, String tag, String val, Map<String, String> attrs) throws IOException { + out.write('<'); + out.write(tag); + for (Map.Entry<String, String> entry : attrs.entrySet()) { + out.write(' '); + out.write(entry.getKey()); + out.write('='); + out.write('"'); + escapeAttributeValue(entry.getValue(), out); + out.write('"'); + } + if (val == null) { + out.write('/'); + out.write('>'); + } else { + out.write('>'); + escapeCharData(val,out); + out.write('<'); + out.write('/'); + out.write(tag); + out.write('>'); + } + } + + private static void escape(char [] chars, int offset, int length, Writer out, String [] escapes) throws IOException{ + for (int i=offset; i<length; i++) { + char ch = chars[i]; + if (ch<escapes.length) { + String replacement = escapes[ch]; + if (replacement != null) { + out.write(replacement); + continue; + } + } + out.write(ch); + } + } + + private static void escape(String str, Writer out, String[] escapes) throws IOException { + for (int i=0; i<str.length(); i++) { + char ch = str.charAt(i); + if (ch<escapes.length) { + String replacement = escapes[ch]; + if (replacement != null) { + out.write(replacement); + continue; + } + } + out.write(ch); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/common/util/XMLErrorLogger.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/common/util/XMLErrorLogger.java b/ranger_solrj/src/main/java/org/apache/solr/common/util/XMLErrorLogger.java new file mode 100644 index 0000000..7f45ff9 --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/common/util/XMLErrorLogger.java @@ -0,0 +1,84 @@ +/* + * 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.solr.common.util; + +import org.slf4j.Logger; + +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import javax.xml.transform.ErrorListener; +import javax.xml.transform.TransformerException; +import javax.xml.stream.Location; +import javax.xml.stream.XMLReporter; + +public final class XMLErrorLogger implements ErrorHandler,ErrorListener,XMLReporter { + + private final Logger log; + + public XMLErrorLogger(Logger log) { + this.log = log; + } + + // ErrorHandler + + @Override + public void warning(SAXParseException e) { + log.warn("XML parse warning in \""+e.getSystemId()+"\", line "+e.getLineNumber()+", column "+e.getColumnNumber()+": "+e.getMessage()); + } + + @Override + public void error(SAXParseException e) throws SAXException { + throw e; + } + + @Override + public void fatalError(SAXParseException e) throws SAXException { + throw e; + } + + // ErrorListener + + @Override + public void warning(TransformerException e) { + log.warn(e.getMessageAndLocation()); + } + + @Override + public void error(TransformerException e) throws TransformerException { + throw e; + } + + @Override + public void fatalError(TransformerException e) throws TransformerException { + throw e; + } + + // XMLReporter + + @Override + public void report(String message, String errorType, Object relatedInformation, Location loc) { + final StringBuilder sb = new StringBuilder("XML parser reported ").append(errorType); + if (loc != null) { + sb.append(" in \"").append(loc.getSystemId()).append("\", line ") + .append(loc.getLineNumber()).append(", column ").append(loc.getColumnNumber()); + } + log.warn(sb.append(": ").append(message).toString()); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/org/apache/solr/common/util/package-info.java ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/org/apache/solr/common/util/package-info.java b/ranger_solrj/src/main/java/org/apache/solr/common/util/package-info.java new file mode 100644 index 0000000..1da825f --- /dev/null +++ b/ranger_solrj/src/main/java/org/apache/solr/common/util/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + */ + +/** + * Common utility classes reused on both clients & server. + */ +package org.apache.solr.common.util; + + http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/ranger_solrj/src/main/java/overview.html ---------------------------------------------------------------------- diff --git a/ranger_solrj/src/main/java/overview.html b/ranger_solrj/src/main/java/overview.html new file mode 100644 index 0000000..7a534ed --- /dev/null +++ b/ranger_solrj/src/main/java/overview.html @@ -0,0 +1,21 @@ +<!-- + 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. +--> +<html> +<body> +Apache Solr Search Server: Solr-j +</body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/security-admin/pom.xml ---------------------------------------------------------------------- diff --git a/security-admin/pom.xml b/security-admin/pom.xml index 78b7e7f..e507afe 100644 --- a/security-admin/pom.xml +++ b/security-admin/pom.xml @@ -244,6 +244,11 @@ </exclusions> </dependency> <dependency> + <groupId>org.apache.ranger</groupId> + <artifactId>ranger_solrj</artifactId> + <version>${ranger.solrj.version}</version> + </dependency> + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/security-admin/scripts/install.properties ---------------------------------------------------------------------- diff --git a/security-admin/scripts/install.properties b/security-admin/scripts/install.properties index 03d09eb..ae66576 100644 --- a/security-admin/scripts/install.properties +++ b/security-admin/scripts/install.properties @@ -58,6 +58,14 @@ db_name=ranger db_user=rangeradmin db_password= +#Source for Audit DB +# * audit_db is solr or db +audit_store=db + +# * audit_solr_url URL to Solr. E.g. http://<solr_host>:6083/solr/ranger_audits +audit_solr_url= + + # # DB UserId for storing auditlog infromation # @@ -69,6 +77,8 @@ audit_db_name=ranger_audit audit_db_user=rangerlogger audit_db_password= + + #------------------------- DB CONFIG - END ---------------------------------- # http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/security-admin/scripts/setup.sh ---------------------------------------------------------------------- diff --git a/security-admin/scripts/setup.sh b/security-admin/scripts/setup.sh index 6c992f7..04e22eb 100755 --- a/security-admin/scripts/setup.sh +++ b/security-admin/scripts/setup.sh @@ -129,8 +129,13 @@ init_variables(){ getPropertyFromFile 'db_root_password' $PROPFILE db_user getPropertyFromFile 'db_user' $PROPFILE db_user getPropertyFromFile 'db_password' $PROPFILE db_password - getPropertyFromFile 'audit_db_user' $PROPFILE audit_db_user - getPropertyFromFile 'audit_db_password' $PROPFILE audit_db_password + if [ "${audit_store}" == "solr" ] + then + getPropertyFromFile 'audit_solr_url' $PROPFILE audit_solr_url + else + getPropertyFromFile 'audit_db_user' $PROPFILE audit_db_user + getPropertyFromFile 'audit_db_password' $PROPFILE audit_db_password + fi } wait_for_tomcat_shutdown() { @@ -820,6 +825,19 @@ update_properties() { newPropertyValue="com.microsoft.sqlserver.jdbc.SQLServerDriver" updatePropertyToFile $propertyName $newPropertyValue $to_file fi + + if [ "${audit_store}" == "solr" ] + then + propertyName=xa.audit.solr.url + newPropertyValue=${audit_solr_url} + updatePropertyToFile $propertyName $newPropertyValue $to_file + fi + + propertyName=xa.audit.db.type + newPropertyValue=${audit_store} + updatePropertyToFile $propertyName $newPropertyValue $to_file + + propertyName=xa.webapp.url.root newPropertyValue="${policymgr_external_url}" updatePropertyToFile $propertyName $newPropertyValue $to_file @@ -878,41 +896,43 @@ update_properties() { fi ########### - audit_db_password_alias=auditDB.jdbc.password + if [ "${audit_store}" != "solr" ] + then + audit_db_password_alias=auditDB.jdbc.password - echo "Starting configuration for Audit DB credentials:" + echo "Starting configuration for Audit DB credentials:" - if [ "${keystore}" != "" ] - then + if [ "${keystore}" != "" ] + then $JAVA_HOME/bin/java -cp "cred/lib/*" org.apache.ranger.credentialapi.buildks create "$audit_db_password_alias" -value "$audit_db_password" -provider jceks://file$keystore propertyName=auditDB.jdbc.credential.alias newPropertyValue="${audit_db_password_alias}" updatePropertyToFile $propertyName $newPropertyValue $to_file - + propertyName=auditDB.jdbc.credential.provider.path newPropertyValue="${keystore}" updatePropertyToFile $propertyName $newPropertyValue $to_file - + propertyName=auditDB.jdbc.password newPropertyValue="_" updatePropertyToFile $propertyName $newPropertyValue $to_file - else + else propertyName=auditDB.jdbc.password newPropertyValue="${audit_db_password}" updatePropertyToFile $propertyName $newPropertyValue $to_file - fi + fi - if test -f $keystore; then + if test -f $keystore; then chown -R ${unix_user}:${unix_group} ${keystore} #echo "$keystore found." - else + else #echo "$keystore not found. so use clear text password" propertyName=auditDB.jdbc.password newPropertyValue="${audit_db_password}" updatePropertyToFile $propertyName $newPropertyValue $to_file + fi fi - } create_audit_db_user(){ @@ -1404,4 +1424,4 @@ execute_java_patches else exit 1 fi -echo "Installation of Ranger PolicyManager Web Application is completed." \ No newline at end of file +echo "Installation of Ranger PolicyManager Web Application is completed." http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java index 3c3bd77..839f1fc 100644 --- a/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java @@ -66,6 +66,7 @@ import org.apache.ranger.service.XPermMapService; import org.apache.ranger.service.XPolicyService; import org.apache.ranger.service.XTrxLogService; import org.apache.ranger.service.XUserService; +import org.apache.ranger.solr.SolrAccessAuditsService; import org.apache.ranger.util.RestUtil; import org.apache.ranger.view.VXAccessAuditList; import org.apache.ranger.view.VXAsset; @@ -135,6 +136,9 @@ public class AssetMgr extends AssetMgrBase { XUserMgr xUserMgr; @Autowired + SolrAccessAuditsService solrAccessAuditsService; + + @Autowired @Qualifier(value = "transactionManager") PlatformTransactionManager txManager; @@ -1776,7 +1780,12 @@ public class AssetMgr extends AssetMgrBase { }else if(!searchCriteria.getSortType().equalsIgnoreCase("asc")&& !searchCriteria.getSortType().equalsIgnoreCase("desc")){ searchCriteria.setSortType("desc"); } - return xAccessAuditService.searchXAccessAudits(searchCriteria); + if (xaBizUtil.getAuditDBType().equalsIgnoreCase(RangerBizUtil.AUDIT_STORE_SOLR)) { + return solrAccessAuditsService.searchXAccessAudits(searchCriteria); + } else { + return xAccessAuditService.searchXAccessAudits(searchCriteria); + } + //return xAccessAuditService.searchXAccessAudits(searchCriteria); } public VXTrxLogList getTransactionReport(String transactionId) { http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java b/security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java index b8659aa..37cc3d7 100644 --- a/security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java @@ -17,7 +17,7 @@ * under the License. */ - package org.apache.ranger.biz; +package org.apache.ranger.biz; import java.io.File; import java.util.ArrayList; @@ -83,15 +83,17 @@ public class RangerBizUtil { Map<String, Integer> classTypeMappings = new HashMap<String, Integer>(); private int maxFirstNameLength; int maxDisplayNameLength = 150; - boolean defaultAutoApprove = true; - boolean showBlockedContent = true; public final String EMPTY_CONTENT_DISPLAY_NAME = "..."; boolean enableResourceAccessControl; private Random random; private static final String PATH_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst0123456789-_."; private static char[] PATH_CHAR_SET = PATH_CHARS.toCharArray(); private static int PATH_CHAR_SET_LEN = PATH_CHAR_SET.length; - + public static final String AUDIT_STORE_RDBMS = "DB"; + public static final String AUDIT_STORE_SOLR = "solr"; + + String auditDBType = AUDIT_STORE_RDBMS; + static String fileSeparator = PropertiesUtil.getProperty( "xa.file.separator", "/"); @@ -100,19 +102,20 @@ public class RangerBizUtil { "xa.user.firstname.maxlength", "16")); maxDisplayNameLength = PropertiesUtil.getIntProperty( "xa.bookmark.name.maxlen", maxDisplayNameLength); - showBlockedContent = PropertiesUtil.getBooleanProperty( - "xa.content.show_blocked", showBlockedContent); - defaultAutoApprove = PropertiesUtil.getBooleanProperty( - "xa.mod.default", defaultAutoApprove); groupEditableClasses = new HashSet<Class<?>>( Arrays.asList(groupEditableClassesList)); enableResourceAccessControl = PropertiesUtil.getBooleanProperty( "xa.resource.accessControl.enabled", true); + auditDBType = PropertiesUtil.getProperty("xa.audit.db.type", + auditDBType).toLowerCase(); + + logger.info("Audit datasource is " + auditDBType); random = new Random(); } - public <T extends XXDBBase> List<? extends XXDBBase> getParentObjects(T object) { + public <T extends XXDBBase> List<? extends XXDBBase> getParentObjects( + T object) { List<XXDBBase> parentObjectList = null; // if (checkParentAcess.contains(object.getMyClassType())) { // parentObjectList = new ArrayList<MBase>(); @@ -216,8 +219,8 @@ public class RangerBizUtil { } public String getDisplayNameForClassName(XXDBBase obj) { - String classTypeDisplayName = RangerConstants.getLabelFor_ClassTypes(obj - .getMyClassType()); + String classTypeDisplayName = RangerConstants + .getLabelFor_ClassTypes(obj.getMyClassType()); if (classTypeDisplayName == null) { logger.error( "Error get name for class type. obj=" + obj.toString(), @@ -254,7 +257,8 @@ public class RangerBizUtil { * @param userProfile * @return */ - public String generatePublicName(VXPortalUser userProfile, XXPortalUser gjUser) { + public String generatePublicName(VXPortalUser userProfile, + XXPortalUser gjUser) { return generatePublicName(userProfile.getFirstName(), userProfile.getLastName()); } @@ -298,7 +302,8 @@ public class RangerBizUtil { public XXDBBase getMObject(VXDataObject vXDataObject) { if (vXDataObject != null) { - return getMObject(vXDataObject.getMyClassType(), vXDataObject.getId()); + return getMObject(vXDataObject.getMyClassType(), + vXDataObject.getId()); } return null; } @@ -308,8 +313,8 @@ public class RangerBizUtil { return null; } if (objClassType == RangerConstants.CLASS_TYPE_USER_PROFILE) { - return userMgr.mapXXPortalUserVXPortalUser(daoManager.getXXPortalUser().getById( - objId)); + return userMgr.mapXXPortalUserVXPortalUser(daoManager + .getXXPortalUser().getById(objId)); } try { AbstractBaseResourceService<?, ?> myService = AbstractBaseResourceService @@ -426,9 +431,10 @@ public class RangerBizUtil { xResourceList, xUserId, permission, reqTableType, reqColumnType, false); if (!matchFound) { - vXResponse.setMsgDesc("You're not permitted to perform " - + "the action for resource path : " - + resourceName); + vXResponse + .setMsgDesc("You're not permitted to perform " + + "the action for resource path : " + + resourceName); vXResponse.setStatusCode(VXResponse.STATUS_ERROR); return vXResponse; } @@ -438,9 +444,10 @@ public class RangerBizUtil { boolean matchFound = matchHivePolicy(resourceName, xResourceList, xUserId, permission); if (!matchFound) { - vXResponse.setMsgDesc("You're not permitted to perform " - + "the action for resource path : " - + resourceName); + vXResponse + .setMsgDesc("You're not permitted to perform " + + "the action for resource path : " + + resourceName); vXResponse.setStatusCode(VXResponse.STATUS_ERROR); return vXResponse; } @@ -477,34 +484,34 @@ public class RangerBizUtil { vXResponse.setStatusCode(VXResponse.STATUS_SUCCESS); return vXResponse; } else if (assetType == AppConstants.ASSET_KNOX) { - String[] requestResNameList = resourceNames.split(","); - for (String resourceName : requestResNameList) { - boolean matchFound = matchKnoxPolicy(resourceName, - xResourceList, vXResponse, xUserId, permission); - if (!matchFound) { - vXResponse.setMsgDesc("You're not permitted to perform " - + "the action for resource path : " + resourceName); - vXResponse.setStatusCode(VXResponse.STATUS_ERROR); - return vXResponse; - } + String[] requestResNameList = resourceNames.split(","); + for (String resourceName : requestResNameList) { + boolean matchFound = matchKnoxPolicy(resourceName, + xResourceList, vXResponse, xUserId, permission); + if (!matchFound) { + vXResponse.setMsgDesc("You're not permitted to perform " + + "the action for resource path : " + resourceName); + vXResponse.setStatusCode(VXResponse.STATUS_ERROR); + return vXResponse; + } + } + vXResponse.setStatusCode(VXResponse.STATUS_SUCCESS); + return vXResponse; + } else if (assetType == AppConstants.ASSET_STORM) { + String[] requestResNameList = resourceNames.split(","); + for (String resourceName : requestResNameList) { + boolean matchFound = matchStormPolicy(resourceName, + xResourceList, vXResponse, xUserId, permission); + if (!matchFound) { + vXResponse.setMsgDesc("You're not permitted to perform " + + "the action for resource path : " + resourceName); + vXResponse.setStatusCode(VXResponse.STATUS_ERROR); + return vXResponse; } - vXResponse.setStatusCode(VXResponse.STATUS_SUCCESS); - return vXResponse; - } else if (assetType == AppConstants.ASSET_STORM) { - String[] requestResNameList = resourceNames.split(","); - for (String resourceName : requestResNameList) { - boolean matchFound = matchStormPolicy(resourceName, - xResourceList, vXResponse, xUserId, permission); - if (!matchFound) { - vXResponse.setMsgDesc("You're not permitted to perform " - + "the action for resource path : " + resourceName); - vXResponse.setStatusCode(VXResponse.STATUS_ERROR); - return vXResponse; - } - } - vXResponse.setStatusCode(VXResponse.STATUS_SUCCESS); - return vXResponse; - } + } + vXResponse.setStatusCode(VXResponse.STATUS_SUCCESS); + return vXResponse; + } return vXResponse; } @@ -619,21 +626,26 @@ public class RangerBizUtil { * @return */ public boolean matchHbasePolicy(String resourceName, - List<XXResource> xResourceList, VXResponse vXResponse, Long xUserId, - int permission) { - if(stringUtil.isEmpty(resourceName) || xResourceList==null || xUserId==null){ + List<XXResource> xResourceList, VXResponse vXResponse, + Long xUserId, int permission) { + if (stringUtil.isEmpty(resourceName) || xResourceList == null + || xUserId == null) { return false; } - String[] splittedResources = stringUtil.split(resourceName, fileSeparator); + String[] splittedResources = stringUtil.split(resourceName, + fileSeparator); if (splittedResources.length < 1 || splittedResources.length > 3) { logger.debug("Invalid resourceName name : " + resourceName); return false; } - String tblName = splittedResources.length > 0 ? splittedResources[0] : StringUtil.WILDCARD_ASTERISK; - String colFamName = splittedResources.length > 1 ? splittedResources[1] : StringUtil.WILDCARD_ASTERISK; - String colName = splittedResources.length > 2 ? splittedResources[2] : StringUtil.WILDCARD_ASTERISK; + String tblName = splittedResources.length > 0 ? splittedResources[0] + : StringUtil.WILDCARD_ASTERISK; + String colFamName = splittedResources.length > 1 ? splittedResources[1] + : StringUtil.WILDCARD_ASTERISK; + String colName = splittedResources.length > 2 ? splittedResources[2] + : StringUtil.WILDCARD_ASTERISK; boolean policyMatched = false; // check all resources whether Hbase policy is enabled in any resource @@ -643,29 +655,38 @@ public class RangerBizUtil { continue; } Long resourceId = xResource.getId(); - boolean hasPermission = checkUsrPermForPolicy(xUserId, permission, resourceId); + boolean hasPermission = checkUsrPermForPolicy(xUserId, permission, + resourceId); // if permission is enabled then load Tables,column family and // columns list from resource - if (! hasPermission) { + if (!hasPermission) { continue; } // 1. does the policy match the table? - String[] xTables = stringUtil.isEmpty(xResource.getTables()) ? null : stringUtil.split(xResource.getTables(), ","); + String[] xTables = stringUtil.isEmpty(xResource.getTables()) ? null + : stringUtil.split(xResource.getTables(), ","); - boolean matchFound = (xTables == null || xTables.length == 0) ? true : matchPath(tblName, xTables); + boolean matchFound = (xTables == null || xTables.length == 0) ? true + : matchPath(tblName, xTables); - if(matchFound) { + if (matchFound) { // 2. does the policy match the column? - String[] xColumnFamilies = stringUtil.isEmpty(xResource.getColumnFamilies()) ? null : stringUtil.split(xResource.getColumnFamilies(), ","); + String[] xColumnFamilies = stringUtil.isEmpty(xResource + .getColumnFamilies()) ? null : stringUtil.split( + xResource.getColumnFamilies(), ","); + + matchFound = (xColumnFamilies == null || xColumnFamilies.length == 0) ? true + : matchPath(colFamName, xColumnFamilies); - matchFound = (xColumnFamilies == null || xColumnFamilies.length == 0) ? true : matchPath(colFamName, xColumnFamilies); - - if(matchFound) { + if (matchFound) { // 3. does the policy match the columnFamily? - String[] xColumns = stringUtil.isEmpty(xResource.getColumns()) ? null : stringUtil.split(xResource.getColumns(), ","); + String[] xColumns = stringUtil.isEmpty(xResource + .getColumns()) ? null : stringUtil.split( + xResource.getColumns(), ","); - matchFound = (xColumns == null || xColumns.length == 0) ? true : matchPath(colName, xColumns); + matchFound = (xColumns == null || xColumns.length == 0) ? true + : matchPath(colName, xColumns); } } @@ -699,19 +720,24 @@ public class RangerBizUtil { List<XXResource> xResourceList, Long xUserId, int permission, int reqTableType, int reqColumnType, boolean isUdfPolicy) { - if(stringUtil.isEmpty(resourceName) || xResourceList==null || xUserId==null){ + if (stringUtil.isEmpty(resourceName) || xResourceList == null + || xUserId == null) { return false; } - String[] splittedResources = stringUtil.split(resourceName, fileSeparator);// get list of resources + String[] splittedResources = stringUtil.split(resourceName, + fileSeparator);// get list of resources if (splittedResources.length < 1 || splittedResources.length > 3) { logger.debug("Invalid resource name : " + resourceName); return false; } - - String dbName = splittedResources.length > 0 ? splittedResources[0] : StringUtil.WILDCARD_ASTERISK; - String tblName = splittedResources.length > 1 ? splittedResources[1] : StringUtil.WILDCARD_ASTERISK; - String colName = splittedResources.length > 2 ? splittedResources[2] : StringUtil.WILDCARD_ASTERISK; + + String dbName = splittedResources.length > 0 ? splittedResources[0] + : StringUtil.WILDCARD_ASTERISK; + String tblName = splittedResources.length > 1 ? splittedResources[1] + : StringUtil.WILDCARD_ASTERISK; + String colName = splittedResources.length > 2 ? splittedResources[2] + : StringUtil.WILDCARD_ASTERISK; boolean policyMatched = false; for (XXResource xResource : xResourceList) { @@ -720,21 +746,24 @@ public class RangerBizUtil { } Long resourceId = xResource.getId(); - boolean hasPermission = checkUsrPermForPolicy(xUserId, permission, resourceId); + boolean hasPermission = checkUsrPermForPolicy(xUserId, permission, + resourceId); - if (! hasPermission) { + if (!hasPermission) { continue; } // 1. does the policy match the database? - String[] xDatabases = stringUtil.isEmpty(xResource.getDatabases()) ? null : stringUtil.split(xResource.getDatabases(), ","); + String[] xDatabases = stringUtil.isEmpty(xResource.getDatabases()) ? null + : stringUtil.split(xResource.getDatabases(), ","); - boolean matchFound = (xDatabases == null || xDatabases.length == 0) ? true : matchPath(dbName, xDatabases); + boolean matchFound = (xDatabases == null || xDatabases.length == 0) ? true + : matchPath(dbName, xDatabases); - if (! matchFound) { + if (!matchFound) { continue; } - + // Type(either UDFs policy or non-UDFs policy) of current policy // should be of same as type of policy being iterated if (!stringUtil.isEmpty(xResource.getUdfs()) && !isUdfPolicy) { @@ -743,9 +772,10 @@ public class RangerBizUtil { if (isUdfPolicy) { // 2. does the policy match the UDF? - String[] xUdfs = stringUtil.isEmpty(xResource.getUdfs()) ? null : stringUtil.split(xResource.getUdfs(), ","); - - if(! matchPath(tblName, xUdfs)) { + String[] xUdfs = stringUtil.isEmpty(xResource.getUdfs()) ? null + : stringUtil.split(xResource.getUdfs(), ","); + + if (!matchPath(tblName, xUdfs)) { continue; } else { policyMatched = true; @@ -753,11 +783,13 @@ public class RangerBizUtil { } } else { // 2. does the policy match the table? - String[] xTables = stringUtil.isEmpty(xResource.getTables()) ? null : stringUtil.split(xResource.getTables(), ","); + String[] xTables = stringUtil.isEmpty(xResource.getTables()) ? null + : stringUtil.split(xResource.getTables(), ","); - matchFound = (xTables == null || xTables.length == 0) ? true : matchPath(tblName, xTables); + matchFound = (xTables == null || xTables.length == 0) ? true + : matchPath(tblName, xTables); - if(xResource.getTableType() == AppConstants.POLICY_EXCLUSION) { + if (xResource.getTableType() == AppConstants.POLICY_EXCLUSION) { matchFound = !matchFound; } @@ -766,11 +798,13 @@ public class RangerBizUtil { } // 3. does current policy match the column? - String[] xColumns = stringUtil.isEmpty(xResource.getColumns()) ? null : stringUtil.split(xResource.getColumns(), ","); + String[] xColumns = stringUtil.isEmpty(xResource.getColumns()) ? null + : stringUtil.split(xResource.getColumns(), ","); - matchFound = (xColumns == null || xColumns.length == 0) ? true : matchPath(colName, xColumns); + matchFound = (xColumns == null || xColumns.length == 0) ? true + : matchPath(colName, xColumns); - if(xResource.getColumnType() == AppConstants.POLICY_EXCLUSION) { + if (xResource.getColumnType() == AppConstants.POLICY_EXCLUSION) { matchFound = !matchFound; } @@ -784,6 +818,7 @@ public class RangerBizUtil { } return policyMatched; } + /** * returns true if user is having required permission on given Hbase * resource @@ -796,8 +831,8 @@ public class RangerBizUtil { * @return */ private boolean matchKnoxPolicy(String resourceName, - List<XXResource> xResourceList, VXResponse vXResponse, Long xUserId, - int permission) { + List<XXResource> xResourceList, VXResponse vXResponse, + Long xUserId, int permission) { String[] splittedResources = stringUtil.split(resourceName, fileSeparator); @@ -817,11 +852,12 @@ public class RangerBizUtil { Long resourceId = xResource.getId(); boolean hasPermission = checkUsrPermForPolicy(xUserId, permission, resourceId); - // if permission is enabled then load Topologies,services list from resource + // if permission is enabled then load Topologies,services list from + // resource if (hasPermission) { String[] xTopologies = (xResource.getTopologies() == null || xResource - .getTopologies().equalsIgnoreCase("")) ? null : stringUtil - .split(xResource.getTopologies(), ","); + .getTopologies().equalsIgnoreCase("")) ? null + : stringUtil.split(xResource.getTopologies(), ","); String[] xServices = (xResource.getServices() == null || xResource .getServices().equalsIgnoreCase("")) ? null : stringUtil.split(xResource.getServices(), ","); @@ -833,30 +869,31 @@ public class RangerBizUtil { // check whether given table resource matches with any // existing topology resource if (index == 0) { - if(xTopologies!=null){ - for (String xTopology : xTopologies) { - if (matchPath(splittedResources[index], xTopology)) { - matchFound = true; - continue; + if (xTopologies != null) { + for (String xTopology : xTopologies) { + if (matchPath(splittedResources[index], + xTopology)) { + matchFound = true; + continue; + } } } - } - if(!matchFound) { + if (!matchFound) { break; } } // check whether given service resource matches with // any existing service resource else if (index == 1) { - if(xServices!=null){ - for (String xService : xServices) { - if (matchPath(splittedResources[index], - xService)) { - matchFound = true; - continue; + if (xServices != null) { + for (String xService : xServices) { + if (matchPath(splittedResources[index], + xService)) { + matchFound = true; + continue; + } } } - } - if(!matchFound) { + if (!matchFound) { break; } } @@ -870,85 +907,84 @@ public class RangerBizUtil { return policyMatched; } - /** - * returns true if user is having required permission on given STORM - * resource - * - * @param resourceName - * @param xResourceList - * @param vXResponse - * @param xUserId - * @param permission - * @return - */ - private boolean matchStormPolicy(String resourceName, - List<XXResource> xResourceList, VXResponse vXResponse, Long xUserId, - int permission) { - - String[] splittedResources = stringUtil.split(resourceName, - fileSeparator); - int numberOfResources = splittedResources.length; - if (numberOfResources < 1 || numberOfResources > 3) { - logger.debug("Invalid policy name : " + resourceName); - return false; - } - - boolean policyMatched = false; - // check all resources whether Knox policy is enabled in any resource - // of provided resource list - for (XXResource xResource : xResourceList) { - if (xResource.getResourceStatus() != AppConstants.STATUS_ENABLED) { - continue; - } - Long resourceId = xResource.getId(); - boolean hasPermission = checkUsrPermForPolicy(xUserId, permission, - resourceId); - // if permission is enabled then load Topologies,services list from resource - if (hasPermission) { - String[] xTopologies = (xResource.getTopologies() == null || xResource - .getTopologies().equalsIgnoreCase("")) ? null : stringUtil - .split(xResource.getTopologies(), ","); - /*String[] xServices = (xResource.getServices() == null || xResource - .getServices().equalsIgnoreCase("")) ? null - : stringUtil.split(xResource.getServices(), ",");*/ - - boolean matchFound = false; - - for (int index = 0; index < numberOfResources; index++) { - matchFound = false; - // check whether given table resource matches with any - // existing topology resource - if (index == 0) { - if(xTopologies!=null){ - for (String xTopology : xTopologies) { - if (matchPath(splittedResources[index], xTopology)) { - matchFound = true; - continue; - } - } - } - } // check whether given service resource matches with - // any existing service resource - /*else if (index == 1) { - if(xServices!=null){ - for (String xService : xServices) { - if (matchPath(splittedResources[index], - xService)) { - matchFound = true; - continue; - } - } - } - }*/ - } - if (matchFound) { - policyMatched = true; - break; - } - } - } - return policyMatched; - } + /** + * returns true if user is having required permission on given STORM + * resource + * + * @param resourceName + * @param xResourceList + * @param vXResponse + * @param xUserId + * @param permission + * @return + */ + private boolean matchStormPolicy(String resourceName, + List<XXResource> xResourceList, VXResponse vXResponse, + Long xUserId, int permission) { + + String[] splittedResources = stringUtil.split(resourceName, + fileSeparator); + int numberOfResources = splittedResources.length; + if (numberOfResources < 1 || numberOfResources > 3) { + logger.debug("Invalid policy name : " + resourceName); + return false; + } + + boolean policyMatched = false; + // check all resources whether Knox policy is enabled in any resource + // of provided resource list + for (XXResource xResource : xResourceList) { + if (xResource.getResourceStatus() != AppConstants.STATUS_ENABLED) { + continue; + } + Long resourceId = xResource.getId(); + boolean hasPermission = checkUsrPermForPolicy(xUserId, permission, + resourceId); + // if permission is enabled then load Topologies,services list from + // resource + if (hasPermission) { + String[] xTopologies = (xResource.getTopologies() == null || xResource + .getTopologies().equalsIgnoreCase("")) ? null + : stringUtil.split(xResource.getTopologies(), ","); + /* + * String[] xServices = (xResource.getServices() == null || + * xResource .getServices().equalsIgnoreCase("")) ? null : + * stringUtil.split(xResource.getServices(), ","); + */ + + boolean matchFound = false; + + for (int index = 0; index < numberOfResources; index++) { + matchFound = false; + // check whether given table resource matches with any + // existing topology resource + if (index == 0) { + if (xTopologies != null) { + for (String xTopology : xTopologies) { + if (matchPath(splittedResources[index], + xTopology)) { + matchFound = true; + continue; + } + } + } + } // check whether given service resource matches with + // any existing service resource + /* + * else if (index == 1) { if(xServices!=null){ for (String + * xService : xServices) { if + * (matchPath(splittedResources[index], xService)) { + * matchFound = true; continue; } } } } + */ + } + if (matchFound) { + policyMatched = true; + break; + } + } + } + return policyMatched; + } /** * returns path without meta characters @@ -1027,8 +1063,11 @@ public class RangerBizUtil { for (XXPermMap permMap : permMapList) { if (permMap.getPermType() == permission) { if (permMap.getPermFor() == AppConstants.XA_PERM_FOR_GROUP) { - // check whether permission is enabled for public group or a group to which user belongs - matchFound = (publicGroupId != null && publicGroupId == permMap.getGroupId()) || isGroupInList(permMap.getGroupId(), userGroups); + // check whether permission is enabled for public group or a + // group to which user belongs + matchFound = (publicGroupId != null && publicGroupId == permMap + .getGroupId()) + || isGroupInList(permMap.getGroupId(), userGroups); } else if (permMap.getPermFor() == AppConstants.XA_PERM_FOR_USER) { // check whether permission is enabled to user matchFound = permMap.getUserId().equals(xUserId); @@ -1040,9 +1079,10 @@ public class RangerBizUtil { } return matchFound; } - + public Long getPublicGroupId() { - XXGroup xXGroupPublic = daoManager.getXXGroup().findByGroupName(RangerConstants.GROUP_PUBLIC); + XXGroup xXGroupPublic = daoManager.getXXGroup().findByGroupName( + RangerConstants.GROUP_PUBLIC); return xXGroupPublic != null ? xXGroupPublic.getId() : null; } @@ -1194,7 +1234,7 @@ public class RangerBizUtil { */ private boolean matchPath(String pathToCheckFragment, String wildCardPathFragment) { - if(pathToCheckFragment == null || wildCardPathFragment == null) { + if (pathToCheckFragment == null || wildCardPathFragment == null) { return false; } @@ -1220,7 +1260,7 @@ public class RangerBizUtil { } } } - + private boolean matchPath(String pathToCheck, String[] wildCardPaths) { if (pathToCheck != null && wildCardPaths != null) { for (String wildCardPath : wildCardPaths) { @@ -1229,7 +1269,7 @@ public class RangerBizUtil { } } } - + return false; } @@ -1308,4 +1348,12 @@ public class RangerBizUtil { } } + public String getAuditDBType() { + return auditDBType; + } + + public void setAuditDBType(String auditDBType) { + this.auditDBType = auditDBType; + } + } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/security-admin/src/main/java/org/apache/ranger/biz/XAuditMgr.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/biz/XAuditMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/XAuditMgr.java index 9d69a95..d9812f9 100644 --- a/security-admin/src/main/java/org/apache/ranger/biz/XAuditMgr.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/XAuditMgr.java @@ -17,9 +17,46 @@ * under the License. */ - package org.apache.ranger.biz; +package org.apache.ranger.biz; + +import org.apache.ranger.common.SearchCriteria; +import org.apache.ranger.solr.SolrAccessAuditsService; +import org.apache.ranger.view.VXAccessAudit; +import org.apache.ranger.view.VXAccessAuditList; +import org.apache.ranger.view.VXLong; +import org.springframework.beans.factory.annotation.Autowired; public class XAuditMgr extends XAuditMgrBase { -} + @Autowired + SolrAccessAuditsService solrAccessAuditsService; + + @Autowired + RangerBizUtil rangerBizUtil; + + @Override + public VXAccessAudit getXAccessAudit(Long id) { + // TODO Auto-generated method stub + return super.getXAccessAudit(id); + } + @Override + public VXAccessAuditList searchXAccessAudits(SearchCriteria searchCriteria) { + if (rangerBizUtil.getAuditDBType().equalsIgnoreCase("solr")) { + return solrAccessAuditsService.searchXAccessAudits(searchCriteria); + } else { + return super.searchXAccessAudits(searchCriteria); + } + } + + @Override + public VXLong getXAccessAuditSearchCount(SearchCriteria searchCriteria) { + if (rangerBizUtil.getAuditDBType().equalsIgnoreCase("solr")) { + return solrAccessAuditsService + .getXAccessAuditSearchCount(searchCriteria); + } else { + return super.getXAccessAuditSearchCount(searchCriteria); + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java b/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java index b1482b6..962eb02 100644 --- a/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java +++ b/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java @@ -321,6 +321,9 @@ public abstract class RangerDaoManagerBase { } public XXAccessAuditDao getXXAccessAudit() { + //Load appropriate class based on audit store + //TODO: Need to fix this, currently hard coding Solr + return new XXAccessAuditDao(this); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/security-admin/src/main/java/org/apache/ranger/solr/SolrAccessAuditsService.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/solr/SolrAccessAuditsService.java b/security-admin/src/main/java/org/apache/ranger/solr/SolrAccessAuditsService.java new file mode 100644 index 0000000..d5d68b1 --- /dev/null +++ b/security-admin/src/main/java/org/apache/ranger/solr/SolrAccessAuditsService.java @@ -0,0 +1,253 @@ +/* + * 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.solr; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; +import org.apache.ranger.common.MessageEnums; +import org.apache.ranger.common.RESTErrorUtil; +import org.apache.ranger.common.SearchCriteria; +import org.apache.ranger.common.SearchField; +import org.apache.ranger.common.SortField; +import org.apache.ranger.common.StringUtil; +import org.apache.ranger.common.SearchField.DATA_TYPE; +import org.apache.ranger.common.SearchField.SEARCH_TYPE; +import org.apache.ranger.common.SortField.SORT_ORDER; +import org.apache.ranger.view.VXAccessAudit; +import org.apache.ranger.view.VXAccessAuditList; +import org.apache.ranger.view.VXLong; +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocument; +import org.apache.solr.common.SolrDocumentList; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Service; + +@Service +@Scope("singleton") +public class SolrAccessAuditsService { + static Logger logger = Logger.getLogger(SolrAccessAuditsService.class); + + @Autowired + SolrMgr solrMgr; + + @Autowired + SolrUtil solrUtil; + + @Autowired + RESTErrorUtil restErrorUtil; + + @Autowired + StringUtil stringUtil; + + public List<SortField> sortFields = new ArrayList<SortField>(); + public List<SearchField> searchFields = new ArrayList<SearchField>(); + + public SolrAccessAuditsService() { + + searchFields.add(new SearchField("id", "id", + SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.FULL)); + searchFields.add(new SearchField("accessType", "access", + SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.FULL)); + searchFields.add(new SearchField("aclEnforcer", "enforcer", + SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.FULL)); + searchFields.add(new SearchField("agentId", "agent", + SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.FULL)); + searchFields.add(new SearchField("repoName", "repo", + SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.FULL)); + searchFields.add(new SearchField("sessionId", "sess", + SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.FULL)); + searchFields.add(new SearchField("requestUser", "reqUser", + SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.FULL)); + searchFields.add(new SearchField("requestData", "reqData", + SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.PARTIAL)); + searchFields.add(new SearchField("resourcePath", "resource", + SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.PARTIAL)); + searchFields.add(new SearchField("clientIP", "cliIP", + SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.FULL)); + + searchFields.add(new SearchField("auditType", "logType", + SearchField.DATA_TYPE.INTEGER, SearchField.SEARCH_TYPE.FULL)); + searchFields.add(new SearchField("accessResult", "result", + SearchField.DATA_TYPE.INTEGER, SearchField.SEARCH_TYPE.FULL)); + // searchFields.add(new SearchField("assetId", "obj.assetId", + // SearchField.DATA_TYPE.INTEGER, SearchField.SEARCH_TYPE.FULL)); + searchFields.add(new SearchField("policyId", "policy", + SearchField.DATA_TYPE.INTEGER, SearchField.SEARCH_TYPE.FULL)); + searchFields.add(new SearchField("repoType", "repoType", + SearchField.DATA_TYPE.INTEGER, SearchField.SEARCH_TYPE.FULL)); + + searchFields.add(new SearchField("resourceType", "resType", + SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.FULL)); + searchFields.add(new SearchField("reason", "reason", + SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.FULL)); + searchFields.add(new SearchField("action", "action", + SearchField.DATA_TYPE.STRING, SearchField.SEARCH_TYPE.FULL)); + + searchFields.add(new SearchField("startDate", "evtTime", + DATA_TYPE.DATE, SEARCH_TYPE.GREATER_EQUAL_THAN)); + searchFields.add(new SearchField("endDate", "evtTime", DATA_TYPE.DATE, + SEARCH_TYPE.LESS_EQUAL_THAN)); + + sortFields.add(new SortField("eventTime", "evtTime", true, + SORT_ORDER.DESC)); + } + + public VXAccessAuditList searchXAccessAudits(SearchCriteria searchCriteria) { + + // Make call to Solr + SolrClient solrClient = solrMgr.getSolrClient(); + + if (solrClient == null) { + logger.warn("Solr client is null, so not running the query."); + throw restErrorUtil.createRESTException( + "Error connecting to search engine", + MessageEnums.ERROR_SYSTEM); + } + + VXAccessAuditList returnList = new VXAccessAuditList(); + List<VXAccessAudit> xAccessAuditList = new ArrayList<VXAccessAudit>(); + + QueryResponse response = solrUtil.searchResources(searchCriteria, + searchFields, sortFields, solrClient); + if (response == null) { + logger.warn("Error running search query. searchCriteria=" + + searchCriteria.toString()); + throw restErrorUtil.createRESTException( + "Error running search query", MessageEnums.ERROR_SYSTEM); + } + SolrDocumentList docs = response.getResults(); + for (int i = 0; i < docs.size(); i++) { + SolrDocument doc = docs.get(i); + VXAccessAudit vXAccessAudit = populateViewBean(doc); + xAccessAuditList.add(vXAccessAudit); + } + + returnList.setResultSize((int) docs.getNumFound()); + returnList.setStartIndex((int) docs.getStart()); + returnList.setVXAccessAudits(xAccessAuditList); + + return returnList; + } + + /** + * @param doc + * @return + */ + private VXAccessAudit populateViewBean(SolrDocument doc) { + VXAccessAudit accessAudit = new VXAccessAudit(); + Object value = null; + logger.info("doc=" + doc.toString()); + + value = doc.getFieldValue("id"); + if (value != null) { + // TODO: Converting ID to hashcode for now + accessAudit.setId((long) value.hashCode()); + } + + value = doc.getFieldValue("access"); + if (value != null) { + accessAudit.setAccessType(value.toString()); + } + + value = doc.getFieldValue("enforcer"); + if (value != null) { + accessAudit.setAclEnforcer(value.toString()); + } + value = doc.getFieldValue("agent"); + if (value != null) { + accessAudit.setAgentId(value.toString()); + } + value = doc.getFieldValue("repo"); + if (value != null) { + accessAudit.setRepoName(value.toString()); + } + value = doc.getFieldValue("sess"); + if (value != null) { + accessAudit.setSessionId(value.toString()); + } + value = doc.getFieldValue("reqUser"); + if (value != null) { + accessAudit.setRequestUser(value.toString()); + } + value = doc.getFieldValue("reqData"); + if (value != null) { + accessAudit.setRequestData(value.toString()); + } + value = doc.getFieldValue("resource"); + if (value != null) { + accessAudit.setResourcePath(value.toString()); + } + value = doc.getFieldValue("cliIP"); + if (value != null) { + accessAudit.setClientIP(value.toString()); + } + value = doc.getFieldValue("logType"); + if (value != null) { + // TODO: Need to see what logType maps to in UI +// accessAudit.setAuditType(solrUtil.toInt(value)); + } + value = doc.getFieldValue("result"); + if (value != null) { + accessAudit.setAccessResult(solrUtil.toInt(value)); + } + value = doc.getFieldValue("policy"); + if (value != null) { + accessAudit.setPolicyId(solrUtil.toLong(value)); + } + value = doc.getFieldValue("repoType"); + if (value != null) { + accessAudit.setRepoType(solrUtil.toInt(value)); + } + value = doc.getFieldValue("resType"); + if (value != null) { + accessAudit.setResourceType(value.toString()); + } + value = doc.getFieldValue("reason"); + if (value != null) { + accessAudit.setResultReason(value.toString()); + } + value = doc.getFieldValue("action"); + if (value != null) { + accessAudit.setAction(value.toString()); + } + value = doc.getFieldValue("evtTime"); + if (value != null) { + accessAudit.setEventTime(solrUtil.toDate(value)); + } + return accessAudit; + } + + /** + * @param searchCriteria + * @return + */ + public VXLong getXAccessAuditSearchCount(SearchCriteria searchCriteria) { + long count = 100; + + VXLong vXLong = new VXLong(); + vXLong.setValue(count); + return vXLong; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/security-admin/src/main/java/org/apache/ranger/solr/SolrMgr.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/solr/SolrMgr.java b/security-admin/src/main/java/org/apache/ranger/solr/SolrMgr.java new file mode 100644 index 0000000..60ef902 --- /dev/null +++ b/security-admin/src/main/java/org/apache/ranger/solr/SolrMgr.java @@ -0,0 +1,99 @@ +/* + * 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.solr; + +import java.util.Date; + +import org.apache.log4j.Logger; +import org.apache.ranger.biz.RangerBizUtil; +import org.apache.ranger.common.PropertiesUtil; +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.impl.BinaryRequestWriter; +import org.apache.solr.client.solrj.impl.HttpSolrClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * This class initializes Solr + * + */ +@Component +public class SolrMgr { + + static final Logger logger = Logger.getLogger(SolrMgr.class); + + @Autowired + RangerBizUtil rangerBizUtil; + + static final Object lock = new Object(); + + SolrClient solrClient = null; + Date lastConnectTime = null; + boolean initDone = false; + + public SolrMgr() { + + } + + void connect() { + if (!initDone) { + synchronized (lock) { + if (!initDone) { + if (rangerBizUtil.getAuditDBType().equalsIgnoreCase("solr")) { + String solrURL = PropertiesUtil + .getProperty("xa.audit.solr.url"); + if (solrURL == null || solrURL.isEmpty()) { + logger.fatal("Solr URL for Audit is empty"); + } + try { + solrClient = new HttpSolrClient(solrURL); + if (solrClient == null) { + logger.fatal("Can't connect to Solr. URL=" + + solrURL); + } else { + initDone = true; + if (solrClient instanceof HttpSolrClient) { + HttpSolrClient httpSolrClient = (HttpSolrClient) solrClient; + httpSolrClient.setAllowCompression(true); + httpSolrClient.setConnectionTimeout(1000); + // httpSolrClient.setSoTimeout(10000); + httpSolrClient.setMaxRetries(1); + httpSolrClient.setRequestWriter(new BinaryRequestWriter()); + } + } + + } catch (Throwable t) { + logger.fatal("Can't connect to Solr server. URL=" + + solrURL, t); + } + } + } + } + } + } + + public SolrClient getSolrClient() { + if (solrClient == null) { + connect(); + } + return solrClient; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/security-admin/src/main/java/org/apache/ranger/solr/SolrUtil.java ---------------------------------------------------------------------- diff --git a/security-admin/src/main/java/org/apache/ranger/solr/SolrUtil.java b/security-admin/src/main/java/org/apache/ranger/solr/SolrUtil.java new file mode 100644 index 0000000..2ce63a7 --- /dev/null +++ b/security-admin/src/main/java/org/apache/ranger/solr/SolrUtil.java @@ -0,0 +1,327 @@ +/* + * 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.solr; + +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.TimeZone; + +import org.apache.log4j.Logger; +import org.apache.ranger.common.MessageEnums; +import org.apache.ranger.common.PropertiesUtil; +import org.apache.ranger.common.RESTErrorUtil; +import org.apache.ranger.common.SearchCriteria; +import org.apache.ranger.common.SearchField; +import org.apache.ranger.common.SortField; +import org.apache.ranger.common.StringUtil; +import org.apache.ranger.common.SearchField.SEARCH_TYPE; +import org.apache.solr.client.solrj.SolrClient; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrQuery.ORDER; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.client.solrj.util.ClientUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class SolrUtil { + static final Logger logger = Logger.getLogger(SolrUtil.class); + + @Autowired + RESTErrorUtil restErrorUtil; + + @Autowired + StringUtil stringUtil; + + SimpleDateFormat dateFormat = new SimpleDateFormat( + "yyyy-MM-dd'T'HH:mm:ss'Z'"); + + public SolrUtil() { + String timeZone = PropertiesUtil.getProperty("xa.solr.timezone"); + if (timeZone != null) { + logger.info("Setting timezone to " + timeZone); + try { + dateFormat.setTimeZone(TimeZone.getTimeZone(timeZone)); + } catch (Throwable t) { + logger.error("Error setting timezone. timeZone=" + timeZone); + } + } + } + + public QueryResponse runQuery(SolrClient solrClient, SolrQuery solrQuery) { + if (solrQuery != null) { + QueryResponse response; + try { + response = solrClient.query(solrQuery); + return response; + } catch (Throwable e) { + logger.error("Error from Solr server.", e); + } + } + return null; + } + + public QueryResponse searchResources(SearchCriteria searchCriteria, + List<SearchField> searchFields, List<SortField> sortFieldList, + SolrClient solrClient) { + SolrQuery query = new SolrQuery(); + query.setQuery("*:*"); + if (searchCriteria.getParamList() != null) { + // For now assuming there is only date field where range query will + // be done. If we there are more than one, then we should create a + // hashmap for each field name + Date fromDate = null; + Date toDate = null; + String dateFieldName = null; + + for (SearchField searchField : searchFields) { + Object paramValue = searchCriteria.getParamValue(searchField + .getClientFieldName()); + if (paramValue == null || paramValue.toString().isEmpty()) { + continue; + } + String fieldName = searchField.getFieldName(); + if (paramValue instanceof Collection) { + String fq = orList(fieldName, (Collection<?>) paramValue); + if (fq != null) { + query.addFilterQuery(fq); + } + } else if (searchField.getDataType() == SearchField.DATA_TYPE.DATE) { + if (!(paramValue instanceof Date)) { + logger.error("Search file is not of java object instanceof Date"); + } else { + if (searchField.getSearchType() == SEARCH_TYPE.GREATER_EQUAL_THAN + || searchField.getSearchType() == SEARCH_TYPE.GREATER_THAN) { + fromDate = (Date) paramValue; + dateFieldName = fieldName; + } else if (searchField.getSearchType() == SEARCH_TYPE.LESS_EQUAL_THAN + || searchField.getSearchType() == SEARCH_TYPE.LESS_THAN) { + toDate = (Date) paramValue; + } + } + } else if (searchField.getSearchType() == SEARCH_TYPE.GREATER_EQUAL_THAN + || searchField.getSearchType() == SEARCH_TYPE.GREATER_THAN + || searchField.getSearchType() == SEARCH_TYPE.LESS_EQUAL_THAN + || searchField.getSearchType() == SEARCH_TYPE.LESS_THAN) { + // TODO: Need to handle range here + } else { + String fq = setField(fieldName, paramValue); + if (fq != null) { + query.addFilterQuery(fq); + } + } + } + if (fromDate != null || toDate != null) { + String fq = setDateRange(dateFieldName, fromDate, toDate); + if (fq != null) { + query.addFilterQuery(fq); + } + } + } + + setSortClause(searchCriteria, sortFieldList, query); + query.setStart(searchCriteria.getStartIndex()); + query.setRows(searchCriteria.getMaxRows()); + + // Fields to get + // query.setFields("myClassType", "id", "score", "globalId"); + if (logger.isDebugEnabled()) { + logger.debug("SOLR QUERY=" + query.toString()); + } + QueryResponse response = runQuery(solrClient, query); + + if (response == null || response.getStatus() != 0) { + logger.error("Error running query. query=" + query.toString() + + ", response=" + response); + throw restErrorUtil.createRESTException("Error running query", + MessageEnums.ERROR_SYSTEM); + } + return response; + } + + public String setField(String fieldName, Object value) { + if (value == null || value.toString().trim().length() == 0) { + return null; + } + return fieldName + + ":" + + ClientUtils.escapeQueryChars(value.toString().trim() + .toLowerCase()); + } + + public String setDateRange(String fieldName, Date fromDate, Date toDate) { + String fromStr = "*"; + String toStr = "NOW"; + if (fromDate != null) { + fromStr = dateFormat.format(fromDate); + } + if (toDate != null) { + toStr = dateFormat.format(toDate); + } + return fieldName + ":[" + fromStr + " TO " + toStr + "]"; + } + + public String orList(String fieldName, Collection<?> valueList) { + if (valueList == null || valueList.size() == 0) { + return null; + } + String expr = ""; + int count = -1; + for (Object value : valueList) { + count++; + if (count > 0) { + expr += " OR "; + } + expr += fieldName + + ":" + + ClientUtils.escapeQueryChars(value.toString() + .toLowerCase()); + } + if (valueList.size() == 0) { + return expr; + } else { + return "(" + expr + ")"; + } + + } + + public String andList(String fieldName, Collection<?> valueList) { + if (valueList == null || valueList.size() == 0) { + return null; + } + String expr = ""; + int count = -1; + for (Object value : valueList) { + count++; + if (count > 0) { + expr += " AND "; + } + expr += fieldName + + ":" + + ClientUtils.escapeQueryChars(value.toString() + .toLowerCase()); + } + if (valueList.size() == 0) { + return expr; + } else { + return "(" + expr + ")"; + } + } + + public void setSortClause(SearchCriteria searchCriteria, + List<SortField> sortFields, SolrQuery query) { + + // TODO: We are supporting single sort field only for now + String sortBy = searchCriteria.getSortBy(); + String querySortBy = null; + if (!stringUtil.isEmpty(sortBy)) { + sortBy = sortBy.trim(); + for (SortField sortField : sortFields) { + if (sortBy.equalsIgnoreCase(sortField.getParamName())) { + querySortBy = sortField.getFieldName(); + // Override the sortBy using the normalized value + searchCriteria.setSortBy(sortField.getParamName()); + break; + } + } + } + + if (querySortBy == null) { + for (SortField sortField : sortFields) { + if (sortField.isDefault()) { + querySortBy = sortField.getFieldName(); + // Override the sortBy using the default value + searchCriteria.setSortBy(sortField.getParamName()); + searchCriteria.setSortType(sortField.getDefaultOrder() + .name()); + break; + } + } + } + + if (querySortBy != null) { + // Add sort type + String sortType = searchCriteria.getSortType(); + ORDER order = ORDER.asc; + if (sortType != null && sortType.equalsIgnoreCase("desc")) { + order = ORDER.desc; + + } + query.addSort(querySortBy, order); + } + } + + // Utility methods + public int toInt(Object value) { + if (value == null) { + return 0; + } + if (value instanceof Integer) { + return (Integer) value; + } + if (value.toString().isEmpty()) { + return 0; + } + try { + return new Integer(value.toString()); + } catch (Throwable t) { + logger.error("Error converting value to integer. value=" + value, t); + } + return 0; + } + + public long toLong(Object value) { + if (value == null) { + return 0; + } + if (value instanceof Long) { + return (Long) value; + } + if (value.toString().isEmpty()) { + return 0; + } + try { + return new Long(value.toString()); + } catch (Throwable t) { + logger.error("Error converting value to long. value=" + value, t); + } + return 0; + } + + public Date toDate(Object value) { + if (value == null) { + return null; + } + if (value instanceof Date) { + return (Date) value; + } + try { + // TODO: Do proper parsing based on Solr response value + return new Date(value.toString()); + } catch (Throwable t) { + logger.error("Error converting value to date. value=" + value, t); + } + return null; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/src/main/assembly/hbase-agent.xml ---------------------------------------------------------------------- diff --git a/src/main/assembly/hbase-agent.xml b/src/main/assembly/hbase-agent.xml index 6ab569f..8dfbd5e 100644 --- a/src/main/assembly/hbase-agent.xml +++ b/src/main/assembly/hbase-agent.xml @@ -36,6 +36,12 @@ <includes> <include>com.google.code.gson:gson*</include> <include>org.eclipse.persistence:eclipselink</include> + <include>org.apache.ranger:ranger_solrj:jar:${ranger.solrj.version}</include> + <include>org.apache.httpcomponents:httpclient:jar:${httpcomponent.httpclient.version}</include> + <include>org.apache.httpcomponents:httpcore:jar:${httpcomponent.httpcore.version}</include> + <include>org.apache.httpcomponents:httpmime:jar:${httpcomponent.httpmime.version}</include> + <include>org.noggit:noggit:jar:${noggit.version}</include> + <include>org.apache.zookeeper:zookeeper:jar:${zookeeper.version}</include> </includes> <unpack>false</unpack> </dependencySet> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/src/main/assembly/hdfs-agent.xml ---------------------------------------------------------------------- diff --git a/src/main/assembly/hdfs-agent.xml b/src/main/assembly/hdfs-agent.xml index 7929231..27c2bf0 100644 --- a/src/main/assembly/hdfs-agent.xml +++ b/src/main/assembly/hdfs-agent.xml @@ -37,6 +37,12 @@ <include>com.google.code.gson:gson*</include> <include>org.eclipse.persistence:javax.persistence</include> <include>org.eclipse.persistence:eclipselink</include> + <include>org.apache.ranger:ranger_solrj:jar:${ranger.solrj.version}</include> + <include>org.apache.httpcomponents:httpclient:jar:${httpcomponent.httpclient.version}</include> + <include>org.apache.httpcomponents:httpcore:jar:${httpcomponent.httpcore.version}</include> + <include>org.apache.httpcomponents:httpmime:jar:${httpcomponent.httpmime.version}</include> + <include>org.noggit:noggit:jar:${noggit.version}</include> + <include>org.apache.zookeeper:zookeeper:jar:${zookeeper.version}</include> </includes> <unpack>false</unpack> </dependencySet> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/src/main/assembly/hive-agent.xml ---------------------------------------------------------------------- diff --git a/src/main/assembly/hive-agent.xml b/src/main/assembly/hive-agent.xml index e9035b4..f0bacb6 100644 --- a/src/main/assembly/hive-agent.xml +++ b/src/main/assembly/hive-agent.xml @@ -37,6 +37,12 @@ <include>com.google.code.gson:gson*</include> <include>org.eclipse.persistence:eclipselink</include> <include>org.eclipse.persistence:javax.persistence</include> + <include>org.apache.ranger:ranger_solrj:jar:${ranger.solrj.version}</include> + <include>org.apache.httpcomponents:httpclient:jar:${httpcomponent.httpclient.version}</include> + <include>org.apache.httpcomponents:httpcore:jar:${httpcomponent.httpcore.version}</include> + <include>org.apache.httpcomponents:httpmime:jar:${httpcomponent.httpmime.version}</include> + <include>org.noggit:noggit:jar:${noggit.version}</include> + <include>org.apache.zookeeper:zookeeper:jar:${zookeeper.version}</include> </includes> <unpack>false</unpack> </dependencySet> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/40aa090d/src/main/assembly/knox-agent.xml ---------------------------------------------------------------------- diff --git a/src/main/assembly/knox-agent.xml b/src/main/assembly/knox-agent.xml index 25604b2..fe7000a 100644 --- a/src/main/assembly/knox-agent.xml +++ b/src/main/assembly/knox-agent.xml @@ -41,6 +41,12 @@ <include>com.google.code.gson:gson*</include> <include>org.eclipse.persistence:eclipselink</include> <include>org.eclipse.persistence:javax.persistence</include> + <include>org.apache.ranger:ranger_solrj:jar:${ranger.solrj.version}</include> + <include>org.apache.httpcomponents:httpclient:jar:${httpcomponent.httpclient.version}</include> + <include>org.apache.httpcomponents:httpcore:jar:${httpcomponent.httpcore.version}</include> + <include>org.apache.httpcomponents:httpmime:jar:${httpcomponent.httpmime.version}</include> + <include>org.noggit:noggit:jar:${noggit.version}</include> + <include>org.apache.zookeeper:zookeeper:jar:${zookeeper.version}</include> </includes> <unpack>false</unpack> </dependencySet>
