Skip to content

Commit

Permalink
merged #5
Browse files Browse the repository at this point in the history
  • Loading branch information
salyh committed Jul 25, 2014
1 parent d99c0a5 commit 19070c3
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 41 deletions.
35 changes: 34 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,41 @@ This rule match if (the user is u1 or u2) and (has the role rol1 or role2) <br>
and (issues the request from host1 or host2) and (operates on i1 or i2 or both)<br>
and uses (documents of types t1 or t2 or both)<br>



<h3>elasticsearch-security-plugin for Kibana</h3>

Ram Kotamaraja provided some enhancements to make the plugin work with Kibana 3.
For details see https://github.com/rkotamaraja/elasticsearch-security-plugin/commits/master and https://github.com/salyh/elasticsearch-security-plugin/pull/5
Here is the documentation for this:

Added a new security index to provide security around kibana 3.0.0 fifth milestone. Kibana uses a generic search query such as http://elasticsearchhost:9200/testindex1/_search. To provide security around queries like that, the plugin is modified to support additional kibana configuration. Configuration is as follows.

<pre><code>
PUT /securityconfiguration/actionpathfilter/kibana
{
"rules": [
{
"index" : "testindex1",
"types" : [ "testtype1", "testtype5", "testtype13", "testtype7"]
},
{
"index" : "testindex2",
"types" : [ "testtype19", "testtype21" ]
},
{
"index" : "testdata",
"types" : [ ""testtype1", "testtype2" ]
}
]
}

</code></pre>

This configuration allows users to specify which types in a given index are accessible by users.

<h3>Contributers</h3>
* Ram Kotamaraja
* Ram Kotamaraja (https://github.com/rkotamaraja)

<p>
<p>
Expand Down
18 changes: 17 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,23 @@

<groupId>com.github.salyh.elasticsearch</groupId>
<artifactId>elasticsearch-security-plugin</artifactId>
<version>0.0.2.Beta6-ea1.2</version>
<version>0.0.2.Beta7-ea1.2</version>
<packaging>jar</packaging>

<name>elasticsearch-security-plugin</name>
<description>Provide security related features for elasticsearch</description>
<url>https://github.com/salyh/elasticsearch-security-plugin</url>
<inceptionYear>2013</inceptionYear>

<licenses>
<license>
<name>No License license - Copyright 2013-2014 Hendrik Saly</name>
<url>http://choosealicense.com/licenses/no-license</url>
<distribution>manual</distribution>
<comments>Copyright 2013-2014 Hendrik Saly</comments>
</license>
</licenses>

<properties>
<elasticsearch.version>1.2.2</elasticsearch.version>
<tomcat.version>7.0.54</tomcat.version>
Expand Down Expand Up @@ -43,6 +52,13 @@
</developer>
</developers>

<contributors>
<contributor>
<name>Ram Kotamaraja</name>
<url>https://github.com/rkotamaraja</url>
</contributor>
</contributors>


<parent>
<groupId>org.sonatype.oss</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.elasticsearch.plugins.security.http.tomcat.TomcatHttpServerRestRequest;
import org.elasticsearch.plugins.security.http.tomcat.TomcatUserRoleCallback;
import org.elasticsearch.plugins.security.service.SecurityService;
import org.elasticsearch.plugins.security.util.EditableRestRequest;
import org.elasticsearch.plugins.security.util.SecurityUtil;
import org.elasticsearch.rest.RestFilterChain;
import org.elasticsearch.rest.RestStatus;
Expand Down Expand Up @@ -83,6 +84,13 @@ public void processSecure(final TomcatHttpServerRestRequest request,
"No permission (for read actions)");
return;
}

// Ram Kotamarja - START
// adding code to modify request modification before it hits elastic
// search to apply the search filters
modifiyKibanaRequest(request, channel);
// Ram Kotamaraja - END


filterChain.continueProcessing(request, channel);
return;
Expand All @@ -105,12 +113,12 @@ public void processSecure(final TomcatHttpServerRestRequest request,
}

/**
* @author - Ram Kotamaraja Method added to modify the request on the fly to
* allow it to process generic queries coming from kibana by
* validating against the security framework
* Method added to modify the request on the fly to
* allow it to process generic queries coming from kibana by
* validating against the security framework (contributed by Ram Kotamaraja)
* @param request
*/
private void massageKibanaRequest(
private void modifiyKibanaRequest(
final TomcatHttpServerRestRequest request,
final TomcatHttpServerRestChannel channel) {

Expand All @@ -130,8 +138,7 @@ private void massageKibanaRequest(
kibanaPermLevel = securityService.getXContentSecurityConfiguration(
getType(), getKibanaId());
} catch (Exception e) {
log.debug("No Kibana configuration found, so continuing the rest of the process");
//log.debug("Generic error: ", e);
log.debug("No Kibana configuration found, so continuing the rest of the process: "+e.getMessage());
return;
}

Expand All @@ -143,8 +150,8 @@ private void massageKibanaRequest(
.getIndices(request));
}

String reqContent = request.content().toUtf8();
String massagedContent = reqContent;
final String reqContent = request.content().toUtf8();
String modifiedContent = reqContent;

// checking where the original request has any types
List<String> requestTypes = SecurityUtil.getTypes(request);
Expand All @@ -157,7 +164,7 @@ private void massageKibanaRequest(
if (kibanaTypesList != null) {

// determine authorized types list
// try {


Iterator<String> kibanaTypesItr = kibanaTypesList
.iterator();
Expand All @@ -181,48 +188,48 @@ private void massageKibanaRequest(
.getSettings()
.get("security.ssl.userattribute")));

// log.debug("Kibana perm level = "+permLevel);
log.debug("Kibana perm level = "+permLevel);

if (!permLevel.equals(PermLevel.NONE)) {
authorizedTypesList.addAll(kibanaType);
}
}

// authorizedTypesList = kibanaTypesList;


// log.debug("Processing kibana types "+ kibanaTypesList);
// log.debug("request Content = "+ reqContent);
log.debug("Processing kibana types "+ kibanaTypesList);
log.debug("request Content = "+ reqContent);

String kibanaFilterStarter = "\"must\":[";
int beginIndex = reqContent.indexOf(kibanaFilterStarter);
// log.debug("filterStarter index = "+ beginIndex );

if (beginIndex > 0) {
String preReqContent = reqContent.substring(0,
beginIndex + kibanaFilterStarter.length());
String postReqContent = reqContent.substring(beginIndex
+ kibanaFilterStarter.length());

massagedContent = preReqContent
modifiedContent = preReqContent
+ "{\"or\": {\"filters\":[";

if (authorizedTypesList != null) {
Iterator<String> authorizedTypesItr = authorizedTypesList
.iterator();
while (authorizedTypesItr.hasNext()) {
massagedContent += "{\"type\":{\"value\":\""
modifiedContent += "{\"type\":{\"value\":\""
+ authorizedTypesItr.next().toString()
+ "\"}},";
}
massagedContent = massagedContent.substring(0,
massagedContent.length() - 1);
modifiedContent = modifiedContent.substring(0,
modifiedContent.length() - 1);
}

massagedContent += "]}}," + postReqContent;
log.debug("massaged request = " + massagedContent);
//request.setContent(new BytesArray(massagedContent));
//request.setAttribute(
// TomcatHttpServerRestRequest.REQUEST_CONTENT_ATTRIBUTE,
//request.content());
modifiedContent += "]}}," + postReqContent;
log.debug("modified request content = " + modifiedContent);
request.setContent(new BytesArray(modifiedContent));
request.setAttribute(TomcatHttpServerRestRequest.REQUEST_CONTENT_ATTRIBUTE, request.getContent());

}
}
}
Expand All @@ -245,8 +252,8 @@ private void massageKibanaRequest(
}

/**
* @author Ram Kotamaraja Method to return the default id
* @return String - default id string
* Method to return the default id (contributed by Ram Kotamaraja)
* @return String - default id string
*/
protected String getKibanaId() {
return "kibana";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
* NOT USED YET Protecting documents/fields from being updated or deletet on
* dlstoken basis
*
* @author salyh
*
*/
public class DlsWriteFilter extends SecureRestFilter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ public void sendResponse(final RestResponse response) {
// TODO: also add more access control parameters
resp.addHeader("Access-Control-Max-Age", "1728000");

//@author - Ram Kotamaraja
//enhancing the list of allowed method list to meet the requirements of Kibana
//enhancing the list of allowed method list to meet the requirements of Kibana (contributed by Ram Kotamaraja)
resp.addHeader("Access-Control-Allow-Methods", "OPTIONS, HEAD, GET, POST, PUT, DELETE");
resp.addHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Content-Length");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class TomcatHttpServerRestRequest extends

private final Map<String, String> params;

private final BytesReference content;
private BytesReference content;

private final String opaqueId;

Expand Down Expand Up @@ -232,5 +232,32 @@ public Iterable<Entry<String, String>> headers() {
}



//next three methods contributed by Ram Kotamaraja

/**
* Setter Method for content
*/
public void setContent(BytesReference content) {
this.content = content;
}

/**
* Getter Method for returning content
* @return BytesReference
*/
public BytesReference getContent() {
return content;
}

/**
* Method added to modify the request query based on the authorization permission settings
* in the security configuration. This method will set the modified content in request.
* @param requestContentAttribute
* @param content
*/
public void setAttribute(String requestContentAttribute,
BytesReference content) {
this.request.setAttribute(requestContentAttribute, content);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ public List<DlsPermission> parseDlsPermissions(final BytesReference br)
}

/**
* @author Ram Kotamaraja
* (contributed by Ram Kotamaraja)
* @param indices - List of ES indices. Now supports only one index at a time.
* @return returns list of types configured in kibana security configuration
* @throws IOException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,9 @@ public T evaluatePerm(final List<String> indices, final List<String> types,
}


//@author - Ram Kotamaraja - START
//START
//added condition to check if indices provided are empty to validate the matching of index. This is required to allow requesting metadata queries like /_mapping, /_setting etc.
//(contributed by Ram Kotamaraja)
else
if(indices.isEmpty() && !p.indices.isEmpty() && !p.indices.contains("*") ){

Expand All @@ -287,7 +288,7 @@ public T evaluatePerm(final List<String> indices, final List<String> types,
continue permloop;

}
//@author - Ram Kotamaraja - END
//END

log.debug("All rules match, will apply " + p);
return p.permLevel;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.elasticsearch.plugins.security.util;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

Expand Down Expand Up @@ -30,6 +31,13 @@ public EditableRestRequest(final RestRequest innerRestquest) {
contentUnsafe = innerRestquest.contentUnsafe();

}

public void addParam(String key, String value){
if(params==null){
params=new HashMap<String, String>();
}
params.put(key, value);
}

public void setContent(final BytesReference content) {
this.content = content;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,11 @@ public static List<String> getIndices(final RestRequest request) {
}
*/
/**
*@author Ram Kotamaraja
*The above commented code handles code if there is a '/' at the end of the elastic search indices. Code is modified to handle indices where there is no '/' after it.
*Code below also handles the root level queries like '/_mapping', '/_settings' etc.
*/
/**
* (contributed by Ram Kotamaraja)
*The above commented code handles code if there is a '/' at the end of the elastic search indices. Code is modified to handle indices where there is no '/' after it.
*Code below also handles the root level queries like '/_mapping', '/_settings' etc.
*/

//Code modification START - Ram Kotamaraja
if ((path.indexOf('/', 1)) != -1) {
Expand Down

0 comments on commit 19070c3

Please sign in to comment.