All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.fabric8.elasticsearch.plugin.acl.SearchGuardACL Maven / Gradle / Ivy

/**
 * Copyright (C) 2015 Red Hat, Inc.
 *
 * Licensed 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 io.fabric8.elasticsearch.plugin.acl;

import static io.fabric8.elasticsearch.plugin.KibanaUserReindexFilter.getUsernameHash;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * Class representation of a ElasticSearch SearchGuard plugin ACL
 * 
 * @author jeff.cantrill
 *
 */
@JsonIgnoreProperties(ignoreUnknown=true)
public class SearchGuardACL implements Iterable{
	
	public static final String OPENSHIFT_SYNC = "[openshift-elasticsearch-plugin]";
	public static final String FLUENTD_USER = "system.logging.fluentd";
	public static final String KIBANA_USER = "system.logging.kibana";
	public static final String CURATOR_USER = "system.logging.curator";
	public static final String FLUENTD_EXECUTE_FILTER = "actionrequestfilter.fluentd";
	public static final String KIBANA_EXECUTE_FILTER = "actionrequestfilter.kibana";
	public static final String CURATOR_EXECUTE_FILTER = "actionrequestfilter.curator";
	public static final String KIBANA_INDEX = ".kibana.*";
	
	@JsonProperty(value="acl")
	private List acls;
	
	public static class Acl {
		
		@JsonProperty(value="__Comment__")
		private String comment = "";
		
		@JsonProperty(value="hosts")
		private List hosts = new ArrayList<>();
		
		@JsonProperty(value="users")
		private List users = new ArrayList<>();
		
		@JsonProperty(value="roles")
		private List roles = new ArrayList<>();
		
		@JsonProperty(value="indices")
		private List indices = new ArrayList<>();
		
		@JsonProperty(value="aliases")
		private List aliases = new ArrayList<>();
		
		@JsonProperty(value="filters_bypass")
		private List filtersBypass = new ArrayList<>();

		@JsonProperty(value="filters_execute")
		private List filtersExecute = new ArrayList<>();
		
		public String getComment() {
			return comment;
		}
		public void setComment(String comment) {
			this.comment = comment;
		}
		public List getHosts() {
			return hosts;
		}
		public void setHosts(List hosts) {
			this.hosts = hosts;
		}
		public List getUsers() {
			return users;
		}
		public void setUsers(List users) {
			this.users = users;
		}
		public List getRoles() {
			return roles;
		}
		public void setRoles(List roles) {
			this.roles = roles;
		}
		public List getIndices() {
			return indices;
		}
		public void setIndices(List indicies) {
			this.indices = indicies;
		}
		public List getAliases() {
			return aliases;
		}
		public void setAliases(List aliases) {
			this.aliases = aliases;
		}
		public List getFiltersBypass() {
			return filtersBypass;
		}
		public void setFiltersBypass(List filterBypass) {
			this.filtersBypass = filterBypass;
		}
		public List getFiltersExecute() {
			return filtersExecute;
		}
		public void setFiltersExecute(List filterExecute) {
			this.filtersExecute = filterExecute;
		}
		@Override
		public String toString() {
			return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
		}
		
		
	}

	/**
	 * An iterator that is safe to delete from 
	 * while spinning through the ACLs
	 */
	@Override
	public Iterator iterator() {
		return new ArrayList<>(acls).iterator();
	}
	
	/**
	 * Remove an ACL
	 * @param acl
	 */
	public void remove(Acl acl){
		acls.remove(acl);
	}
	
	public void syncFrom(UserProjectCache cache, final String userProfilePrefix){
		removeSyncAcls();
		for (Map.Entry> userProjects : cache.getUserProjects().entrySet()) {
			AclBuilder builder = new AclBuilder()
				.user(userProjects.getKey())
				.bypass("*")
				.projects(formatIndicies(userProjects.getKey(), userProjects.getValue(), userProfilePrefix));
			if(cache.isClusterAdmin(userProjects.getKey())){
				builder.project(".operations.*");
			}
			acls.add(builder.build());
		}
	}
	
	public void createInitialACLs() {
		
		if ( acls == null )
			acls = new ArrayList();

		// Create the default to deny all
		Acl defaultAcl = new AclBuilder().comment("Default is to deny all").build();
		acls.add(defaultAcl);
		
		// Create ACL so that fluentd can only write
		Acl fluentdAcl = new AclBuilder().user(FLUENTD_USER).executes(FLUENTD_EXECUTE_FILTER).comment("Fluentd can only write").build();
		acls.add(fluentdAcl);
		
		// Create ACL so that kibana can do anything in the kibana index
		Acl kibanaProjectAcl = new AclBuilder().user(KIBANA_USER).project(KIBANA_INDEX).bypass("*").comment("Kibana can do anything in the kibana index").build();
		acls.add(kibanaProjectAcl);
		
		// Create ACL so that kibana can only read every other index
		Acl kibanaOthersAcl = new AclBuilder().user(KIBANA_USER).executes(KIBANA_EXECUTE_FILTER).comment("Kibana can only read from every other index").build(); 
		acls.add(kibanaOthersAcl);

		// Create ACL so that curator can find out what indices are available, and delete them
		Acl curatorAcl = new AclBuilder().user(CURATOR_USER).executes(CURATOR_EXECUTE_FILTER).comment("Curator can list all indices and delete them").build();
		acls.add(curatorAcl);
	}
	
	private List formatIndicies(String user, Set projects, final String userProfilePrefix){
		ArrayList indicies = new ArrayList<>(projects.size());
		indicies.add(String.format("%s.%s", userProfilePrefix, getUsernameHash(user)));
		for (String project : projects) {
			indicies.add(String.format("%s.*", project));
		}
		return indicies;
	}
	private void removeSyncAcls() {
		for (Acl acl : new ArrayList<>(acls)) {
			if(acl.getComment() != null && acl.getComment().startsWith(OPENSHIFT_SYNC)){
				remove(acl);
			}
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy