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

org.codelibs.elasticsearch.auth.security.IndexAuthenticator Maven / Gradle / Ivy

There is a newer version: 1.4.0
Show newest version
package org.codelibs.elasticsearch.auth.security;

import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;

import java.util.Map;

import org.apache.commons.codec.digest.DigestUtils;
import org.codelibs.elasticsearch.auth.AuthException;
import org.codelibs.elasticsearch.auth.service.AuthService;
import org.codelibs.elasticsearch.auth.util.MapUtil;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestStatus;

public class IndexAuthenticator extends
        AbstractLifecycleComponent implements Authenticator {
    private static final ESLogger logger = Loggers
            .getLogger(IndexAuthenticator.class);;

    protected Client client;

    protected AuthService authService;

    protected String authIndex;

    protected String userType;

    protected String usernameKey;

    protected String passwordKey;

    @Inject
    public IndexAuthenticator(final Settings settings, final Client client,
            final AuthService authService) {
        super(settings);
        this.client = client;
        this.authService = authService;

        authIndex = settings.get("auth.authenticator.index.index", "auth");
        userType = settings.get("auth.authenticator.index.type", "user");
        usernameKey = settings.get("auth.authenticator.index.username",
                "username");
        passwordKey = settings.get("auth.authenticator.index.password",
                "password");

    }

    @Override
    protected void doStart() throws ElasticsearchException {
        logger.info("Registering IndexAuthenticator.");
        authService.registerAuthenticator("index", this);
    }

    @Override
    protected void doStop() throws ElasticsearchException {

    }

    @Override
    protected void doClose() throws ElasticsearchException {

    }

    @Override
    public void login(final RestRequest request,
            final ActionListener listener) {
        String username = request.param(usernameKey);
        String password = request.param(passwordKey);
        final BytesReference content = request.content();
        final XContentType xContentType = XContentFactory.xContentType(content);
        XContentParser parser = null;
        try {
            parser = XContentFactory.xContent(xContentType).createParser(
                    content);
            final XContentParser.Token t = parser.nextToken();
            if (t != null) {
                final Map contentMap = parser.map();
                username = MapUtil.getAsString(contentMap, usernameKey,
                        username);
                password = MapUtil.getAsString(contentMap, passwordKey,
                        password);
            }
        } catch (final Exception e) {
            listener.onFailure(e);
            return;
        } finally {
            if (parser != null) {
                parser.close();
            }
        }

        if (username == null) {
            listener.onResponse(new String[0]);
            return;
        }

        processLogin(username, password, listener);

    }

    private void processLogin(final String username, final String password,
            final ActionListener listener) {
        client.prepareGet(authIndex, userType, getUserId(username)).execute(
                new ActionListener() {

                    @Override
                    public void onResponse(final GetResponse response) {
                        final Map sourceMap = response
                                .getSource();
                        if (sourceMap != null) {
                            final String hash = (String) sourceMap
                                    .get("password");
                            if (hash != null
                                    && hash.equals(hashPassword(password))) {
                                if (logger.isDebugEnabled()) {
                                    logger.debug(sourceMap.get("username")
                                            + " is logged in.");
                                }
                                listener.onResponse(MapUtil.getAsArray(
                                        sourceMap, "roles", new String[0]));
                                return;
                            }
                        }
                        listener.onResponse(new String[0]);
                        return;
                    }

                    @Override
                    public void onFailure(final Throwable e) {
                        listener.onFailure(e);
                    }
                });
    }

    @Override
    public void createUser(final String username, final String password,
            final String[] roles, final ActionListener listener) {
        try {
            final XContentBuilder builder = jsonBuilder() //
                    .startObject() //
                    .field("username", username) //
                    .field("password", hashPassword(password)) //
                    .field("roles", roles) //
                    .endObject();
            client.prepareIndex(authIndex, userType, getUserId(username))
                    .setSource(builder).setRefresh(true)
                    .execute(new ActionListener() {
                        @Override
                        public void onResponse(final IndexResponse response) {
                            listener.onResponse(null);
                        }

                        @Override
                        public void onFailure(final Throwable e) {
                            listener.onFailure(new AuthException(
                                    RestStatus.INTERNAL_SERVER_ERROR,
                                    "Could not create " + username, e));
                        }
                    });
        } catch (final Exception e) {
            listener.onFailure(new AuthException(
                    RestStatus.INTERNAL_SERVER_ERROR, "Could not create "
                            + username, e));
        }
    }

    @Override
    public void updateUser(final String username, final String password,
            final String[] roles, final ActionListener listener) {
        try {
            final XContentBuilder builder = jsonBuilder().startObject()
                    .field("doc").startObject();
            if (password != null) {
                builder.field("password", hashPassword(password));
            }
            if (roles != null) {
                builder.field("roles", roles);
            }
            builder.endObject().endObject();
            final String userId = getUserId(username);
            client.prepareUpdate(authIndex, userType, userId)
                    .setSource(builder).setRefresh(true)
                    .execute(new ActionListener() {

                        @Override
                        public void onResponse(final UpdateResponse response) {
                            if (!userId.equals(response.getId())) {
                                listener.onFailure(new AuthException(
                                        RestStatus.BAD_REQUEST,
                                        "Could not update " + username));
                            } else {
                                listener.onResponse(null);
                            }
                        }

                        @Override
                        public void onFailure(final Throwable e) {
                            listener.onFailure(new AuthException(
                                    RestStatus.INTERNAL_SERVER_ERROR,
                                    "Could not update " + username, e));
                        }
                    });

        } catch (final Exception e) {
            listener.onFailure(new AuthException(
                    RestStatus.INTERNAL_SERVER_ERROR, "Could not update "
                            + username, e));
        }

    }

    @Override
    public void deleteUser(final String username,
            final ActionListener listener) {
        client.prepareDelete(authIndex, userType, getUserId(username))
                .setRefresh(true).execute(new ActionListener() {

                    @Override
                    public void onResponse(final DeleteResponse response) {
                        if (response.isFound()) {
                            listener.onResponse(null);
                        } else {
                            listener.onFailure(new AuthException(
                                RestStatus.BAD_REQUEST, "Could not delete "
                                + username));
                        }
                    }

                    @Override
                    public void onFailure(final Throwable e) {
                        listener.onFailure(new AuthException(
                                RestStatus.INTERNAL_SERVER_ERROR,
                                "Could not delete " + username, e));
                    }
                });

    }

    protected String getUserId(final String username) {
        return DigestUtils.sha512Hex(username);
    }

    protected String hashPassword(final String password) {
        if (password == null) {
            return "";
        }
        return DigestUtils.sha512Hex(password);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy