You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@eagle.apache.org by ha...@apache.org on 2017/02/22 08:12:37 UTC
[1/3] eagle git commit: [EAGLE-918] Support auth annotations
PermitAll/DenyAll/RolesAllowed and API
Repository: eagle
Updated Branches:
refs/heads/master a7df69e3a -> 94b597b77
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/test/java/org/apache/eagle/server/security/resource/BasicAuthenticationTestCase.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/test/java/org/apache/eagle/server/security/resource/BasicAuthenticationTestCase.java b/eagle-server/src/test/java/org/apache/eagle/server/security/resource/BasicAuthenticationTestCase.java
new file mode 100644
index 0000000..c848d19
--- /dev/null
+++ b/eagle-server/src/test/java/org/apache/eagle/server/security/resource/BasicAuthenticationTestCase.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.eagle.server.security.resource;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import io.dropwizard.testing.junit.DropwizardAppRule;
+import org.apache.eagle.common.Base64;
+import org.apache.eagle.common.security.User;
+import org.apache.eagle.server.ServerApplication;
+import org.apache.eagle.server.ServerConfig;
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+public class BasicAuthenticationTestCase {
+
+ @ClassRule
+ public static final DropwizardAppRule<ServerConfig> RULE =
+ new DropwizardAppRule<>(ServerApplication.class,
+ BasicAuthenticationTestCase.class.getResource("/configuration.yml").getPath());
+
+ private static final String USER_AUTH_KEY = "Basic " + Base64.encode("user:secret");
+ private static final String ADMIN_AUTH_KEY = "Basic " + Base64.encode("admin:secret");
+ private static final String BAD_AUTH_KEY = "Basic " + Base64.encode("bad:bad");
+
+ @Test
+ public void testAuthUserOnly() {
+ Client client = new Client();
+ client.resource(String.format("http://localhost:%d/rest/testAuth/userOnly", RULE.getLocalPort()))
+ .header("Authorization", USER_AUTH_KEY)
+ .get(User.class);
+ }
+
+ @Test (expected = UniformInterfaceException.class)
+ public void testAuthUserOnlyWitBadKey() {
+ Client client = new Client();
+ client.resource(String.format("http://localhost:%d/rest/testAuth/userOnly", RULE.getLocalPort()))
+ .header("Authorization", BAD_AUTH_KEY)
+ .get(User.class);
+ }
+
+ @Test
+ public void testAuthAdminOnly() {
+ Client client = new Client();
+ client.resource(String.format("http://localhost:%d/rest/testAuth/adminOnly", RULE.getLocalPort()))
+ .header("Authorization", ADMIN_AUTH_KEY)
+ .get(User.class);
+ }
+
+ @Test
+ public void testAdminOnlyWithoutAuth() {
+ Client client = new Client();
+ client.resource(String.format("http://localhost:%d/rest/testAuth/adminOnlyWithoutAuth", RULE.getLocalPort()))
+ .header("Authorization", ADMIN_AUTH_KEY)
+ .get(String.class);
+ }
+
+
+ @Test
+ public void testUserWithoutRole() {
+ Client client = new Client();
+ User user = client.resource(String.format("http://localhost:%d/rest/testAuth/userWithoutRole", RULE.getLocalPort()))
+ .header("Authorization", ADMIN_AUTH_KEY)
+ .get(User.class);
+ Assert.assertEquals("admin", user.getName());
+
+ user = client.resource(String.format("http://localhost:%d/rest/testAuth/userWithoutRole", RULE.getLocalPort()))
+ .header("Authorization", USER_AUTH_KEY)
+ .get(User.class);
+ Assert.assertEquals("user", user.getName());
+
+ try {
+ client.resource(String.format("http://localhost:%d/rest/testAuth/userWithoutRole", RULE.getLocalPort()))
+ .get(User.class);
+ Assert.fail();
+ } catch (UniformInterfaceException e) {
+ Assert.assertEquals(401, e.getResponse().getStatus());
+ }
+ }
+
+ @Test
+ public void testUserWithoutRequiredAuth() {
+ Client client = new Client();
+ String response = client.resource(String.format("http://localhost:%d/rest/testAuth/userWithNotRequiredAuth", RULE.getLocalPort()))
+ .header("Authorization", ADMIN_AUTH_KEY)
+ .get(String.class);
+ Assert.assertNotNull(response);
+ Assert.assertEquals("User found admin", response);
+
+ response = client.resource(String.format("http://localhost:%d/rest/testAuth/userWithNotRequiredAuth", RULE.getLocalPort()))
+ .get(String.class);
+ Assert.assertEquals("User not found", response);
+ }
+
+
+ @Test
+ public void testAdminOnlyWithoutAuthByUser() {
+ try {
+ Client client = new Client();
+ client.resource(String.format("http://localhost:%d/rest/testAuth/adminOnlyWithoutAuth", RULE.getLocalPort()))
+ .header("Authorization", USER_AUTH_KEY)
+ .get(String.class);
+ Assert.fail();
+ } catch (UniformInterfaceException e) {
+ Assert.assertEquals(403, e.getResponse().getStatus());
+ }
+ }
+
+ @Test
+ public void testAuthPermitAll() {
+ Client client = new Client();
+ client.resource(String.format("http://localhost:%d/rest/testAuth/permitAll", RULE.getLocalPort()))
+ .header("Authorization", USER_AUTH_KEY)
+ .get(User.class);
+ }
+
+ @Test
+ public void testAuthPermitAllWithoutKeyShouldPass() {
+ Client client = new Client();
+ try {
+ client.resource(String.format("http://localhost:%d/rest/testAuth/permitAll", RULE.getLocalPort()))
+ .get(User.class);
+ Assert.fail();
+ } catch (UniformInterfaceException e) {
+ Assert.assertEquals(204, e.getResponse().getStatus());
+ }
+ }
+
+ @Test
+ public void testAuthPermitAllWithBadKeyShouldAccept401() {
+ Client client = new Client();
+ try {
+ client.resource(String.format("http://localhost:%d/rest/testAuth/permitAll", RULE.getLocalPort()))
+ .header("Authorization", BAD_AUTH_KEY)
+ .get(User.class);
+ Assert.fail();
+ } catch (UniformInterfaceException e) {
+ Assert.assertEquals(401, e.getResponse().getStatus());
+ }
+ }
+
+ @Test(expected = UniformInterfaceException.class)
+ public void testAuthDenyAll() {
+ Client client = new Client();
+ client.resource(String.format("http://localhost:%d/rest/testAuth/denyAll", RULE.getLocalPort()))
+ .header("Authorization", USER_AUTH_KEY)
+ .get(User.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/test/java/org/apache/eagle/server/security/resource/TestBasicAuthenticationResource.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/test/java/org/apache/eagle/server/security/resource/TestBasicAuthenticationResource.java b/eagle-server/src/test/java/org/apache/eagle/server/security/resource/TestBasicAuthenticationResource.java
new file mode 100644
index 0000000..9e4ebf9
--- /dev/null
+++ b/eagle-server/src/test/java/org/apache/eagle/server/security/resource/TestBasicAuthenticationResource.java
@@ -0,0 +1,107 @@
+/*
+ * 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.eagle.server.security.resource;
+
+import io.dropwizard.auth.Auth;
+import org.apache.eagle.common.security.DenyAll;
+import org.apache.eagle.common.security.PermitAll;
+import org.apache.eagle.common.security.RolesAllowed;
+import org.apache.eagle.common.security.User;
+import org.junit.Ignore;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.SecurityContext;
+
+@Ignore
+@Path("/testAuth")
+public class TestBasicAuthenticationResource {
+ @GET
+ @Path("/userOnly")
+ @Produces(MediaType.APPLICATION_JSON)
+ @RolesAllowed(User.Role.USER)
+ public User getUser(@Auth User user) {
+ return user;
+ }
+
+ @GET
+ @Path("/adminOnly")
+ @Produces(MediaType.APPLICATION_JSON)
+ @RolesAllowed(User.Role.ADMINISTRATOR)
+ public User getAdminUser(@Auth User user) {
+ return user;
+ }
+
+ @GET
+ @Path("/adminOnlyWithoutAuth")
+ @Produces(MediaType.APPLICATION_JSON)
+ @RolesAllowed(User.Role.ADMINISTRATOR)
+ public String getAdminUserWithoutAuth() {
+ return "Success";
+ }
+
+ @GET
+ @Path("/userWithoutRole")
+ @Produces(MediaType.APPLICATION_JSON)
+ public User getUserWithoutRole(@Auth User user) {
+ return user;
+ }
+
+ @GET
+ @Path("/userWithNotRequiredAuth")
+ @Produces(MediaType.APPLICATION_JSON)
+ public String getUserWithNotRequiredAuth(@Auth(required = false) User user) {
+ if (user == null) {
+ return "User not found";
+ }
+ return "User found " + user.getName();
+ }
+
+ @GET
+ @Path("/userOrAdmin")
+ @Produces(MediaType.APPLICATION_JSON)
+ @RolesAllowed({User.Role.ADMINISTRATOR, User.Role.USER})
+ public User getUserOrAdmin(@Auth User user) {
+ return user;
+ }
+
+ @GET
+ @Path("/securityContext")
+ @Produces(MediaType.APPLICATION_JSON)
+ public SecurityContext getSecurityContext(@Context SecurityContext securityContext) {
+ return securityContext;
+ }
+
+ @GET
+ @Path("/permitAll")
+ @Produces(MediaType.APPLICATION_JSON)
+ @PermitAll
+ public User getPermitAllUser(@Auth(required = false) User user) {
+ return user;
+ }
+
+ @GET
+ @Path("/denyAll")
+ @Produces(MediaType.APPLICATION_JSON)
+ @DenyAll
+ public User getDenyAllUser(@Auth User user) {
+ return user;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/test/resources/configuration.yml
----------------------------------------------------------------------
diff --git a/eagle-server/src/test/resources/configuration.yml b/eagle-server/src/test/resources/configuration.yml
index eabb8a1..b49da04 100644
--- a/eagle-server/src/test/resources/configuration.yml
+++ b/eagle-server/src/test/resources/configuration.yml
@@ -26,7 +26,7 @@ server:
# ---------------------------------------------
auth:
# indicating if authentication is enabled, true for enabled, false for disabled
- enabled: false
+ enabled: true
# indicating authentication mode, "simple" or "ldap"
mode: simple
@@ -38,18 +38,28 @@ auth:
# indicating the cache policy, containing maximumSize and expireAfterWrite, e.g. maximumSize=10000, expireAfterWrite=10m
cachePolicy: maximumSize=10000, expireAfterWrite=1m
- # indicating whether authorization is needed
- authorization: false
-
- # indicating whether @Auth annotation on parameters is needed
- annotated: true
-
# for basic authentication, effective only when auth.mode=simple
+ # default password is "secret"
simple:
- # username for basic authentication, effective only when auth.mode=simple
- username: admin
- # password for basic authentication, effective only when auth.mode=simple
- password: secret
+ accounts:
+ - name: admin
+ password: rWV/cdTCr01wTLBQ/rUilkExd2TJKrifXuCCTEwig1o08K8Mi0b1qQAgVXpPqflb
+ roles: ADMINISTRATOR
+ firstName: Admin
+ lastName: Test
+ email: mock-admin@eagle.apache.org
+ - name: user
+ password: rWV/cdTCr01wTLBQ/rUilkExd2TJKrifXuCCTEwig1o08K8Mi0b1qQAgVXpPqflb
+ roles: USER
+ firstName: User
+ lastName: Test
+ email: mock-user@eagle.apache.org
+ - name: app
+ password: rWV/cdTCr01wTLBQ/rUilkExd2TJKrifXuCCTEwig1o08K8Mi0b1qQAgVXpPqflb
+ firstName: Application
+ lastName: Test
+ roles: APPLICATION
+ email: mock-support@eagle.apache.org
# for ldap authentication, effective only when auth.mode=ldap
ldap:
@@ -58,7 +68,7 @@ auth:
providerUrl: ldap://server.address.or.domain:port
# template string containing ${USERNAME} placeholder. This is designed for some orgs who don't use plain usernames
- # to authenticate, e.g. they may use its members' email address as the username: ${USERNAME}@some.org. When username
+ # to authenticate, e.g. they may use its members' email address as the name: ${USERNAME}@some.org. When name
# is supposed to be recognized originally, just configure this parameter as ${USERNAME}
principalTemplate: ${USERNAME}@maybe.email.suffix
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index daa24a2..34f73ef 100755
--- a/pom.xml
+++ b/pom.xml
@@ -234,6 +234,7 @@
<metrics.version>3.1.0</metrics.version>
<mapdb.version>3.0.0-M6</mapdb.version>
<asm.version>5.0</asm.version>
+ <jasypt.version>1.9.2</jasypt.version>
<!-- Streaming -->
<!--<kafka.version>0.10.0.0</kafka.version>-->
@@ -486,6 +487,11 @@
<artifactId>reflections</artifactId>
<version>${reflections.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.jasypt</groupId>
+ <artifactId>jasypt</artifactId>
+ <version>${jasypt.version}</version>
+ </dependency>
<!-- Serialization -->
<dependency>
@@ -1318,6 +1324,11 @@
</build>
<repositories>
<repository>
+ <id>maven.central</id>
+ <name>Maven Central Repository</name>
+ <url>http://central.maven.org/maven2</url>
+ </repository>
+ <repository>
<id>maven.repo1</id>
<name>Maven Repo1 Repository</name>
<url>http://repo1.maven.org/maven2</url>
[2/3] eagle git commit: [EAGLE-918] Support auth annotations
PermitAll/DenyAll/RolesAllowed and API
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/security/BasicAuthBuilder.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/security/BasicAuthBuilder.java b/eagle-server/src/main/java/org/apache/eagle/server/security/BasicAuthBuilder.java
new file mode 100644
index 0000000..8d41a90
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/security/BasicAuthBuilder.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.eagle.server.security;
+
+import com.google.common.cache.CacheBuilderSpec;
+import com.sun.jersey.api.core.HttpContext;
+import com.sun.jersey.api.model.Parameter;
+import com.sun.jersey.core.spi.component.ComponentContext;
+import com.sun.jersey.server.impl.inject.AbstractHttpContextInjectable;
+import com.sun.jersey.spi.inject.Injectable;
+import io.dropwizard.auth.Auth;
+import io.dropwizard.auth.Authenticator;
+import io.dropwizard.auth.CachingAuthenticator;
+import io.dropwizard.auth.basic.BasicAuthProvider;
+import io.dropwizard.auth.basic.BasicCredentials;
+import io.dropwizard.setup.Environment;
+import org.apache.eagle.common.security.User;
+import org.apache.eagle.server.security.authenticator.LdapBasicAuthenticator;
+import org.apache.eagle.server.security.authenticator.SimpleBasicAuthenticator;
+import org.apache.eagle.server.security.config.AuthenticationConfig;
+
+import java.util.Arrays;
+
+public class BasicAuthBuilder {
+ private static final String SIMPLE_MODE_REALM = "SIMPLE_BASIC_AUTHENTICATION";
+ private static final String LDAP_MODE_REALM = "LDAP_BASIC_AUTHENTICATION";
+ private final Authenticator<BasicCredentials, User> authenticator;
+ private final BasicAuthProvider basicAuthProvider;
+ private AuthenticationConfig authConfig;
+ private Environment environment;
+
+ public BasicAuthBuilder(AuthenticationConfig authConfig, Environment environment) {
+ this.authConfig = authConfig;
+ this.environment = environment;
+ boolean needsCaching = authConfig.needsCaching();
+ Authenticator<BasicCredentials, User> authenticator;
+ String realm;
+ if (authConfig.isEnabled()) {
+ switch (authConfig.getMode()) {
+ case "simple":
+ authenticator = new SimpleBasicAuthenticator(authConfig.getSimple());
+ realm = SIMPLE_MODE_REALM;
+ break;
+ case "ldap":
+ authenticator = new LdapBasicAuthenticator(authConfig.getLdap());
+ realm = LDAP_MODE_REALM;
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid auth mode " + authConfig.getMode());
+ }
+ if (needsCaching) {
+ authenticator = cache(authenticator);
+ }
+ this.authenticator = authenticator;
+ this.basicAuthProvider = new BasicAuthProvider<>(this.authenticator, realm);
+ } else {
+ this.authenticator = null;
+ this.basicAuthProvider = new BasicAuthProvider<User>(null, "") {
+ public Injectable<User> getInjectable(ComponentContext ic, Auth a, Parameter c) {
+ return new AbstractHttpContextInjectable<User>() {
+ public User getValue(HttpContext c) {
+ User user = new User();
+ user.setName("anonymous");
+ user.setFirstName("Anonymous User (auth: false)");
+ user.setRoles(Arrays.asList(User.Role.ALL_ROLES));
+ return user;
+ }
+ };
+ }
+ };
+ }
+ }
+
+ public BasicAuthProvider getBasicAuthProvider() {
+ return this.basicAuthProvider;
+ }
+
+ public Authenticator<BasicCredentials, User> getBasicAuthenticator() {
+ return this.authenticator;
+ }
+
+ private Authenticator<BasicCredentials, User> cache(Authenticator<BasicCredentials, User> authenticator) {
+ return new CachingAuthenticator<>(environment.metrics(), authenticator, CacheBuilderSpec.parse(authConfig.getCachePolicy()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/security/BasicAuthRequestFilter.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/security/BasicAuthRequestFilter.java b/eagle-server/src/main/java/org/apache/eagle/server/security/BasicAuthRequestFilter.java
new file mode 100644
index 0000000..1542505
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/security/BasicAuthRequestFilter.java
@@ -0,0 +1,161 @@
+package org.apache.eagle.server.security;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.sun.jersey.api.model.AbstractMethod;
+import com.sun.jersey.core.util.Base64;
+import com.sun.jersey.core.util.Priority;
+import com.sun.jersey.spi.container.ContainerRequest;
+import com.sun.jersey.spi.container.ContainerRequestFilter;
+import io.dropwizard.auth.Auth;
+import io.dropwizard.auth.AuthenticationException;
+import io.dropwizard.auth.Authenticator;
+import io.dropwizard.auth.basic.BasicCredentials;
+import org.apache.eagle.common.rest.RESTResponse;
+import org.apache.eagle.common.security.DenyAll;
+import org.apache.eagle.common.security.PermitAll;
+import org.apache.eagle.common.security.RolesAllowed;
+import org.apache.eagle.common.security.User;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Priorities;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.ext.Provider;
+import java.lang.reflect.Parameter;
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.List;
+import java.util.StringTokenizer;
+
+@Provider
+@Priority(Priorities.AUTHORIZATION)
+public class BasicAuthRequestFilter implements ContainerRequestFilter {
+ private final Authenticator<BasicCredentials, User> authenticator;
+ private final AbstractMethod method;
+ private static final Logger LOG = LoggerFactory.getLogger(BasicAuthRequestFilter.class);
+ private boolean isSecurityDefined = false;
+ private boolean isAuthRequired = false;
+ private boolean hasPermitAllAnnotation = false;
+ private boolean hasDenyAllAnnotation = false;
+ private boolean hasRolesAllowedAnnotation = false;
+
+ public BasicAuthRequestFilter(Authenticator<BasicCredentials, User> authenticator, AbstractMethod method) {
+ this.authenticator = authenticator;
+ this.method = method;
+ this.hasPermitAllAnnotation = method.isAnnotationPresent(PermitAll.class);
+ this.hasDenyAllAnnotation = method.isAnnotationPresent(DenyAll.class);
+ this.hasRolesAllowedAnnotation = method.isAnnotationPresent(RolesAllowed.class);
+ this.isSecurityDefined = this.hasPermitAllAnnotation || this.hasDenyAllAnnotation || this.hasRolesAllowedAnnotation;
+ for (Parameter parameter : method.getMethod().getParameters()) {
+ if (isSecurityDefined && isAuthRequired) {
+ break;
+ }
+ Auth[] authAnnotations = parameter.getAnnotationsByType(Auth.class);
+ this.isSecurityDefined = this.isSecurityDefined || authAnnotations.length > 0;
+ for (Auth auth : authAnnotations) {
+ this.isAuthRequired = this.isAuthRequired || auth.required();
+ }
+ }
+ Preconditions.checkArgument(!(this.hasDenyAllAnnotation && this.hasPermitAllAnnotation), "Conflict @DenyAll and @PermitAll on method " + this.method.toString());
+ }
+
+
+ private static final String AUTHORIZATION_PROPERTY = "Authorization";
+ private static final String AUTHENTICATION_SCHEME = "Basic";
+ private static final Response UNAUTHORIZED_ACCESS_DENIED = RESTResponse.builder()
+ .message("Unauthorized access denied")
+ .status(false, Response.Status.UNAUTHORIZED)
+ .build();
+
+ private static final Response ALL_ACCESS_DENIED = RESTResponse.builder()
+ .message("Access denied")
+ .status(false, Response.Status.FORBIDDEN)
+ .build();
+
+ @Override
+ public ContainerRequest filter(ContainerRequest containerRequest) {
+ if (!isSecurityDefined) {
+ return containerRequest;
+ }
+ //Access denied for all
+
+ if (hasDenyAllAnnotation) {
+ throw new WebApplicationException(ALL_ACCESS_DENIED);
+ }
+
+ //Get request headers
+ final MultivaluedMap<String, String> headers = containerRequest.getRequestHeaders();
+
+ //Fetch authorization header
+ final List<String> authorization = headers.get(AUTHORIZATION_PROPERTY);
+
+ //If no authorization information present; block access
+ if ((authorization == null || authorization.isEmpty()) && isAuthRequired) {
+ throw new WebApplicationException(UNAUTHORIZED_ACCESS_DENIED);
+ }
+
+ if (authorization != null) {
+ //Get encoded username and password
+ final String encodedUserPassword = authorization.get(0).replaceFirst(AUTHENTICATION_SCHEME + " ", "");
+
+ //Decode username and password
+ String usernameAndPassword = new String(Base64.decode(encodedUserPassword.getBytes()));
+
+ //Split username and password tokens
+ final StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, ":");
+ final String username = tokenizer.nextToken();
+ final String password = tokenizer.nextToken();
+
+ try {
+ Optional<User> userOptional = this.authenticator.authenticate(new BasicCredentials(username, password));
+ if (userOptional.isPresent()) {
+ User user = userOptional.get();
+ containerRequest.setSecurityContext(new SecurityContext() {
+ @Override
+ public Principal getUserPrincipal() {
+ return user;
+ }
+
+ @Override
+ public boolean isUserInRole(String role) {
+ return user.isInRole(User.Role.locateCaseInsensitive(role));
+ }
+
+ @Override
+ public boolean isSecure() {
+ return "https".equals(containerRequest.getRequestUri().getScheme());
+ }
+
+ @Override
+ public String getAuthenticationScheme() {
+ return "Basic Auth";
+ }
+ });
+
+ //Verify user access
+ if (hasRolesAllowedAnnotation && !hasPermitAllAnnotation) {
+ RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class);
+ if (!user.isInRole(rolesAnnotation.value())) {
+ throw new WebApplicationException(
+ RESTResponse.builder()
+ .status(false, Response.Status.FORBIDDEN)
+ .message("Access forbidden, required roles: " + Arrays.toString(rolesAnnotation.value()))
+ .build());
+ }
+ }
+ } else {
+ throw new WebApplicationException(UNAUTHORIZED_ACCESS_DENIED);
+ }
+ } catch (AuthenticationException e) {
+ LOG.error("Server authentication error: " + e.getMessage(), e);
+ throw new WebApplicationException(Response.status(Response.Status.INTERNAL_SERVER_ERROR)
+ .entity("Server authentication error: " + e.getMessage()).build());
+ }
+ }
+ return containerRequest;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/security/BasicAuthResourceFilterFactory.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/security/BasicAuthResourceFilterFactory.java b/eagle-server/src/main/java/org/apache/eagle/server/security/BasicAuthResourceFilterFactory.java
new file mode 100644
index 0000000..e6b8522
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/security/BasicAuthResourceFilterFactory.java
@@ -0,0 +1,53 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.eagle.server.security;
+
+
+import com.sun.jersey.api.model.AbstractMethod;
+import com.sun.jersey.spi.container.ContainerRequestFilter;
+import com.sun.jersey.spi.container.ContainerResponseFilter;
+import com.sun.jersey.spi.container.ResourceFilter;
+import com.sun.jersey.spi.container.ResourceFilterFactory;
+import io.dropwizard.auth.Authenticator;
+import io.dropwizard.auth.basic.BasicCredentials;
+import org.apache.eagle.common.security.User;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class BasicAuthResourceFilterFactory implements ResourceFilterFactory {
+ private final Authenticator<BasicCredentials, User> authenticator;
+
+ public BasicAuthResourceFilterFactory(Authenticator<BasicCredentials, User> authenticator) {
+ this.authenticator = authenticator;
+ }
+
+ @Override
+ public List<ResourceFilter> create(AbstractMethod abstractMethod) {
+ return Arrays.asList(new ResourceFilter() {
+ @Override
+ public ContainerRequestFilter getRequestFilter() {
+ return new BasicAuthRequestFilter(authenticator, abstractMethod);
+ }
+
+ @Override
+ public ContainerResponseFilter getResponseFilter() {
+ return null;
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/security/authenticator/LdapBasicAuthenticator.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/security/authenticator/LdapBasicAuthenticator.java b/eagle-server/src/main/java/org/apache/eagle/server/security/authenticator/LdapBasicAuthenticator.java
new file mode 100644
index 0000000..bc50c82
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/security/authenticator/LdapBasicAuthenticator.java
@@ -0,0 +1,106 @@
+/*
+ * 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.eagle.server.security.authenticator;
+
+import com.google.common.base.Optional;
+import io.dropwizard.auth.AuthenticationException;
+import io.dropwizard.auth.Authenticator;
+import io.dropwizard.auth.basic.BasicCredentials;
+import org.apache.eagle.common.security.User;
+import org.apache.eagle.server.security.config.LdapConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.Context;
+import javax.naming.directory.InitialDirContext;
+import java.io.File;
+import java.util.Hashtable;
+
+public class LdapBasicAuthenticator implements Authenticator<BasicCredentials, User> {
+ private static final Logger LOGGER = LoggerFactory.getLogger(LdapBasicAuthenticator.class);
+ private static final String LDAP_LDAP_CTX_FACTORY_NAME = "com.sun.jndi.ldap.LdapCtxFactory";
+ private static final String LDAP_CONNECT_TIMEOUT_KEY = "com.sun.jndi.ldap.connect.timeout";
+ private static final String LDAP_READ_TIMEOUT_KEY = "com.sun.jndi.ldap.read.timeout";
+ private static final String SYS_PROP_SSL_KEY_STORE = "javax.net.ssl.keyStore";
+ private static final String SYS_PROP_SSL_TRUST_STORE = "javax.net.ssl.trustStore";
+ private static final String LDAPS_URL_PREFIX = "ldaps://";
+ private static final String SSL_PROTOCOL_VALUE = "ssl";
+ private LdapConfig settings = null;
+
+ public LdapBasicAuthenticator(LdapConfig settings) {
+ this.settings = settings;
+ }
+
+ public Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException {
+ String sanitizedUsername = sanitizeUsername(credentials.getUsername());
+ try {
+ new InitialDirContext(getContextEnvironment(sanitizedUsername, credentials.getPassword()));
+ return Optional.of(new User(sanitizedUsername));
+ } catch (javax.naming.AuthenticationException ae) {
+ LOGGER.warn(String.format("Authentication failed for user[%s]: wrong username or password", sanitizedUsername));
+ return Optional.absent();
+ } catch (Exception e) {
+ throw new AuthenticationException(String.format("Error occurs while trying to authenticate for user[%s]: %s", sanitizedUsername, e.getMessage()), e);
+ }
+ }
+
+ Hashtable<String, String> getContextEnvironment(String sanitizedUsername, String password) {
+ String providerUrl = settings.getProviderUrl();
+ if (providerUrl == null) {
+ throw new IllegalArgumentException("providerUrl of the ldap service shouldn't be null");
+ }
+
+ Hashtable<String, String> env = new Hashtable<>();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, LDAP_LDAP_CTX_FACTORY_NAME);
+ env.put(Context.PROVIDER_URL, providerUrl);
+ env.put(LDAP_CONNECT_TIMEOUT_KEY, String.valueOf(settings.getConnectingTimeout().toMilliseconds()));
+ env.put(LDAP_READ_TIMEOUT_KEY, String.valueOf(settings.getReadingTimeout().toMilliseconds()));
+
+ String strategy = settings.getStrategy();
+ if (!"".equals(strategy)) {
+ env.put(Context.SECURITY_AUTHENTICATION, strategy);
+ }
+
+ if (providerUrl.toLowerCase().startsWith(LDAPS_URL_PREFIX)) { // using ldap over ssl to authenticate
+ env.put(Context.SECURITY_PROTOCOL, SSL_PROTOCOL_VALUE);
+
+ String certificateAbsolutePath = settings.getCertificateAbsolutePath();
+ if (certificateAbsolutePath == null || "".equals(certificateAbsolutePath)) {
+ throw new RuntimeException("The attribute 'certificateAbsolutePath' must be set when using ldap over ssl to authenticate.");
+ }
+ if (!new File(certificateAbsolutePath).exists()) {
+ throw new RuntimeException(String.format("The file specified not existing: %s", certificateAbsolutePath));
+ }
+
+ System.setProperty(SYS_PROP_SSL_KEY_STORE, certificateAbsolutePath);
+ System.setProperty(SYS_PROP_SSL_TRUST_STORE, certificateAbsolutePath);
+ }
+
+ env.put(Context.SECURITY_PRINCIPAL, comprisePrincipal(sanitizedUsername));
+ env.put(Context.SECURITY_CREDENTIALS, password);
+ return env;
+ }
+
+ String comprisePrincipal(String sanitizedUsername) {
+ return settings.getPrincipalTemplate().replaceAll("\\$\\{USERNAME\\}", sanitizedUsername);
+ }
+
+ String sanitizeUsername(String username) {
+ return username.replaceAll("[^a-zA-Z0-9_.]", "");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/security/authenticator/SimpleBasicAuthenticator.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/security/authenticator/SimpleBasicAuthenticator.java b/eagle-server/src/main/java/org/apache/eagle/server/security/authenticator/SimpleBasicAuthenticator.java
new file mode 100644
index 0000000..63dfd3b
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/security/authenticator/SimpleBasicAuthenticator.java
@@ -0,0 +1,59 @@
+/*
+ * 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.eagle.server.security.authenticator;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import io.dropwizard.auth.AuthenticationException;
+import io.dropwizard.auth.Authenticator;
+import io.dropwizard.auth.basic.BasicCredentials;
+import org.apache.eagle.common.security.User;
+import org.apache.eagle.server.security.config.SimpleConfig;
+import org.apache.eagle.server.security.config.UserAccount;
+import org.apache.eagle.server.security.encrypt.EncryptorFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+public class SimpleBasicAuthenticator implements Authenticator<BasicCredentials, User> {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SimpleBasicAuthenticator.class);
+ private final Map<String, UserAccount> userAccountRepository;
+
+ public SimpleBasicAuthenticator(SimpleConfig config) {
+ userAccountRepository = new HashMap<>();
+ for (UserAccount userAccount : config.getAccounts()) {
+ Preconditions.checkNotNull(userAccount.getName(), " Username is null " + userAccount);
+ Preconditions.checkArgument(!userAccountRepository.containsKey(userAccount.getName()), "Duplicated user name: " + userAccount.getName());
+ if (userAccount.getRoles() == null) {
+ LOGGER.warn("UserPrincipal {} has no roles, set as {} by default", userAccount.getName(), User.Role.USER);
+ userAccount.setRoles(User.Role.USER.toString());
+ }
+ userAccountRepository.put(userAccount.getName(), userAccount);
+ }
+ }
+
+ public Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException {
+ if (userAccountRepository.containsKey(credentials.getUsername())
+ && EncryptorFactory.getPasswordEncryptor().checkPassword(credentials.getPassword(), userAccountRepository.get(credentials.getUsername()).getEncryptedPassword())) {
+ UserAccount userAccount = userAccountRepository.get(credentials.getUsername());
+ return Optional.of(new User(userAccount));
+ } else {
+ return Optional.absent();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/security/config/AuthenticationConfig.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/security/config/AuthenticationConfig.java b/eagle-server/src/main/java/org/apache/eagle/server/security/config/AuthenticationConfig.java
new file mode 100644
index 0000000..dbbb13b
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/security/config/AuthenticationConfig.java
@@ -0,0 +1,95 @@
+/*
+ * 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.eagle.server.security.config;
+
+import io.dropwizard.Configuration;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class AuthenticationConfig extends Configuration {
+ private boolean enabled = false;
+ private String mode = null;
+ private boolean caching = false;
+ private String cachePolicy = null;
+ private SimpleConfig simple = new SimpleConfig();
+ private LdapConfig ldap = new LdapConfig();
+
+ @JsonProperty
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ @JsonProperty
+ public AuthenticationConfig setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ return this;
+ }
+
+ @JsonProperty
+ public String getMode() {
+ return mode;
+ }
+
+ @JsonProperty
+ public AuthenticationConfig setMode(String mode) {
+ this.mode = mode;
+ return this;
+ }
+
+ @JsonProperty
+ public boolean needsCaching() {
+ return caching;
+ }
+
+ @JsonProperty
+ public AuthenticationConfig setCaching(boolean caching) {
+ this.caching = caching;
+ return this;
+ }
+
+ @JsonProperty
+ public String getCachePolicy() {
+ return cachePolicy;
+ }
+
+ @JsonProperty
+ public AuthenticationConfig setCachePolicy(String cachePolicy) {
+ this.cachePolicy = cachePolicy;
+ return this;
+ }
+
+ @JsonProperty("ldap")
+ public LdapConfig getLdap() {
+ return ldap;
+ }
+
+ @JsonProperty("ldap")
+ public AuthenticationConfig setLdap(LdapConfig ldap) {
+ this.ldap = ldap;
+ return this;
+ }
+
+ @JsonProperty("simple")
+ public SimpleConfig getSimple() {
+ return simple;
+ }
+
+ @JsonProperty("simple")
+ public AuthenticationConfig setSimple(SimpleConfig simple) {
+ this.simple = simple;
+ return this;
+ }
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/security/config/LdapConfig.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/security/config/LdapConfig.java b/eagle-server/src/main/java/org/apache/eagle/server/security/config/LdapConfig.java
new file mode 100644
index 0000000..c87553f
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/security/config/LdapConfig.java
@@ -0,0 +1,96 @@
+/*
+ * 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.eagle.server.security.config;
+
+import io.dropwizard.util.Duration;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class LdapConfig {
+
+ private String providerUrl = "";
+ private String strategy = "";
+ private String principalTemplate = "";
+ private String certificateAbsolutePath = "";
+ private Duration connectingTimeout = Duration.parse("500ms");
+ private Duration readingTimeout = Duration.parse("500ms");
+
+ @JsonProperty
+ public String getProviderUrl() {
+ return providerUrl;
+ }
+
+ @JsonProperty
+ public LdapConfig setProviderUrl(String providerUrl) {
+ this.providerUrl = providerUrl;
+ return this;
+ }
+
+ @JsonProperty
+ public String getPrincipalTemplate() {
+ return principalTemplate;
+ }
+
+ @JsonProperty
+ public LdapConfig setPrincipalTemplate(String principalTemplate) {
+ this.principalTemplate = principalTemplate;
+ return this;
+ }
+
+ @JsonProperty
+ public String getStrategy() {
+ return strategy;
+ }
+
+ @JsonProperty
+ public LdapConfig setStrategy(String strategy) {
+ this.strategy = strategy;
+ return this;
+ }
+
+ @JsonProperty
+ public Duration getConnectingTimeout() {
+ return connectingTimeout;
+ }
+
+ @JsonProperty
+ public LdapConfig setConnectingTimeout(Duration connectingTimeout) {
+ this.connectingTimeout = connectingTimeout;
+ return this;
+ }
+
+ @JsonProperty
+ public Duration getReadingTimeout() {
+ return readingTimeout;
+ }
+
+ @JsonProperty
+ public LdapConfig setReadingTimeout(Duration readingTimeout) {
+ this.readingTimeout = readingTimeout;
+ return this;
+ }
+
+ @JsonProperty
+ public String getCertificateAbsolutePath() {
+ return certificateAbsolutePath;
+ }
+
+ @JsonProperty
+ public LdapConfig setCertificateAbsolutePath(String certificateAbsolutePath) {
+ this.certificateAbsolutePath = certificateAbsolutePath;
+ return this;
+ }
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/security/config/SimpleConfig.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/security/config/SimpleConfig.java b/eagle-server/src/main/java/org/apache/eagle/server/security/config/SimpleConfig.java
new file mode 100644
index 0000000..65ae10f
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/security/config/SimpleConfig.java
@@ -0,0 +1,34 @@
+/*
+ * 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.eagle.server.security.config;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.List;
+
+public class SimpleConfig {
+ private List<UserAccount> accounts;
+
+ @JsonProperty("accounts")
+ public List<UserAccount> getAccounts() {
+ return accounts;
+ }
+
+ public void setAccounts(List<UserAccount> accounts) {
+ this.accounts = accounts;
+ }
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/security/config/UserAccount.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/security/config/UserAccount.java b/eagle-server/src/main/java/org/apache/eagle/server/security/config/UserAccount.java
new file mode 100644
index 0000000..882e797
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/security/config/UserAccount.java
@@ -0,0 +1,55 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.eagle.server.security.config;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Preconditions;
+import org.apache.eagle.common.security.User;
+
+import java.util.*;
+
+public class UserAccount extends User {
+
+ @JsonProperty("password")
+ public String getEncryptedPassword() {
+ return encryptedPassword;
+ }
+
+ private String encryptedPassword;
+
+ public UserAccount() {
+
+ }
+
+ public UserAccount(String username, String encryptedPassword) {
+ this.setName(username);
+ this.encryptedPassword = encryptedPassword;
+ }
+
+ public void setRoles(String roles) {
+ if (roles != null) {
+ String[] roleStrArray = roles.split(",");
+ Set<User.Role> rolesSet = new HashSet<>();
+ for (String roleStr:roleStrArray) {
+ User.Role role = User.Role.locateCaseInsensitive(roleStr.trim());
+ Preconditions.checkNotNull(role, "Invalid role " + roleStr);
+ rolesSet.add(role);
+ }
+ super.setRoles(rolesSet);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/security/encrypt/EncryptorFactory.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/security/encrypt/EncryptorFactory.java b/eagle-server/src/main/java/org/apache/eagle/server/security/encrypt/EncryptorFactory.java
new file mode 100644
index 0000000..ff90213
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/security/encrypt/EncryptorFactory.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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.eagle.server.security.encrypt;
+
+public class EncryptorFactory {
+ public static PasswordEncryptor getPasswordEncryptor() {
+ return new PasswordEncryptorImpl();
+ }
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/security/encrypt/PasswordEncryptor.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/security/encrypt/PasswordEncryptor.java b/eagle-server/src/main/java/org/apache/eagle/server/security/encrypt/PasswordEncryptor.java
new file mode 100644
index 0000000..acf679e
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/security/encrypt/PasswordEncryptor.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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.eagle.server.security.encrypt;
+
+public interface PasswordEncryptor {
+ String encryptPassword(String password);
+
+ boolean checkPassword(String password, String encryptedPassword);
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/security/encrypt/PasswordEncryptorImpl.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/security/encrypt/PasswordEncryptorImpl.java b/eagle-server/src/main/java/org/apache/eagle/server/security/encrypt/PasswordEncryptorImpl.java
new file mode 100644
index 0000000..2c93c3c
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/security/encrypt/PasswordEncryptorImpl.java
@@ -0,0 +1,37 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.eagle.server.security.encrypt;
+
+import org.jasypt.util.password.StrongPasswordEncryptor;
+
+class PasswordEncryptorImpl implements PasswordEncryptor {
+ private final StrongPasswordEncryptor encryptor;
+
+ PasswordEncryptorImpl() {
+ this.encryptor = new StrongPasswordEncryptor();
+ }
+
+ @Override
+ public String encryptPassword(String password) {
+ return this.encryptor.encryptPassword(password);
+ }
+
+ @Override
+ public boolean checkPassword(String password, String encryptedPassword) {
+ return this.encryptor.checkPassword(password, encryptedPassword);
+ }
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/tool/EncryptTool.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/tool/EncryptTool.java b/eagle-server/src/main/java/org/apache/eagle/server/tool/EncryptTool.java
new file mode 100644
index 0000000..f77d90d
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/tool/EncryptTool.java
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.eagle.server.tool;
+
+import org.apache.eagle.server.ServerMain;
+import org.apache.eagle.server.security.encrypt.EncryptorFactory;
+import org.apache.eagle.server.security.encrypt.PasswordEncryptor;
+
+public class EncryptTool implements Tool {
+
+ private static final String MISSING_TEXT =
+ "Error: require text to encrypt\n"
+ + "Usage: java " + ServerMain.class.getName() + " encrypt [text to encrypt]";
+
+ @Override
+ public void execute(String[] args) {
+ if (args.length < 2) {
+ System.err.println(MISSING_TEXT);
+ } else {
+ String textToEncrypt = args[1];
+ PasswordEncryptor encryptor = EncryptorFactory.getPasswordEncryptor();
+ String encryptedText = encryptor.encryptPassword(textToEncrypt);
+ System.out.println("Original: " + textToEncrypt);
+ System.out.println("Encrypted: " + encryptedText);
+ System.exit(0);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/tool/Tool.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/tool/Tool.java b/eagle-server/src/main/java/org/apache/eagle/server/tool/Tool.java
new file mode 100644
index 0000000..bb5632a
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/tool/Tool.java
@@ -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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.eagle.server.tool;
+
+public interface Tool {
+ public void execute(String[] args);
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/resources/configuration.yml
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/resources/configuration.yml b/eagle-server/src/main/resources/configuration.yml
index eabb8a1..a208f57 100644
--- a/eagle-server/src/main/resources/configuration.yml
+++ b/eagle-server/src/main/resources/configuration.yml
@@ -1,77 +1,74 @@
-# 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.
-
-server:
- applicationConnectors:
- - type: http
- port: 9090
- adminConnectors:
- - type: http
- port: 9091
-
-# ---------------------------------------------
-# Eagle Authentication Configuration
-# ---------------------------------------------
-auth:
- # indicating if authentication is enabled, true for enabled, false for disabled
- enabled: false
-
- # indicating authentication mode, "simple" or "ldap"
- mode: simple
-
- # indicating whether to use cache: cache is usually used for authentications that may
- # not handle high throughput (an RDBMS or LDAP server, for example)
- caching: false
-
- # indicating the cache policy, containing maximumSize and expireAfterWrite, e.g. maximumSize=10000, expireAfterWrite=10m
- cachePolicy: maximumSize=10000, expireAfterWrite=1m
-
- # indicating whether authorization is needed
- authorization: false
-
- # indicating whether @Auth annotation on parameters is needed
- annotated: true
-
- # for basic authentication, effective only when auth.mode=simple
- simple:
- # username for basic authentication, effective only when auth.mode=simple
- username: admin
- # password for basic authentication, effective only when auth.mode=simple
- password: secret
-
- # for ldap authentication, effective only when auth.mode=ldap
- ldap:
- # url providing ldap service. By convention, the port for typical ldap service is 389, and ldap service over ssl
- # uses port 636 with protocol "ldaps", which requires certificates pre-installed.
- providerUrl: ldap://server.address.or.domain:port
-
- # template string containing ${USERNAME} placeholder. This is designed for some orgs who don't use plain usernames
- # to authenticate, e.g. they may use its members' email address as the username: ${USERNAME}@some.org. When username
- # is supposed to be recognized originally, just configure this parameter as ${USERNAME}
- principalTemplate: ${USERNAME}@maybe.email.suffix
-
- # string of strategy used by ldap service. "simple" is usually supported in most circumstances, we can use it by
- # default or leave it a blank string.
- strategy: simple
-
- # the absolute path of ssl certificate file. This attribute is required conditional only when the auth -> mode is set
- # as "ldap" and providerUrl starting with "ldaps://".
- certificateAbsolutePath: /certificate/absolute/path
-
- # timeout expression for connecting to ldap service endpoint
- connectingTimeout: 500ms
-
- # timeout expression for reading from ldap service
- readingTimeout: 500ms
+# 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.
+
+server:
+ applicationConnectors:
+ - type: http
+ port: 9090
+ adminConnectors:
+ - type: http
+ port: 9091
+
+# ---------------------------------------------
+# Eagle Authentication Configuration
+# ---------------------------------------------
+auth:
+ # indicating if authentication is enabled, true for enabled, false for disabled
+ enabled: false
+
+ # indicating authentication mode, "simple" or "ldap"
+ mode: simple
+
+ # indicating whether to use cache: cache is usually used for authentications that may
+ # not handle high throughput (an RDBMS or LDAP server, for example)
+ caching: false
+
+ # indicating the cache policy, containing maximumSize and expireAfterWrite, e.g. maximumSize=10000, expireAfterWrite=10m
+ cachePolicy: maximumSize=10000, expireAfterWrite=1m
+
+ # for basic authentication, effective only when auth.mode=simple
+ simple:
+ accounts:
+ - name: admin
+ password: rWV/cdTCr01wTLBQ/rUilkExd2TJKrifXuCCTEwig1o08K8Mi0b1qQAgVXpPqflb
+ roles: ADMINISTRATOR
+ firstName: Admin
+ lastName: Admin
+ email: unknown-admin@eagle.apache.org
+
+ # for ldap authentication, effective only when auth.mode=ldap
+ ldap:
+ # url providing ldap service. By convention, the port for typical ldap service is 389, and ldap service over ssl
+ # uses port 636 with protocol "ldaps", which requires certificates pre-installed.
+ providerUrl: ldap://server.address.or.domain:port
+
+ # template string containing ${USERNAME} placeholder. This is designed for some orgs who don't use plain usernames
+ # to authenticate, e.g. they may use its members' email address as the name: ${USERNAME}@some.org. When name
+ # is supposed to be recognized originally, just configure this parameter as ${USERNAME}
+ principalTemplate: ${USERNAME}@maybe.email.suffix
+
+ # string of strategy used by ldap service. "simple" is usually supported in most circumstances, we can use it by
+ # default or leave it a blank string.
+ strategy: simple
+
+ # the absolute path of ssl certificate file. This attribute is required conditional only when the auth -> mode is set
+ # as "ldap" and providerUrl starting with "ldaps://".
+ certificateAbsolutePath: /certificate/absolute/path
+
+ # timeout expression for connecting to ldap service endpoint
+ connectingTimeout: 500ms
+
+ # timeout expression for reading from ldap service
+ readingTimeout: 500ms
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/test/java/org/apache/eagle/server/ServerApplicationTest.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/test/java/org/apache/eagle/server/ServerApplicationTest.java b/eagle-server/src/test/java/org/apache/eagle/server/ServerApplicationTest.java
deleted file mode 100644
index 6b299e5..0000000
--- a/eagle-server/src/test/java/org/apache/eagle/server/ServerApplicationTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.eagle.server;
-
-import org.junit.Test;
-
-public class ServerApplicationTest {
- @Test
- public void testServerMain() throws Exception {
- ServerMain.main(new String[] {"server", "src/test/resources/configuration.yml"});
- }
-}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/test/java/org/apache/eagle/server/ServerDebug.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/test/java/org/apache/eagle/server/ServerDebug.java b/eagle-server/src/test/java/org/apache/eagle/server/ServerDebug.java
index f47f2bf..3225435 100644
--- a/eagle-server/src/test/java/org/apache/eagle/server/ServerDebug.java
+++ b/eagle-server/src/test/java/org/apache/eagle/server/ServerDebug.java
@@ -16,9 +16,11 @@
*/
package org.apache.eagle.server;
+import org.junit.Ignore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+@Ignore
public class ServerDebug {
private static final Logger LOGGER = LoggerFactory.getLogger(ServerDebug.class);
private static String serverConf = null;
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/test/java/org/apache/eagle/server/authentication/authenticator/LdapBasicAuthenticatorTest.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/test/java/org/apache/eagle/server/authentication/authenticator/LdapBasicAuthenticatorTest.java b/eagle-server/src/test/java/org/apache/eagle/server/authentication/authenticator/LdapBasicAuthenticatorTest.java
deleted file mode 100644
index 8700a75..0000000
--- a/eagle-server/src/test/java/org/apache/eagle/server/authentication/authenticator/LdapBasicAuthenticatorTest.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.eagle.server.authentication.authenticator;
-
-import io.dropwizard.util.Duration;
-import org.apache.eagle.server.authentication.config.LdapSettings;
-import org.junit.Assert;
-import org.junit.Test;
-
-import javax.naming.Context;
-import java.util.Hashtable;
-
-public class LdapBasicAuthenticatorTest {
-
- private static final String USERNAME_SUFFIX = "@some.emailbox.suffix";
- private static final String USERNAME_TEMPLATE = "${USERNAME}" + USERNAME_SUFFIX;
- private static final String LDAP_SERVICE_PROVIDER_URL = "ldap://some.address:port";
- private static final String LDAP_SERVICE_PROVIDER_SSL_URL = "ldaps://some.address:port";
- private static final String STRATEGY_SIMPLE = "customized";
- private static final String CONNECTING_TIMEOUT_VALUE = "500ms";
- private static final String READING_TIMEOUT_VALUE = "800ms";
- private static final String LDAP_CTX_FACTORY_NAME = "com.sun.jndi.ldap.LdapCtxFactory";
- private static final String LDAP_CONNECT_TIMEOUT_KEY = "com.sun.jndi.ldap.connect.timeout";
- private static final String LDAP_READ_TIMEOUT_KEY = "com.sun.jndi.ldap.read.timeout";
- private static final String SYS_PROP_SSL_KEY_STORE = "javax.net.ssl.keyStore";
- private static final String SYS_PROP_SSL_TRUST_STORE = "javax.net.ssl.trustStore";
- private static final String EXISTING_MOCK_FILE_PATH = String.format("%s/pom.xml", System.getProperty("user.dir"));
- private static final LdapBasicAuthenticator AUTHENTICATOR_FOR_UTIL_METHODS_WITHOUT_SSL = new LdapBasicAuthenticator(
- getNonSSLPreSettings().setPrincipalTemplate(USERNAME_TEMPLATE)
- .setStrategy(STRATEGY_SIMPLE)
- .setConnectingTimeout(Duration.parse(CONNECTING_TIMEOUT_VALUE))
- .setReadingTimeout(Duration.parse(READING_TIMEOUT_VALUE))
- );
- private static final LdapBasicAuthenticator AUTHENTICATOR_FOR_UTIL_METHODS_WITH_SSL = new LdapBasicAuthenticator(
- getSSLPreSettings().setPrincipalTemplate(USERNAME_TEMPLATE)
- .setStrategy(STRATEGY_SIMPLE)
- .setCertificateAbsolutePath(EXISTING_MOCK_FILE_PATH)
- .setConnectingTimeout(Duration.parse(CONNECTING_TIMEOUT_VALUE))
- .setReadingTimeout(Duration.parse(READING_TIMEOUT_VALUE))
- );
-
- @Test
- public void testSanitizeUsername() {
- String correctUsername = "userNAME_123.45Z";
- String sanitized = AUTHENTICATOR_FOR_UTIL_METHODS_WITHOUT_SSL.sanitizeUsername(correctUsername);
- Assert.assertEquals(correctUsername, sanitized);
-
- String incorrectUsername = "userNAME-~!@#$%^&777*()_+-=`[]\\{}|;':\",./<>?\u4f60";
- sanitized = AUTHENTICATOR_FOR_UTIL_METHODS_WITHOUT_SSL.sanitizeUsername(incorrectUsername);
- System.out.println(sanitized);
- Assert.assertEquals("userNAME777_.", sanitized);
- }
-
- @Test
- public void testComprisePrincipal() {
- String username = "my.userNAME_123";
- String principal = AUTHENTICATOR_FOR_UTIL_METHODS_WITHOUT_SSL.comprisePrincipal(username);
- Assert.assertEquals(username+USERNAME_SUFFIX, principal);
- }
-
- @Test
- public void testGetContextEnvironmentNormal() {
- String username = "username";
- String secretPhrase = "secret-phrase";
- Hashtable<String, String> env = AUTHENTICATOR_FOR_UTIL_METHODS_WITHOUT_SSL.getContextEnvironment(username, secretPhrase);
-
- Assert.assertEquals("unexpected ldap context factory name", LDAP_CTX_FACTORY_NAME, env.get(Context.INITIAL_CONTEXT_FACTORY));
- Assert.assertEquals("unexpected ldap service provider url", LDAP_SERVICE_PROVIDER_URL, env.get(Context.PROVIDER_URL));
- Assert.assertEquals("unexpected connecting timeout value", String.valueOf(Duration.parse(CONNECTING_TIMEOUT_VALUE).toMilliseconds()), env.get(LDAP_CONNECT_TIMEOUT_KEY));
- Assert.assertEquals("unexpected reading timeout value", String.valueOf(Duration.parse(READING_TIMEOUT_VALUE).toMilliseconds()), env.get(LDAP_READ_TIMEOUT_KEY));
- Assert.assertEquals("unexpected username", username+USERNAME_SUFFIX, env.get(Context.SECURITY_PRINCIPAL));
- Assert.assertEquals("unexpected secret credentials", secretPhrase, env.get(Context.SECURITY_CREDENTIALS));
- Assert.assertEquals("unexpected strategy", STRATEGY_SIMPLE, env.get(Context.SECURITY_AUTHENTICATION));
- }
-
- @Test
- public void testGetContextEnvironmentBlankStrategy() {
- String username = "username";
- String secretPhrase = "secret-phrase";
-
- // check strategy while it's configured as ""
- LdapBasicAuthenticator blankStrategyAuthenticator = new LdapBasicAuthenticator(getNonSSLPreSettings().setStrategy(""));
- String strategyMaybeBlank = blankStrategyAuthenticator.getContextEnvironment(username, secretPhrase).get(Context.SECURITY_AUTHENTICATION);
- Assert.assertNull("unexpected strategy", strategyMaybeBlank);
- }
-
- @Test
- public void testGetContextEnvironmentNormalWithSSL() {
- String username = "username";
- String secretPhrase = "secret-phrase";
- Hashtable<String, String> env = AUTHENTICATOR_FOR_UTIL_METHODS_WITH_SSL.getContextEnvironment(username, secretPhrase);
-
- Assert.assertEquals("unexpected ldap context factory name", LDAP_CTX_FACTORY_NAME, env.get(Context.INITIAL_CONTEXT_FACTORY));
- Assert.assertEquals("unexpected ldap service provider url", LDAP_SERVICE_PROVIDER_SSL_URL, env.get(Context.PROVIDER_URL));
- Assert.assertEquals("unexpected connecting timeout value", String.valueOf(Duration.parse(CONNECTING_TIMEOUT_VALUE).toMilliseconds()), env.get(LDAP_CONNECT_TIMEOUT_KEY));
- Assert.assertEquals("unexpected reading timeout value", String.valueOf(Duration.parse(READING_TIMEOUT_VALUE).toMilliseconds()), env.get(LDAP_READ_TIMEOUT_KEY));
- Assert.assertEquals("unexpected username", username+USERNAME_SUFFIX, env.get(Context.SECURITY_PRINCIPAL));
- Assert.assertEquals("unexpected secret credentials", secretPhrase, env.get(Context.SECURITY_CREDENTIALS));
- Assert.assertEquals("unexpected strategy", STRATEGY_SIMPLE, env.get(Context.SECURITY_AUTHENTICATION));
- Assert.assertEquals("unexpected key-store path", EXISTING_MOCK_FILE_PATH, System.getProperty(SYS_PROP_SSL_KEY_STORE));
- Assert.assertEquals("unexpected trust-store path", EXISTING_MOCK_FILE_PATH, System.getProperty(SYS_PROP_SSL_TRUST_STORE));
- }
-
- @Test
- public void testGetContextEnvironmentMeaninglessCAPathSSL() {
- String username = "username";
- String secretPhrase = "secret-phrase";
-
- // check null certificateAbsolutePath
- try {
- LdapBasicAuthenticator blankStrategyAuthenticator = new LdapBasicAuthenticator(getSSLPreSettings().setCertificateAbsolutePath(null));
- blankStrategyAuthenticator.getContextEnvironment(username, secretPhrase).get(Context.SECURITY_AUTHENTICATION);
- }
- catch (Exception e) {
- Assert.assertEquals("unexpected exception thrown", RuntimeException.class, e.getClass());
- Assert.assertEquals("unexpected exception message", "The attribute 'certificateAbsolutePath' must be set when using ldap over ssl to authenticate.", e.getMessage());
- }
-
- // check "" certificateAbsolutePath
- try {
- LdapBasicAuthenticator blankStrategyAuthenticator = new LdapBasicAuthenticator(getSSLPreSettings().setCertificateAbsolutePath(""));
- blankStrategyAuthenticator.getContextEnvironment(username, secretPhrase).get(Context.SECURITY_AUTHENTICATION);
- }
- catch (Exception e) {
- Assert.assertEquals("unexpected exception thrown", RuntimeException.class, e.getClass());
- Assert.assertEquals("unexpected exception message", "The attribute 'certificateAbsolutePath' must be set when using ldap over ssl to authenticate.", e.getMessage());
- }
- }
-
- @Test
- public void testGetContextEnvironmentUnexistingCA_SSL() {
- String username = "username";
- String secretPhrase = "secret-phrase";
- String wrongCAPath = String.format("%s/this/cannot/be/existing", System.getProperty("user.dir"));
- try {
- // check with not existing path indicated by certificateAbsolutePath
- LdapBasicAuthenticator blankStrategyAuthenticator = new LdapBasicAuthenticator(getSSLPreSettings().setCertificateAbsolutePath(wrongCAPath));
- blankStrategyAuthenticator.getContextEnvironment(username, secretPhrase).get(Context.SECURITY_AUTHENTICATION);
- }
- catch (Exception e) {
- Assert.assertEquals("unexpected exception thrown", RuntimeException.class, e.getClass());
- Assert.assertEquals("unexpected exception message", String.format("The file specified not existing: %s", wrongCAPath), e.getMessage());
- }
- }
-
- private static LdapSettings getNonSSLPreSettings() {
- return new LdapSettings().setProviderUrl(LDAP_SERVICE_PROVIDER_URL);
- }
-
- private static LdapSettings getSSLPreSettings() {
- return new LdapSettings().setProviderUrl(LDAP_SERVICE_PROVIDER_SSL_URL);
- }
-}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/test/java/org/apache/eagle/server/authentication/authenticator/SimpleBasicAuthenticatorTest.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/test/java/org/apache/eagle/server/authentication/authenticator/SimpleBasicAuthenticatorTest.java b/eagle-server/src/test/java/org/apache/eagle/server/authentication/authenticator/SimpleBasicAuthenticatorTest.java
deleted file mode 100644
index e896a7c..0000000
--- a/eagle-server/src/test/java/org/apache/eagle/server/authentication/authenticator/SimpleBasicAuthenticatorTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.eagle.server.authentication.authenticator;
-
-import com.google.common.base.Optional;
-import io.dropwizard.auth.AuthenticationException;
-import io.dropwizard.auth.basic.BasicCredentials;
-import org.apache.eagle.common.authentication.User;
-import org.apache.eagle.server.authentication.config.SimpleSettings;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SimpleBasicAuthenticatorTest {
-
- private static final String TEST_USERNAME = "normal-username";
- private static final String TEST_SECRET_PHRASE = "secret-phrase";
- private static final String TEST_UNEXISTING_USERNAME = "unexisting-username";
- private static final String TEST_WRONG_SECRET_PHRASE = "wrong-secret-phrase";
- private static SimpleBasicAuthenticator authenticator = new SimpleBasicAuthenticator(new SimpleSettings().setUsername(TEST_USERNAME).setPassword(TEST_SECRET_PHRASE));
-
- @Test
- public void testNormal() {
- try {
- BasicCredentials credentials = new BasicCredentials(TEST_USERNAME, TEST_SECRET_PHRASE);
- Optional<User> result = authenticator.authenticate(credentials);
- Assert.assertTrue("result isn't present when passed correct credentials", result.isPresent());
- User user = result.get();
- Assert.assertEquals("authenticated user is not expected", TEST_USERNAME, user.getName());
- }
- catch (AuthenticationException e) {
- Assert.fail("unexpected error occurs: "+e.getMessage());
- }
- }
-
- @Test
- public void testUnexistingUsername() {
- try {
- Optional<User> result = authenticator.authenticate(new BasicCredentials(TEST_UNEXISTING_USERNAME, TEST_SECRET_PHRASE));
- Assert.assertFalse("result is present when passed unexisting username", result.isPresent());
- }
- catch (AuthenticationException e) {
- Assert.fail("unexpected error occurs: "+e.getMessage());
- }
- }
-
- @Test
- public void testWrongPassword() {
- try {
- Optional<User> result = authenticator.authenticate(new BasicCredentials(TEST_USERNAME, TEST_WRONG_SECRET_PHRASE));
- Assert.assertFalse("result is present when passed wrong password", result.isPresent());
- }
- catch (AuthenticationException e) {
- Assert.fail("unexpected error occurs: "+e.getMessage());
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/test/java/org/apache/eagle/server/authentication/resource/TestBasicAuthenticationResource.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/test/java/org/apache/eagle/server/authentication/resource/TestBasicAuthenticationResource.java b/eagle-server/src/test/java/org/apache/eagle/server/authentication/resource/TestBasicAuthenticationResource.java
deleted file mode 100644
index 0ea6666..0000000
--- a/eagle-server/src/test/java/org/apache/eagle/server/authentication/resource/TestBasicAuthenticationResource.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.eagle.server.authentication.resource;
-
-import io.dropwizard.auth.Auth;
-import org.apache.eagle.common.authentication.User;
-import org.apache.eagle.metadata.resource.RESTResponse;
-import org.junit.Ignore;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-@Ignore
-@Path("/test")
-public class TestBasicAuthenticationResource {
- @GET
- @Path("/ba/simple")
- @Produces(MediaType.APPLICATION_JSON)
- public RESTResponse<User> getIt(@Auth User user) {
- return RESTResponse.<User>builder().data(user).success(true).status(Response.Status.OK).get();
- }
-}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/test/java/org/apache/eagle/server/security/authenticator/LdapBasicAuthenticatorTest.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/test/java/org/apache/eagle/server/security/authenticator/LdapBasicAuthenticatorTest.java b/eagle-server/src/test/java/org/apache/eagle/server/security/authenticator/LdapBasicAuthenticatorTest.java
new file mode 100644
index 0000000..8389da8
--- /dev/null
+++ b/eagle-server/src/test/java/org/apache/eagle/server/security/authenticator/LdapBasicAuthenticatorTest.java
@@ -0,0 +1,168 @@
+/*
+ * 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.eagle.server.security.authenticator;
+
+import io.dropwizard.util.Duration;
+import org.apache.eagle.server.security.config.LdapConfig;
+import org.junit.Assert;
+import org.junit.Test;
+
+import javax.naming.Context;
+import java.util.Hashtable;
+
+public class LdapBasicAuthenticatorTest {
+
+ private static final String USERNAME_SUFFIX = "@some.emailbox.suffix";
+ private static final String USERNAME_TEMPLATE = "${USERNAME}" + USERNAME_SUFFIX;
+ private static final String LDAP_SERVICE_PROVIDER_URL = "ldap://some.address:port";
+ private static final String LDAP_SERVICE_PROVIDER_SSL_URL = "ldaps://some.address:port";
+ private static final String STRATEGY_SIMPLE = "customized";
+ private static final String CONNECTING_TIMEOUT_VALUE = "500ms";
+ private static final String READING_TIMEOUT_VALUE = "800ms";
+ private static final String LDAP_CTX_FACTORY_NAME = "com.sun.jndi.ldap.LdapCtxFactory";
+ private static final String LDAP_CONNECT_TIMEOUT_KEY = "com.sun.jndi.ldap.connect.timeout";
+ private static final String LDAP_READ_TIMEOUT_KEY = "com.sun.jndi.ldap.read.timeout";
+ private static final String SYS_PROP_SSL_KEY_STORE = "javax.net.ssl.keyStore";
+ private static final String SYS_PROP_SSL_TRUST_STORE = "javax.net.ssl.trustStore";
+ private static final String EXISTING_MOCK_FILE_PATH = String.format("%s/pom.xml", System.getProperty("user.dir"));
+ private static final LdapBasicAuthenticator AUTHENTICATOR_FOR_UTIL_METHODS_WITHOUT_SSL = new LdapBasicAuthenticator(
+ getNonSSLPreSettings().setPrincipalTemplate(USERNAME_TEMPLATE)
+ .setStrategy(STRATEGY_SIMPLE)
+ .setConnectingTimeout(Duration.parse(CONNECTING_TIMEOUT_VALUE))
+ .setReadingTimeout(Duration.parse(READING_TIMEOUT_VALUE))
+ );
+ private static final LdapBasicAuthenticator AUTHENTICATOR_FOR_UTIL_METHODS_WITH_SSL = new LdapBasicAuthenticator(
+ getSSLPreSettings().setPrincipalTemplate(USERNAME_TEMPLATE)
+ .setStrategy(STRATEGY_SIMPLE)
+ .setCertificateAbsolutePath(EXISTING_MOCK_FILE_PATH)
+ .setConnectingTimeout(Duration.parse(CONNECTING_TIMEOUT_VALUE))
+ .setReadingTimeout(Duration.parse(READING_TIMEOUT_VALUE))
+ );
+
+ @Test
+ public void testSanitizeUsername() {
+ String correctUsername = "userNAME_123.45Z";
+ String sanitized = AUTHENTICATOR_FOR_UTIL_METHODS_WITHOUT_SSL.sanitizeUsername(correctUsername);
+ Assert.assertEquals(correctUsername, sanitized);
+
+ String incorrectUsername = "userNAME-~!@#$%^&777*()_+-=`[]\\{}|;':\",./<>?\u4f60";
+ sanitized = AUTHENTICATOR_FOR_UTIL_METHODS_WITHOUT_SSL.sanitizeUsername(incorrectUsername);
+ System.out.println(sanitized);
+ Assert.assertEquals("userNAME777_.", sanitized);
+ }
+
+ @Test
+ public void testComprisePrincipal() {
+ String username = "my.userNAME_123";
+ String principal = AUTHENTICATOR_FOR_UTIL_METHODS_WITHOUT_SSL.comprisePrincipal(username);
+ Assert.assertEquals(username+USERNAME_SUFFIX, principal);
+ }
+
+ @Test
+ public void testGetContextEnvironmentNormal() {
+ String username = "username";
+ String secretPhrase = "secret-phrase";
+ Hashtable<String, String> env = AUTHENTICATOR_FOR_UTIL_METHODS_WITHOUT_SSL.getContextEnvironment(username, secretPhrase);
+
+ Assert.assertEquals("unexpected ldap context factory name", LDAP_CTX_FACTORY_NAME, env.get(Context.INITIAL_CONTEXT_FACTORY));
+ Assert.assertEquals("unexpected ldap service provider url", LDAP_SERVICE_PROVIDER_URL, env.get(Context.PROVIDER_URL));
+ Assert.assertEquals("unexpected connecting timeout value", String.valueOf(Duration.parse(CONNECTING_TIMEOUT_VALUE).toMilliseconds()), env.get(LDAP_CONNECT_TIMEOUT_KEY));
+ Assert.assertEquals("unexpected reading timeout value", String.valueOf(Duration.parse(READING_TIMEOUT_VALUE).toMilliseconds()), env.get(LDAP_READ_TIMEOUT_KEY));
+ Assert.assertEquals("unexpected username", username+USERNAME_SUFFIX, env.get(Context.SECURITY_PRINCIPAL));
+ Assert.assertEquals("unexpected secret credentials", secretPhrase, env.get(Context.SECURITY_CREDENTIALS));
+ Assert.assertEquals("unexpected strategy", STRATEGY_SIMPLE, env.get(Context.SECURITY_AUTHENTICATION));
+ }
+
+ @Test
+ public void testGetContextEnvironmentBlankStrategy() {
+ String username = "username";
+ String secretPhrase = "secret-phrase";
+
+ // check strategy while it's configured as ""
+ LdapBasicAuthenticator blankStrategyAuthenticator = new LdapBasicAuthenticator(getNonSSLPreSettings().setStrategy(""));
+ String strategyMaybeBlank = blankStrategyAuthenticator.getContextEnvironment(username, secretPhrase).get(Context.SECURITY_AUTHENTICATION);
+ Assert.assertNull("unexpected strategy", strategyMaybeBlank);
+ }
+
+ @Test
+ public void testGetContextEnvironmentNormalWithSSL() {
+ String username = "username";
+ String secretPhrase = "secret-phrase";
+ Hashtable<String, String> env = AUTHENTICATOR_FOR_UTIL_METHODS_WITH_SSL.getContextEnvironment(username, secretPhrase);
+
+ Assert.assertEquals("unexpected ldap context factory name", LDAP_CTX_FACTORY_NAME, env.get(Context.INITIAL_CONTEXT_FACTORY));
+ Assert.assertEquals("unexpected ldap service provider url", LDAP_SERVICE_PROVIDER_SSL_URL, env.get(Context.PROVIDER_URL));
+ Assert.assertEquals("unexpected connecting timeout value", String.valueOf(Duration.parse(CONNECTING_TIMEOUT_VALUE).toMilliseconds()), env.get(LDAP_CONNECT_TIMEOUT_KEY));
+ Assert.assertEquals("unexpected reading timeout value", String.valueOf(Duration.parse(READING_TIMEOUT_VALUE).toMilliseconds()), env.get(LDAP_READ_TIMEOUT_KEY));
+ Assert.assertEquals("unexpected username", username+USERNAME_SUFFIX, env.get(Context.SECURITY_PRINCIPAL));
+ Assert.assertEquals("unexpected secret credentials", secretPhrase, env.get(Context.SECURITY_CREDENTIALS));
+ Assert.assertEquals("unexpected strategy", STRATEGY_SIMPLE, env.get(Context.SECURITY_AUTHENTICATION));
+ Assert.assertEquals("unexpected key-store path", EXISTING_MOCK_FILE_PATH, System.getProperty(SYS_PROP_SSL_KEY_STORE));
+ Assert.assertEquals("unexpected trust-store path", EXISTING_MOCK_FILE_PATH, System.getProperty(SYS_PROP_SSL_TRUST_STORE));
+ }
+
+ @Test
+ public void testGetContextEnvironmentMeaninglessCAPathSSL() {
+ String username = "username";
+ String secretPhrase = "secret-phrase";
+
+ // check null certificateAbsolutePath
+ try {
+ LdapBasicAuthenticator blankStrategyAuthenticator = new LdapBasicAuthenticator(getSSLPreSettings().setCertificateAbsolutePath(null));
+ blankStrategyAuthenticator.getContextEnvironment(username, secretPhrase).get(Context.SECURITY_AUTHENTICATION);
+ }
+ catch (Exception e) {
+ Assert.assertEquals("unexpected exception thrown", RuntimeException.class, e.getClass());
+ Assert.assertEquals("unexpected exception message", "The attribute 'certificateAbsolutePath' must be set when using ldap over ssl to authenticate.", e.getMessage());
+ }
+
+ // check "" certificateAbsolutePath
+ try {
+ LdapBasicAuthenticator blankStrategyAuthenticator = new LdapBasicAuthenticator(getSSLPreSettings().setCertificateAbsolutePath(""));
+ blankStrategyAuthenticator.getContextEnvironment(username, secretPhrase).get(Context.SECURITY_AUTHENTICATION);
+ }
+ catch (Exception e) {
+ Assert.assertEquals("unexpected exception thrown", RuntimeException.class, e.getClass());
+ Assert.assertEquals("unexpected exception message", "The attribute 'certificateAbsolutePath' must be set when using ldap over ssl to authenticate.", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testGetContextEnvironmentUnexistingCA_SSL() {
+ String username = "username";
+ String secretPhrase = "secret-phrase";
+ String wrongCAPath = String.format("%s/this/cannot/be/existing", System.getProperty("user.dir"));
+ try {
+ // check with not existing path indicated by certificateAbsolutePath
+ LdapBasicAuthenticator blankStrategyAuthenticator = new LdapBasicAuthenticator(getSSLPreSettings().setCertificateAbsolutePath(wrongCAPath));
+ blankStrategyAuthenticator.getContextEnvironment(username, secretPhrase).get(Context.SECURITY_AUTHENTICATION);
+ }
+ catch (Exception e) {
+ Assert.assertEquals("unexpected exception thrown", RuntimeException.class, e.getClass());
+ Assert.assertEquals("unexpected exception message", String.format("The file specified not existing: %s", wrongCAPath), e.getMessage());
+ }
+ }
+
+ private static LdapConfig getNonSSLPreSettings() {
+ return new LdapConfig().setProviderUrl(LDAP_SERVICE_PROVIDER_URL);
+ }
+
+ private static LdapConfig getSSLPreSettings() {
+ return new LdapConfig().setProviderUrl(LDAP_SERVICE_PROVIDER_SSL_URL);
+ }
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/test/java/org/apache/eagle/server/security/authenticator/SimpleBasicAuthenticatorTest.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/test/java/org/apache/eagle/server/security/authenticator/SimpleBasicAuthenticatorTest.java b/eagle-server/src/test/java/org/apache/eagle/server/security/authenticator/SimpleBasicAuthenticatorTest.java
new file mode 100644
index 0000000..8c638c5
--- /dev/null
+++ b/eagle-server/src/test/java/org/apache/eagle/server/security/authenticator/SimpleBasicAuthenticatorTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.eagle.server.security.authenticator;
+
+import com.google.common.base.Optional;
+import io.dropwizard.auth.AuthenticationException;
+import io.dropwizard.auth.basic.BasicCredentials;
+import org.apache.eagle.common.security.User;
+import org.apache.eagle.server.security.config.SimpleConfig;
+import org.apache.eagle.server.security.config.UserAccount;
+import org.apache.eagle.server.security.encrypt.EncryptorFactory;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Collections;
+
+public class SimpleBasicAuthenticatorTest {
+
+ private static final String TEST_USERNAME = "normal-username";
+ private static final String TEST_SECRET_PHRASE = "secret-phrase";
+ private static final String TEST_UNEXISTING_USERNAME = "unexisting-username";
+ private static final String TEST_WRONG_SECRET_PHRASE = "wrong-secret-phrase";
+
+ private static SimpleConfig config = new SimpleConfig();
+
+ static {
+ config.setAccounts(Collections.singletonList(new UserAccount(TEST_USERNAME,
+ EncryptorFactory.getPasswordEncryptor().encryptPassword(TEST_SECRET_PHRASE))));
+ }
+
+ private static SimpleBasicAuthenticator authenticator = new SimpleBasicAuthenticator(config);
+
+ @Test
+ public void testNormal() {
+ try {
+ BasicCredentials credentials = new BasicCredentials(TEST_USERNAME, TEST_SECRET_PHRASE);
+ Optional<User> result = authenticator.authenticate(credentials);
+ Assert.assertTrue("result isn't present when passed correct credentials", result.isPresent());
+ User user = result.get();
+ Assert.assertEquals("authenticated user is not expected", TEST_USERNAME, user.getName());
+ } catch (AuthenticationException e) {
+ Assert.fail("unexpected error occurs: " + e.getMessage());
+ }
+ }
+
+ @Test
+ public void testUnexistingUsername() {
+ try {
+ Optional<User> result = authenticator.authenticate(new BasicCredentials(TEST_UNEXISTING_USERNAME, TEST_SECRET_PHRASE));
+ Assert.assertFalse("result is present when passed unexisting username", result.isPresent());
+ } catch (AuthenticationException e) {
+ Assert.fail("unexpected error occurs: " + e.getMessage());
+ }
+ }
+
+
+ @Test
+ public void testWrongPassword() {
+ try {
+ Optional<User> result = authenticator.authenticate(new BasicCredentials(TEST_USERNAME, TEST_WRONG_SECRET_PHRASE));
+ Assert.assertFalse("result is present when passed wrong password", result.isPresent());
+ } catch (AuthenticationException e) {
+ Assert.fail("unexpected error occurs: " + e.getMessage());
+ }
+ }
+}
[3/3] eagle git commit: [EAGLE-918] Support auth annotations
PermitAll/DenyAll/RolesAllowed and API
Posted by ha...@apache.org.
[EAGLE-918] Support auth annotations PermitAll/DenyAll/RolesAllowed and API
* Improve eagle auth framework to support annotations under Jersey 1.9 and Dropwizard 0.7.1
PermitAll
DenyAll
RolesAllowed
Auth
* Add Authentication API
GET /auth/principal
GET /auth/validate
GET /auth/login
* Add password encryption and EncrytTool
java ServerMain encrypt [text to encrypt]
Author: Hao Chen <ha...@apache.org>
Closes #831 from haoch/EnableAuthAPI.
Project: http://git-wip-us.apache.org/repos/asf/eagle/repo
Commit: http://git-wip-us.apache.org/repos/asf/eagle/commit/94b597b7
Tree: http://git-wip-us.apache.org/repos/asf/eagle/tree/94b597b7
Diff: http://git-wip-us.apache.org/repos/asf/eagle/diff/94b597b7
Branch: refs/heads/master
Commit: 94b597b774464d33c30b290538a4231075a363e1
Parents: a7df69e
Author: Hao Chen <ha...@apache.org>
Authored: Wed Feb 22 16:12:10 2017 +0800
Committer: Hao Chen <ha...@apache.org>
Committed: Wed Feb 22 16:12:10 2017 +0800
----------------------------------------------------------------------
.../eagle/app/resource/ApplicationResource.java | 2 +-
.../eagle/common/authentication/User.java | 46 ----
.../apache/eagle/common/rest/RESTResponse.java | 255 +++++++++++++++++++
.../apache/eagle/common/security/DenyAll.java | 27 ++
.../apache/eagle/common/security/PermitAll.java | 29 +++
.../eagle/common/security/RolesAllowed.java | 26 ++
.../org/apache/eagle/common/security/User.java | 176 +++++++++++++
.../apache/eagle/common/service/HadoopUser.java | 2 +-
.../eagle-metadata/eagle-metadata-base/pom.xml | 4 +
.../eagle/metadata/resource/RESTResponse.java | 246 ------------------
.../eagle/metadata/resource/SiteResource.java | 1 +
.../entity/meta/EntityDefinitionManager.java | 2 +-
.../storage/hbase/TestWithHBaseCoprocessor.java | 24 +-
.../jpm/analyzer/resource/AnalyzerResource.java | 2 +-
.../apache/eagle/jpm/analyzer/util/Utils.java | 2 +-
.../history/crawl/JHFSparkEventReader.java | 2 +-
.../app/apps/jpm/partials/queue/overview.html | 2 +-
.../entity/HdfsUserCommandPatternEntity.java | 2 +-
.../eagle/security/hive/ql/TestParser.java | 2 +-
eagle-server/pom.xml | 9 +
.../eagle/server/RESTExceptionMapper.java | 2 +-
.../apache/eagle/server/ServerApplication.java | 29 ++-
.../org/apache/eagle/server/ServerConfig.java | 8 +-
.../org/apache/eagle/server/ServerMain.java | 46 +++-
.../BasicAuthProviderBuilder.java | 82 ------
.../authenticator/LdapBasicAuthenticator.java | 106 --------
.../authenticator/SimpleBasicAuthenticator.java | 43 ----
.../config/AuthenticationSettings.java | 119 ---------
.../authentication/config/LdapSettings.java | 96 -------
.../authentication/config/SimpleSettings.java | 46 ----
.../server/resource/AuthenticationResource.java | 65 +++++
.../eagle/server/security/BasicAuthBuilder.java | 99 +++++++
.../server/security/BasicAuthRequestFilter.java | 161 ++++++++++++
.../BasicAuthResourceFilterFactory.java | 53 ++++
.../authenticator/LdapBasicAuthenticator.java | 106 ++++++++
.../authenticator/SimpleBasicAuthenticator.java | 59 +++++
.../security/config/AuthenticationConfig.java | 95 +++++++
.../server/security/config/LdapConfig.java | 96 +++++++
.../server/security/config/SimpleConfig.java | 34 +++
.../server/security/config/UserAccount.java | 55 ++++
.../security/encrypt/EncryptorFactory.java | 23 ++
.../security/encrypt/PasswordEncryptor.java | 23 ++
.../security/encrypt/PasswordEncryptorImpl.java | 37 +++
.../apache/eagle/server/tool/EncryptTool.java | 42 +++
.../java/org/apache/eagle/server/tool/Tool.java | 21 ++
.../src/main/resources/configuration.yml | 151 ++++++-----
.../eagle/server/ServerApplicationTest.java | 26 --
.../org/apache/eagle/server/ServerDebug.java | 2 +
.../LdapBasicAuthenticatorTest.java | 168 ------------
.../SimpleBasicAuthenticatorTest.java | 71 ------
.../TestBasicAuthenticationResource.java | 39 ---
.../LdapBasicAuthenticatorTest.java | 168 ++++++++++++
.../SimpleBasicAuthenticatorTest.java | 81 ++++++
.../resource/BasicAuthenticationTestCase.java | 164 ++++++++++++
.../TestBasicAuthenticationResource.java | 107 ++++++++
.../src/test/resources/configuration.yml | 34 ++-
pom.xml | 11 +
57 files changed, 2215 insertions(+), 1214 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/resource/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/resource/ApplicationResource.java b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/resource/ApplicationResource.java
index f304768..3c62367 100644
--- a/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/resource/ApplicationResource.java
+++ b/eagle-core/eagle-app/eagle-app-base/src/main/java/org/apache/eagle/app/resource/ApplicationResource.java
@@ -19,9 +19,9 @@ package org.apache.eagle.app.resource;
import org.apache.eagle.app.service.ApplicationManagementService;
import org.apache.eagle.app.service.ApplicationOperations;
import org.apache.eagle.app.service.ApplicationProviderService;
+import org.apache.eagle.common.rest.RESTResponse;
import org.apache.eagle.metadata.model.ApplicationDesc;
import org.apache.eagle.metadata.model.ApplicationEntity;
-import org.apache.eagle.metadata.resource.RESTResponse;
import org.apache.eagle.metadata.service.ApplicationEntityService;
import com.google.inject.Inject;
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/authentication/User.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/authentication/User.java b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/authentication/User.java
deleted file mode 100644
index e967624..0000000
--- a/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/authentication/User.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.eagle.common.authentication;
-
-import java.io.Serializable;
-import java.security.Principal;
-import java.util.Set;
-
-public class User implements Principal, Serializable {
- private String username = "Unauthenticated";
- private Set<String> roles = null;
-
- public User() {
- }
-
- public User(String username) {
- this.username = username;
- }
-
- public User(String username, Set<String> roles) {
- this.username = username;
- this.roles = roles;
- }
-
- public Set<String> getRoles() {
- return roles;
- }
-
- public String getName() {
- return username;
- }
-}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/rest/RESTResponse.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/rest/RESTResponse.java b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/rest/RESTResponse.java
new file mode 100644
index 0000000..7aaade3
--- /dev/null
+++ b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/rest/RESTResponse.java
@@ -0,0 +1,255 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.eagle.common.rest;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.eagle.common.function.ThrowableConsumer;
+import org.apache.eagle.common.function.ThrowableSupplier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+public class RESTResponse<T> {
+ private static final Logger LOGGER = LoggerFactory.getLogger(RESTResponse.class);
+
+ @JsonProperty
+ private boolean success = false;
+ @JsonProperty
+ private String message;
+ @JsonProperty
+ private String exception;
+ @JsonProperty
+ private T data;
+
+ public RESTResponse() {
+ }
+
+ public RESTResponse(Throwable throwable) {
+ if (throwable.getMessage() == null || throwable.getMessage().isEmpty()) {
+ this.setMessage(throwable.getMessage());
+ } else {
+ this.setMessage(ExceptionUtils.getMessage(throwable));
+ }
+ this.setException(ExceptionUtils.getStackTrace(throwable));
+ }
+
+ public T getData() {
+ return data;
+ }
+
+ public void setData(T data) {
+ this.data = data;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public static <E> RestResponseBuilder<E> builder() {
+ return new RestResponseBuilder<>();
+ }
+
+ public static <E> RestResponseBuilder<E> of(E data) {
+ return RESTResponse.<E>builder().data(data);
+ }
+
+ public static <E> RestResponseBuilder<E> of(Consumer<RestResponseBuilder<E>> func) {
+ return RESTResponse.<E>builder().of(func);
+ }
+
+ public static <E> RestResponseBuilder<E> of(Supplier<E> func) {
+ return RESTResponse.<E>builder().of(func);
+ }
+
+ public static <E> RestResponseBuilder<E> async(ThrowableSupplier<E, Exception> func) {
+ return RESTResponse.<E>builder().async(func);
+ }
+
+ public static <E> RestResponseBuilder<E> async(ThrowableConsumer<RestResponseBuilder<E>, Exception> func) {
+ return RESTResponse.<E>builder().async(func);
+ }
+
+ public String getException() {
+ return exception;
+ }
+
+ public void setThrowable(Throwable exception) {
+ this.setException(ExceptionUtils.getStackTrace(exception));
+ }
+
+ public void setException(String exception) {
+ this.exception = exception;
+ }
+
+ public static class RestResponseBuilder<E> {
+ private RESTResponse current = new RESTResponse();
+ private Response.Status status = Response.Status.OK;
+ private CompletableFuture future = null;
+
+ public RestResponseBuilder<E> success(boolean success) {
+ this.current.setSuccess(success);
+ return this;
+ }
+
+ public RestResponseBuilder<E> status(Response.Status status) {
+ this.status = status;
+ return this;
+ }
+
+ public RestResponseBuilder<E> status(boolean success, Response.Status status) {
+ this.success(success);
+ this.status(status);
+ return this;
+ }
+
+ public RestResponseBuilder<E> message(String message) {
+ this.current.setMessage(message);
+ return this;
+ }
+
+ public RestResponseBuilder<E> data(E data) {
+ this.current.setData(data);
+ return this;
+ }
+
+ public RestResponseBuilder<E> exception(Throwable exception) {
+ this.current.setThrowable(exception);
+ if (this.current.getMessage() == null) {
+ if (exception.getMessage() == null || exception.getMessage().isEmpty()) {
+ this.current.setMessage(ExceptionUtils.getMessage(exception));
+ } else {
+ this.current.setMessage(exception.getMessage());
+ }
+ }
+ return this;
+ }
+
+ public RestResponseBuilder<E> of(Consumer<RestResponseBuilder<E>> func) {
+ try {
+ this.success(true).status(Response.Status.OK);
+ func.accept(this);
+ } catch (Exception ex) {
+ LOGGER.error("Exception: " + ex.getMessage(), ex);
+ this.success(false).data(null).status(Response.Status.BAD_REQUEST).exception(ex);
+ raiseWebAppException(ex);
+ }
+ return this;
+ }
+
+ public RestResponseBuilder<E> of(Supplier<E> func) {
+ try {
+ this.success(true).status(Response.Status.OK).data(func.get());
+ } catch (Throwable ex) {
+ LOGGER.error("Exception: " + ex.getMessage(), ex);
+ this.success(false).status(Response.Status.BAD_REQUEST).exception(ex);
+ raiseWebAppException(ex);
+ }
+ return this;
+ }
+
+ public RestResponseBuilder<E> async(ThrowableSupplier<E, Exception> func) {
+ CompletableFuture future = CompletableFuture.runAsync(() -> {
+ try {
+ this.status(Response.Status.OK).success(true).data(func.get());
+ } catch (Throwable e) {
+ LOGGER.error("Exception: " + e.getMessage(), e);
+ this.success(false).status(Response.Status.BAD_REQUEST).exception(e);
+ raiseWebAppException(e);
+ }
+ });
+ runAsync(future);
+ return this;
+ }
+
+ public RestResponseBuilder<E> async(ThrowableConsumer<RestResponseBuilder<E>, Exception> func) {
+ CompletableFuture future = CompletableFuture.runAsync(() -> {
+ try {
+ func.accept(this);
+ this.success(true);
+ } catch (Throwable ex) {
+ LOGGER.error("Exception: " + ex.getMessage(), ex);
+ this.success(false).status(Response.Status.BAD_REQUEST).exception(ex);
+ raiseWebAppException(ex);
+ }
+ });
+ runAsync(future);
+ return this;
+ }
+
+ private void runAsync(CompletableFuture future) {
+ try {
+ future.get();
+ } catch (InterruptedException ex) {
+ LOGGER.error("InterruptedException: " + ex.getMessage(), ex);
+ Thread.currentThread().interrupt();
+ future.cancel(true);
+ this.success(false).status(Response.Status.BAD_REQUEST).exception(ex.getCause());
+ raiseWebAppException(ex);
+ } catch (ExecutionException ex) {
+ LOGGER.error("ExecutionException: " + ex.getMessage(), ex);
+ this.success(false).status(Response.Status.BAD_REQUEST).exception(ex.getCause());
+ raiseWebAppException(ex);
+ }
+ }
+
+ private void raiseWebAppException(Throwable ex) {
+ throw new WebApplicationException(ex, Response.status(this.status).entity(this.current).build());
+ }
+
+
+ public RestResponseBuilder<E> then(ThrowableConsumer<RestResponseBuilder<E>, Exception> func) {
+ try {
+ func.accept(this);
+ } catch (Throwable ex) {
+ LOGGER.error("Exception: " + ex.getMessage(), ex);
+ this.success(false).status(Response.Status.BAD_REQUEST).exception(ex);
+ raiseWebAppException(ex);
+ }
+ return this;
+ }
+
+ public RESTResponse<E> get() {
+ return current;
+ }
+
+ public Response build() {
+ return Response.status(status).entity(current).type(MediaType.APPLICATION_JSON).build();
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/DenyAll.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/DenyAll.java b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/DenyAll.java
new file mode 100644
index 0000000..db5cc99
--- /dev/null
+++ b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/DenyAll.java
@@ -0,0 +1,27 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.eagle.common.security;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DenyAll {
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/PermitAll.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/PermitAll.java b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/PermitAll.java
new file mode 100644
index 0000000..7975f67
--- /dev/null
+++ b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/PermitAll.java
@@ -0,0 +1,29 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.eagle.common.security;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PermitAll {
+
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/RolesAllowed.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/RolesAllowed.java b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/RolesAllowed.java
new file mode 100644
index 0000000..b3aae58
--- /dev/null
+++ b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/RolesAllowed.java
@@ -0,0 +1,26 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.eagle.common.security;
+
+import java.lang.annotation.*;
+
+@Inherited
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RolesAllowed {
+ User.Role[] value();
+}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/User.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/User.java b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/User.java
new file mode 100644
index 0000000..a99ba95
--- /dev/null
+++ b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/security/User.java
@@ -0,0 +1,176 @@
+/*
+ * 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.eagle.common.security;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.google.common.base.Preconditions;
+
+import java.io.Serializable;
+import java.security.Principal;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+@JsonSerialize
+public class User implements Principal, Serializable {
+ private String username;
+ private String firstName;
+ private String lastName;
+ private String email;
+ private String fullName;
+
+ private Collection<Role> roles;
+
+ public User() {
+
+ }
+
+ public User(User user) {
+ this.setName(user.getName());
+ this.setFirstName(user.getFirstName());
+ this.setLastName(user.getLastName());
+ this.setEmail(user.getEmail());
+ this.setRoles(user.getRoles());
+ }
+
+ public User(String username) {
+ this.username = username;
+ }
+
+ public User(String username, Collection<Role> roles) {
+ this.username = username;
+ this.roles = roles;
+ }
+
+ public Collection<Role> getRoles() {
+ return roles;
+ }
+
+ public void setRoles(Collection<Role> roles) {
+ this.roles = roles;
+ }
+
+ public String getFullName() {
+ if (this.fullName != null ) {
+ return this.fullName;
+ }
+ if (this.firstName == null && this.lastName == null) {
+ return this.username;
+ } else if (this.firstName != null && this.lastName == null ) {
+ return this.firstName;
+ } else if (this.firstName == null) {
+ return this.lastName;
+ } else {
+ return String.format("%s, %s", this.lastName, this.firstName);
+ }
+ }
+
+ @Override
+ public String getName() {
+ return this.username;
+ }
+
+ public void setName(String username) {
+ this.username = username;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public void setFullName(String fullName) {
+ this.fullName = fullName;
+ }
+
+ @Override
+ public String toString() {
+ return "User {"
+ + "name='" + username + '\''
+ + ", firstName='" + firstName + '\''
+ + ", lastName='" + lastName + '\''
+ + ", email='" + email + '\''
+ + ", fullName='" + fullName + '\''
+ + ", roles=" + roles
+ + '}';
+ }
+
+ public enum Role implements Serializable {
+ USER("USER"), // USER role with user-level permissions
+ APPLICATION("APPLICATION"), // APPLICATION role with application-level permissions
+ ADMINISTRATOR("ADMINISTRATOR"); // ADMINISTRATOR role with admin-level permissions
+
+ public static final Role[] ALL_ROLES = new Role[] {
+ USER,APPLICATION, ADMINISTRATOR
+ };
+
+ private static Map<String,Role> nameRoleMap = new HashMap<String,Role>() {
+ {
+ put(ADMINISTRATOR.roleName.toUpperCase(), ADMINISTRATOR);
+ put(APPLICATION.roleName.toUpperCase(), APPLICATION);
+ put(USER.roleName.toUpperCase(), USER);
+ }
+ };
+
+ Role(String roleName) {
+ this.roleName = roleName;
+ }
+
+ @Override
+ public String toString() {
+ return roleName;
+ }
+
+ public static Role locateCaseInsensitive(String roleName) {
+ Preconditions.checkArgument(nameRoleMap.containsKey(roleName.toUpperCase()), "Illegal role " + roleName);
+ return nameRoleMap.get(roleName.toUpperCase());
+ }
+
+ private final String roleName;
+ }
+
+ public boolean isInRole(Role ... allowedRoles) {
+ Preconditions.checkNotNull(allowedRoles);
+ if (this.roles != null ) {
+ for (Role allowRole: allowedRoles) {
+ if (this.roles.contains(allowRole)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/service/HadoopUser.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/service/HadoopUser.java b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/service/HadoopUser.java
index 5c9cf80..094b808 100644
--- a/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/service/HadoopUser.java
+++ b/eagle-core/eagle-common/src/main/java/org/apache/eagle/common/service/HadoopUser.java
@@ -19,7 +19,7 @@ package org.apache.eagle.common.service;
import java.util.List;
/**
- * Hadoop User.
+ * Hadoop UserPrincipal.
* @since : 7/11/14,2014
*/
public class HadoopUser {
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-core/eagle-metadata/eagle-metadata-base/pom.xml
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-metadata/eagle-metadata-base/pom.xml b/eagle-core/eagle-metadata/eagle-metadata-base/pom.xml
index ff3db18..88274c2 100644
--- a/eagle-core/eagle-metadata/eagle-metadata-base/pom.xml
+++ b/eagle-core/eagle-metadata/eagle-metadata-base/pom.xml
@@ -67,5 +67,9 @@
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.dropwizard</groupId>
+ <artifactId>dropwizard-auth</artifactId>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/resource/RESTResponse.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/resource/RESTResponse.java b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/resource/RESTResponse.java
deleted file mode 100644
index 5647458..0000000
--- a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/resource/RESTResponse.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * <p/>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p/>
- * 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.eagle.metadata.resource;
-
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.eagle.common.function.ThrowableConsumer;
-import org.apache.eagle.common.function.ThrowableSupplier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Response;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
-public class RESTResponse<T> {
- private static final Logger LOGGER = LoggerFactory.getLogger(RESTResponse.class);
- private boolean success = false;
- private String message;
- private String exception;
- private T data;
-
- public RESTResponse() {
- }
-
- public RESTResponse(Throwable throwable) {
- if (throwable.getMessage() == null || throwable.getMessage().isEmpty()) {
- this.setMessage(throwable.getMessage());
- } else {
- this.setMessage(ExceptionUtils.getMessage(throwable));
- }
- this.setException(ExceptionUtils.getStackTrace(throwable));
- }
-
- public T getData() {
- return data;
- }
-
- public void setData(T data) {
- this.data = data;
- }
-
- public String getMessage() {
- return message;
- }
-
- public void setMessage(String message) {
- this.message = message;
- }
-
- public boolean isSuccess() {
- return success;
- }
-
- public void setSuccess(boolean success) {
- this.success = success;
- }
-
- public static <E> RestResponseBuilder<E> builder() {
- return new RestResponseBuilder<>();
- }
-
- public static <E> RestResponseBuilder<E> of(E data) {
- return RESTResponse.<E>builder().data(data);
- }
-
- public static <E> RestResponseBuilder<E> of(Consumer<RestResponseBuilder<E>> func) {
- return RESTResponse.<E>builder().of(func);
- }
-
- public static <E> RestResponseBuilder<E> of(Supplier<E> func) {
- return RESTResponse.<E>builder().of(func);
- }
-
- public static <E> RestResponseBuilder<E> async(ThrowableSupplier<E, Exception> func) {
- return RESTResponse.<E>builder().async(func);
- }
-
- public static <E> RestResponseBuilder<E> async(ThrowableConsumer<RestResponseBuilder<E>, Exception> func) {
- return RESTResponse.<E>builder().async(func);
- }
-
- public String getException() {
- return exception;
- }
-
- public void setThrowable(Throwable exception) {
- this.setException(ExceptionUtils.getStackTrace(exception));
- }
-
- public void setException(String exception) {
- this.exception = exception;
- }
-
-
- public static class RestResponseBuilder<E> {
- private RESTResponse current = new RESTResponse();
- private Response.Status status = Response.Status.OK;
- private CompletableFuture future = null;
-
- public RestResponseBuilder<E> success(boolean success) {
- this.current.setSuccess(success);
- return this;
- }
-
- public RestResponseBuilder<E> status(Response.Status status) {
- this.status = status;
- return this;
- }
-
- public RestResponseBuilder<E> status(boolean success, Response.Status status) {
- this.success(success);
- this.status(status);
- return this;
- }
-
- public RestResponseBuilder<E> message(String message) {
- this.current.setMessage(message);
- return this;
- }
-
- public RestResponseBuilder<E> data(E data) {
- this.current.setData(data);
- return this;
- }
-
- public RestResponseBuilder<E> exception(Throwable exception) {
- this.current.setThrowable(exception);
- if (this.current.getMessage() == null) {
- if (exception.getMessage() == null || exception.getMessage().isEmpty()) {
- this.current.setMessage(ExceptionUtils.getMessage(exception));
- } else {
- this.current.setMessage(exception.getMessage());
- }
- }
- return this;
- }
-
- public RestResponseBuilder<E> of(Consumer<RestResponseBuilder<E>> func) {
- try {
- this.success(true).status(Response.Status.OK);
- func.accept(this);
- } catch (Exception ex) {
- LOGGER.error("Exception: " + ex.getMessage(), ex);
- this.success(false).data(null).status(Response.Status.BAD_REQUEST).exception(ex);
- raiseWebAppException(ex);
- }
- return this;
- }
-
- public RestResponseBuilder<E> of(Supplier<E> func) {
- try {
- this.success(true).status(Response.Status.OK).data(func.get());
- } catch (Throwable ex) {
- LOGGER.error("Exception: " + ex.getMessage(), ex);
- this.success(false).status(Response.Status.BAD_REQUEST).exception(ex);
- raiseWebAppException(ex);
- }
- return this;
- }
-
- public RestResponseBuilder<E> async(ThrowableSupplier<E, Exception> func) {
- CompletableFuture future = CompletableFuture.runAsync(() -> {
- try {
- this.status(Response.Status.OK).success(true).data(func.get());
- } catch (Throwable e) {
- LOGGER.error("Exception: " + e.getMessage(), e);
- this.success(false).status(Response.Status.BAD_REQUEST).exception(e);
- raiseWebAppException(e);
- }
- });
- runAsync(future);
- return this;
- }
-
- public RestResponseBuilder<E> async(ThrowableConsumer<RestResponseBuilder<E>, Exception> func) {
- CompletableFuture future = CompletableFuture.runAsync(() -> {
- try {
- func.accept(this);
- this.success(true);
- } catch (Throwable ex) {
- LOGGER.error("Exception: " + ex.getMessage(), ex);
- this.success(false).status(Response.Status.BAD_REQUEST).exception(ex);
- raiseWebAppException(ex);
- }
- });
- runAsync(future);
- return this;
- }
-
- private void runAsync(CompletableFuture future) {
- try {
- future.get();
- } catch (InterruptedException ex) {
- LOGGER.error("InterruptedException: " + ex.getMessage(), ex);
- Thread.currentThread().interrupt();
- future.cancel(true);
- this.success(false).status(Response.Status.BAD_REQUEST).exception(ex.getCause());
- raiseWebAppException(ex);
- } catch (ExecutionException ex) {
- LOGGER.error("ExecutionException: " + ex.getMessage(), ex);
- this.success(false).status(Response.Status.BAD_REQUEST).exception(ex.getCause());
- raiseWebAppException(ex);
- }
- }
-
- private void raiseWebAppException(Throwable ex) {
- throw new WebApplicationException(ex, Response.status(this.status).entity(this.current).build());
- }
-
-
- public RestResponseBuilder<E> then(ThrowableConsumer<RestResponseBuilder<E>, Exception> func) {
- try {
- func.accept(this);
- } catch (Throwable ex) {
- LOGGER.error("Exception: " + ex.getMessage(), ex);
- this.success(false).status(Response.Status.BAD_REQUEST).exception(ex);
- raiseWebAppException(ex);
- }
- return this;
- }
-
- public RESTResponse<E> get() {
- return current;
- }
-
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/resource/SiteResource.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/resource/SiteResource.java b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/resource/SiteResource.java
index a5461b3..22a693a 100644
--- a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/resource/SiteResource.java
+++ b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/resource/SiteResource.java
@@ -16,6 +16,7 @@
*/
package org.apache.eagle.metadata.resource;
+import org.apache.eagle.common.rest.RESTResponse;
import org.apache.eagle.metadata.exceptions.SiteDeleteException;
import org.apache.eagle.metadata.model.SiteEntity;
import org.apache.eagle.metadata.service.ApplicationEntityService;
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-core/eagle-query/eagle-entity-base/src/main/java/org/apache/eagle/log/entity/meta/EntityDefinitionManager.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-query/eagle-entity-base/src/main/java/org/apache/eagle/log/entity/meta/EntityDefinitionManager.java b/eagle-core/eagle-query/eagle-entity-base/src/main/java/org/apache/eagle/log/entity/meta/EntityDefinitionManager.java
index 7b1010d..8795ba0 100755
--- a/eagle-core/eagle-query/eagle-entity-base/src/main/java/org/apache/eagle/log/entity/meta/EntityDefinitionManager.java
+++ b/eagle-core/eagle-query/eagle-entity-base/src/main/java/org/apache/eagle/log/entity/meta/EntityDefinitionManager.java
@@ -278,7 +278,7 @@ public class EntityDefinitionManager {
}
/**
- * User can register their own field SerDeser
+ * UserPrincipal can register their own field SerDeser
* @param clazz class of the the SerDeser
* @param entitySerDeser entity or field SerDeser
* @throws IllegalArgumentException
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-core/eagle-query/eagle-storage-hbase/src/test/java/org/apache/eagle/storage/hbase/TestWithHBaseCoprocessor.java
----------------------------------------------------------------------
diff --git a/eagle-core/eagle-query/eagle-storage-hbase/src/test/java/org/apache/eagle/storage/hbase/TestWithHBaseCoprocessor.java b/eagle-core/eagle-query/eagle-storage-hbase/src/test/java/org/apache/eagle/storage/hbase/TestWithHBaseCoprocessor.java
index b3d3cfa..b647173 100644
--- a/eagle-core/eagle-query/eagle-storage-hbase/src/test/java/org/apache/eagle/storage/hbase/TestWithHBaseCoprocessor.java
+++ b/eagle-core/eagle-query/eagle-storage-hbase/src/test/java/org/apache/eagle/storage/hbase/TestWithHBaseCoprocessor.java
@@ -25,6 +25,7 @@ import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.junit.AfterClass;
+import org.junit.Assert;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -46,14 +47,27 @@ public class TestWithHBaseCoprocessor {
conf.setStrings(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, AggregateProtocolEndPoint.class.getName());
conf.setInt("hbase.master.info.port", -1);//avoid port clobbering
conf.setInt("hbase.regionserver.info.port", -1);//avoid port clobbering
+
+ int attempts = 0;
hbase = new HBaseTestingUtility();
- try {
- hbase.startMiniCluster();
- } catch (Exception e) {
- LOG.error("Error to start mini cluster: " + e.getMessage(), e);
- throw new IllegalStateException(e);
+ boolean successToStart = false;
+ while (attempts < 3) {
+ try {
+ attempts ++;
+ hbase.startMiniCluster();
+ successToStart = true;
+ } catch (Exception e) {
+ LOG.error("Error to start mini cluster (tried {} times): {}", attempts, e.getMessage(), e);
+ try {
+ hbase.shutdownMiniCluster();
+ } catch (Exception e1) {
+ LOG.warn(e.getMessage(), e);
+ }
+ }
}
+ Assert.assertTrue("Failed to start mini cluster in " + attempts + " attempts", successToStart);
+
HTable table = hbase.createTable(String.valueOf("unittest"),"f");
HTableDescriptor descriptor = new HTableDescriptor(table.getTableDescriptor());
descriptor.addCoprocessor(AggregateProtocolEndPoint.class.getName());
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-jpm/eagle-jpm-analyzer/src/main/java/org/apache/eagle/jpm/analyzer/resource/AnalyzerResource.java
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-analyzer/src/main/java/org/apache/eagle/jpm/analyzer/resource/AnalyzerResource.java b/eagle-jpm/eagle-jpm-analyzer/src/main/java/org/apache/eagle/jpm/analyzer/resource/AnalyzerResource.java
index dc09202..80d9fb7 100644
--- a/eagle-jpm/eagle-jpm-analyzer/src/main/java/org/apache/eagle/jpm/analyzer/resource/AnalyzerResource.java
+++ b/eagle-jpm/eagle-jpm-analyzer/src/main/java/org/apache/eagle/jpm/analyzer/resource/AnalyzerResource.java
@@ -18,10 +18,10 @@
package org.apache.eagle.jpm.analyzer.resource;
import com.google.inject.Inject;
+import org.apache.eagle.common.rest.RESTResponse;
import org.apache.eagle.jpm.analyzer.meta.MetaManagementService;
import org.apache.eagle.jpm.analyzer.meta.model.JobMetaEntity;
import org.apache.eagle.jpm.analyzer.meta.model.PublisherEntity;
-import org.apache.eagle.metadata.resource.RESTResponse;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-jpm/eagle-jpm-analyzer/src/main/java/org/apache/eagle/jpm/analyzer/util/Utils.java
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-analyzer/src/main/java/org/apache/eagle/jpm/analyzer/util/Utils.java b/eagle-jpm/eagle-jpm-analyzer/src/main/java/org/apache/eagle/jpm/analyzer/util/Utils.java
index 66f7622..a987bd8 100644
--- a/eagle-jpm/eagle-jpm-analyzer/src/main/java/org/apache/eagle/jpm/analyzer/util/Utils.java
+++ b/eagle-jpm/eagle-jpm-analyzer/src/main/java/org/apache/eagle/jpm/analyzer/util/Utils.java
@@ -19,9 +19,9 @@
package org.apache.eagle.jpm.analyzer.util;
import com.typesafe.config.Config;
+import org.apache.eagle.common.rest.RESTResponse;
import org.apache.eagle.jpm.analyzer.meta.model.JobMetaEntity;
import org.apache.eagle.jpm.util.resourcefetch.connection.InputStreamUtils;
-import org.apache.eagle.metadata.resource.RESTResponse;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-jpm/eagle-jpm-spark-history/src/main/java/org/apache/eagle/jpm/spark/history/crawl/JHFSparkEventReader.java
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-spark-history/src/main/java/org/apache/eagle/jpm/spark/history/crawl/JHFSparkEventReader.java b/eagle-jpm/eagle-jpm-spark-history/src/main/java/org/apache/eagle/jpm/spark/history/crawl/JHFSparkEventReader.java
index 2ef1bd9..d245f49 100644
--- a/eagle-jpm/eagle-jpm-spark-history/src/main/java/org/apache/eagle/jpm/spark/history/crawl/JHFSparkEventReader.java
+++ b/eagle-jpm/eagle-jpm-spark-history/src/main/java/org/apache/eagle/jpm/spark/history/crawl/JHFSparkEventReader.java
@@ -169,7 +169,7 @@ public class JHFSparkEventReader {
// the second argument of getNormalizeName() is changed to null because the original code contains sensitive text
// original second argument looks like: this.app.getConfig().getConfig().get("xxx"), "xxx" is the sensitive text
entity.getTags().put(SparkJobTagName.SPARK_APP_NORM_NAME.toString(), this.getNormalizedName(JSONUtils.getString(event, "App Name"), null));
- entity.getTags().put(SparkJobTagName.SPARK_USER.toString(), JSONUtils.getString(event, "User"));
+ entity.getTags().put(SparkJobTagName.SPARK_USER.toString(), JSONUtils.getString(event, "UserPrincipal"));
entity.setTimestamp(appStartTime);
}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/partials/queue/overview.html
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/partials/queue/overview.html b/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/partials/queue/overview.html
index 732fbb2..dfcf41c 100644
--- a/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/partials/queue/overview.html
+++ b/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/partials/queue/overview.html
@@ -42,7 +42,7 @@
<!-- div class="nav-tabs-custom">
<ul class="nav nav-tabs">
- <li class="active"><a data-toggle="tab" href="#queueUser">User</a></li>
+ <li class="active"><a data-toggle="tab" href="#queueUser">UserPrincipal</a></li>
<li><a data-toggle="tab" href="#queueJob">Job</a></li>
<li class="pull-right">
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-security/eagle-security-common/src/main/java/org/apache/eagle/security/entity/HdfsUserCommandPatternEntity.java
----------------------------------------------------------------------
diff --git a/eagle-security/eagle-security-common/src/main/java/org/apache/eagle/security/entity/HdfsUserCommandPatternEntity.java b/eagle-security/eagle-security-common/src/main/java/org/apache/eagle/security/entity/HdfsUserCommandPatternEntity.java
index e8c7b72..713057b 100644
--- a/eagle-security/eagle-security-common/src/main/java/org/apache/eagle/security/entity/HdfsUserCommandPatternEntity.java
+++ b/eagle-security/eagle-security-common/src/main/java/org/apache/eagle/security/entity/HdfsUserCommandPatternEntity.java
@@ -25,7 +25,7 @@ import org.apache.eagle.log.entity.meta.*;
import java.util.Map;
/**
- * User command pattern entity to specify Siddhi pattern, field selector and field modifier
+ * UserPrincipal command pattern entity to specify Siddhi pattern, field selector and field modifier
*/
@Table("hdfsusercommandpattern")
@ColumnFamily("f")
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-security/eagle-security-hive/src/test/java/org/apache/eagle/security/hive/ql/TestParser.java
----------------------------------------------------------------------
diff --git a/eagle-security/eagle-security-hive/src/test/java/org/apache/eagle/security/hive/ql/TestParser.java b/eagle-security/eagle-security-hive/src/test/java/org/apache/eagle/security/hive/ql/TestParser.java
index a5f5f82..599a4c8 100644
--- a/eagle-security/eagle-security-hive/src/test/java/org/apache/eagle/security/hive/ql/TestParser.java
+++ b/eagle-security/eagle-security-hive/src/test/java/org/apache/eagle/security/hive/ql/TestParser.java
@@ -212,7 +212,7 @@ public class TestParser {
public void testCreateTable() throws Exception {
String query = "CREATE TABLE page_view(viewTime INT, userid BIGINT,\n" +
" page_url STRING, referrer_url STRING,\n" +
- " ip STRING COMMENT 'IP Address of the User')\n" +
+ " ip STRING COMMENT 'IP Address of the UserPrincipal')\n" +
"COMMENT 'This is the page view table'\n" +
"PARTITIONED BY(dt STRING, country STRING)\n" +
"STORED AS SEQUENCEFILE";
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/pom.xml
----------------------------------------------------------------------
diff --git a/eagle-server/pom.xml b/eagle-server/pom.xml
index c2cefcd..77e974a 100644
--- a/eagle-server/pom.xml
+++ b/eagle-server/pom.xml
@@ -181,6 +181,15 @@
<version>1.6</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>io.dropwizard</groupId>
+ <artifactId>dropwizard-testing</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jasypt</groupId>
+ <artifactId>jasypt</artifactId>
+ </dependency>
</dependencies>
<profiles>
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/RESTExceptionMapper.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/RESTExceptionMapper.java b/eagle-server/src/main/java/org/apache/eagle/server/RESTExceptionMapper.java
index 1799eff..9a5ab49 100644
--- a/eagle-server/src/main/java/org/apache/eagle/server/RESTExceptionMapper.java
+++ b/eagle-server/src/main/java/org/apache/eagle/server/RESTExceptionMapper.java
@@ -16,8 +16,8 @@
*/
package org.apache.eagle.server;
-import org.apache.eagle.metadata.resource.RESTResponse;
import io.dropwizard.jersey.errors.LoggingExceptionMapper;
+import org.apache.eagle.common.rest.RESTResponse;
import java.util.concurrent.ThreadLocalRandom;
import javax.ws.rs.WebApplicationException;
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/ServerApplication.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/ServerApplication.java b/eagle-server/src/main/java/org/apache/eagle/server/ServerApplication.java
index c779201..9f2a4ef 100644
--- a/eagle-server/src/main/java/org/apache/eagle/server/ServerApplication.java
+++ b/eagle-server/src/main/java/org/apache/eagle/server/ServerApplication.java
@@ -28,18 +28,18 @@ import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import io.swagger.jaxrs.config.BeanConfig;
import io.swagger.jaxrs.listing.ApiListingResource;
-import org.apache.eagle.alert.coordinator.CoordinatorListener;
+import org.apache.eagle.alert.coordinator.Coordinator;
import org.apache.eagle.alert.resource.SimpleCORSFiler;
import org.apache.eagle.app.service.ApplicationHealthCheckService;
import org.apache.eagle.app.service.ApplicationProviderService;
import org.apache.eagle.app.spi.ApplicationProvider;
import org.apache.eagle.common.Version;
-import org.apache.eagle.common.utils.ReflectionsHelper;
import org.apache.eagle.log.base.taggedlog.EntityJsonModule;
import org.apache.eagle.log.base.taggedlog.TaggedLogAPIEntity;
import org.apache.eagle.log.entity.repo.EntityRepositoryScanner;
import org.apache.eagle.metadata.service.ApplicationStatusUpdateService;
-import org.apache.eagle.server.authentication.BasicAuthProviderBuilder;
+import org.apache.eagle.server.security.BasicAuthBuilder;
+import org.apache.eagle.server.security.BasicAuthResourceFilterFactory;
import org.apache.eagle.server.task.ManagedService;
import org.apache.eagle.server.module.GuiceBundleLoader;
import org.slf4j.Logger;
@@ -50,7 +50,7 @@ import java.util.EnumSet;
import static org.apache.eagle.app.service.impl.ApplicationHealthCheckServiceImpl.HEALTH_CHECK_PATH;
-class ServerApplication extends Application<ServerConfig> {
+public class ServerApplication extends Application<ServerConfig> {
private static final Logger LOG = LoggerFactory.getLogger(ServerApplication.class);
@Inject
private ApplicationStatusUpdateService applicationStatusUpdateService;
@@ -116,15 +116,28 @@ class ServerApplication extends Application<ServerConfig> {
.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
// Register authentication provider
- environment.jersey().register(new BasicAuthProviderBuilder(configuration.getAuth(), environment).build());
-
- // Context listener
- environment.servlets().addServletListeners(new CoordinatorListener());
+ BasicAuthBuilder authBuilder = new BasicAuthBuilder(configuration.getAuthConfig(), environment);
+ environment.jersey().register(authBuilder.getBasicAuthProvider());
+ environment.jersey().getResourceConfig().getResourceFilterFactories()
+ .add(new BasicAuthResourceFilterFactory(authBuilder.getBasicAuthenticator()));
registerAppServices(environment);
}
private void registerAppServices(Environment environment) {
+ LOG.debug("Registering CoordinatorService");
+ environment.lifecycle().manage(new Managed() {
+ @Override
+ public void start() throws Exception {
+ Coordinator.startSchedule();
+ }
+
+ @Override
+ public void stop() throws Exception {
+
+ }
+ });
+
// Run application status service in background
LOG.debug("Registering ApplicationStatusUpdateService");
Managed updateAppStatusTask = new ManagedService(applicationStatusUpdateService);
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/ServerConfig.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/ServerConfig.java b/eagle-server/src/main/java/org/apache/eagle/server/ServerConfig.java
index 3def198..68a874e 100644
--- a/eagle-server/src/main/java/org/apache/eagle/server/ServerConfig.java
+++ b/eagle-server/src/main/java/org/apache/eagle/server/ServerConfig.java
@@ -18,7 +18,7 @@ package org.apache.eagle.server;
import io.dropwizard.Configuration;
import org.apache.eagle.common.Version;
-import org.apache.eagle.server.authentication.config.AuthenticationSettings;
+import org.apache.eagle.server.security.config.AuthenticationConfig;
import com.fasterxml.jackson.annotation.JsonProperty;
public class ServerConfig extends Configuration {
@@ -29,15 +29,15 @@ public class ServerConfig extends Configuration {
private static final String LICENSE = "Apache License (Version 2.0)";
private static final String LICENSE_URL = "http://www.apache.org/licenses/LICENSE-2.0";
- private AuthenticationSettings auth = new AuthenticationSettings();
+ private AuthenticationConfig auth = new AuthenticationConfig();
@JsonProperty("auth")
- public AuthenticationSettings getAuth() {
+ public AuthenticationConfig getAuthConfig() {
return auth;
}
@JsonProperty("auth")
- public void setAuth(AuthenticationSettings auth) {
+ public void setAuthConfig(AuthenticationConfig auth) {
this.auth = auth;
}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/ServerMain.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/ServerMain.java b/eagle-server/src/main/java/org/apache/eagle/server/ServerMain.java
index 318a74e..412dc2e 100644
--- a/eagle-server/src/main/java/org/apache/eagle/server/ServerMain.java
+++ b/eagle-server/src/main/java/org/apache/eagle/server/ServerMain.java
@@ -17,21 +17,47 @@
package org.apache.eagle.server;
import org.apache.eagle.common.Version;
+import org.apache.eagle.server.tool.EncryptTool;
import java.util.Date;
public class ServerMain {
+ private static final String USAGE =
+ "Usage: java " + ServerMain.class.getName() + " command [options] \n"
+ + "where options include: \n"
+ + "\tserver\t[path to configuration]\n"
+ + "\tencrypt\t[text to encrypt]\n";
+
public static void main(String[] args) {
- System.out.println(
- "\nApache Eagle\u2122 v" + Version.version + ": "
- + "built with git revision " + Version.gitRevision + " by " + Version.userName + " on " + new Date(Long.parseLong(Version.timestamp))
- );
- System.out.println("\nStarting Eagle Server ...\n");
- try {
- new ServerApplication().run(args);
- } catch (Exception e) {
- System.err.println("Oops, got error to start eagle server: " + e.getMessage());
- e.printStackTrace();
+ if (args.length > 1) {
+ String cmd = args[0];
+
+ switch (cmd) {
+ case "server":
+ System.out.println(
+ "\nApache Eagle\u2122 v" + Version.version + ": "
+ + "built with git revision " + Version.gitRevision + " by " + Version.userName + " on " + new Date(Long.parseLong(Version.timestamp))
+ );
+
+ System.out.println("\nStarting Eagle Server ...\n");
+ try {
+ new ServerApplication().run(args);
+ } catch (Exception e) {
+ System.err.println("Oops, got error to start eagle server: " + e.getMessage());
+ e.printStackTrace();
+ System.exit(1);
+ }
+ break;
+ case "encrypt":
+ new EncryptTool().execute(args);
+ break;
+ default:
+ System.err.println("Invalid command " + cmd);
+ System.err.print(USAGE);
+ System.exit(2);
+ }
+ } else {
+ System.err.print(USAGE);
System.exit(1);
}
}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/authentication/BasicAuthProviderBuilder.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/authentication/BasicAuthProviderBuilder.java b/eagle-server/src/main/java/org/apache/eagle/server/authentication/BasicAuthProviderBuilder.java
deleted file mode 100644
index 855134b..0000000
--- a/eagle-server/src/main/java/org/apache/eagle/server/authentication/BasicAuthProviderBuilder.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.eagle.server.authentication;
-
-import com.google.common.cache.CacheBuilderSpec;
-import com.sun.jersey.api.core.HttpContext;
-import com.sun.jersey.api.model.Parameter;
-import com.sun.jersey.core.spi.component.ComponentContext;
-import com.sun.jersey.server.impl.inject.AbstractHttpContextInjectable;
-import com.sun.jersey.spi.inject.Injectable;
-import io.dropwizard.auth.Auth;
-import io.dropwizard.auth.Authenticator;
-import io.dropwizard.auth.CachingAuthenticator;
-import io.dropwizard.auth.basic.BasicAuthProvider;
-import io.dropwizard.auth.basic.BasicCredentials;
-import io.dropwizard.setup.Environment;
-import org.apache.eagle.common.authentication.User;
-import org.apache.eagle.server.authentication.authenticator.LdapBasicAuthenticator;
-import org.apache.eagle.server.authentication.authenticator.SimpleBasicAuthenticator;
-import org.apache.eagle.server.authentication.config.AuthenticationSettings;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class BasicAuthProviderBuilder {
- private static final String SIMPLE_MODE_REALM = "SIMPLE_AUTHENTICATION";
- private static final String LDAP_MODE_REALM = "LDAP_AUTHENTICATION";
- private static final Map<String, BasicAuthProvider<User>> MAPPING = new HashMap<>();
- private AuthenticationSettings authSettings;
- private Environment environment;
-
- public BasicAuthProviderBuilder(AuthenticationSettings authSettings, Environment environment) {
- this.authSettings = authSettings;
- this.environment = environment;
- Authenticator<BasicCredentials, User> simpleAuthenticator = new SimpleBasicAuthenticator(authSettings.getSimple());
- Authenticator<BasicCredentials, User> ldapAuthenticator = new LdapBasicAuthenticator(authSettings.getLdap());
- boolean needsCaching = authSettings.needsCaching();
- MAPPING.put("simple",
- new BasicAuthProvider<>(needsCaching ? cache(simpleAuthenticator) : simpleAuthenticator, SIMPLE_MODE_REALM));
- MAPPING.put("ldap",
- new BasicAuthProvider<>(needsCaching ? cache(ldapAuthenticator) : ldapAuthenticator, LDAP_MODE_REALM));
- }
-
- public BasicAuthProvider build() {
- if (authSettings.isEnabled()) {
- String mode = authSettings.getMode();
- if (MAPPING.containsKey(mode)) {
- return MAPPING.get(mode);
- } else {
- throw new RuntimeException(String.format("No matching mode found: %s", mode));
- }
- } else {
- return new BasicAuthProvider<User>(null, "") {
- public Injectable<?> getInjectable(ComponentContext ic, Auth a, Parameter c) {
- return new AbstractHttpContextInjectable<User>() {
- public User getValue(HttpContext c) {
- return new User("non-auth");
- }
- };
- }
- };
- }
- }
-
- private Authenticator<BasicCredentials, User> cache(Authenticator<BasicCredentials, User> authenticator) {
- return new CachingAuthenticator<>(environment.metrics(), authenticator, CacheBuilderSpec.parse(authSettings.getCachePolicy()));
- }
-}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/authentication/authenticator/LdapBasicAuthenticator.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/authentication/authenticator/LdapBasicAuthenticator.java b/eagle-server/src/main/java/org/apache/eagle/server/authentication/authenticator/LdapBasicAuthenticator.java
deleted file mode 100644
index c67dea8..0000000
--- a/eagle-server/src/main/java/org/apache/eagle/server/authentication/authenticator/LdapBasicAuthenticator.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.eagle.server.authentication.authenticator;
-
-import com.google.common.base.Optional;
-import io.dropwizard.auth.AuthenticationException;
-import io.dropwizard.auth.Authenticator;
-import io.dropwizard.auth.basic.BasicCredentials;
-import org.apache.eagle.common.authentication.User;
-import org.apache.eagle.server.authentication.config.LdapSettings;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.naming.Context;
-import javax.naming.directory.InitialDirContext;
-import java.io.File;
-import java.util.Hashtable;
-
-public class LdapBasicAuthenticator implements Authenticator<BasicCredentials, User> {
- private static final Logger LOGGER = LoggerFactory.getLogger(LdapBasicAuthenticator.class);
- private static final String LDAP_LDAP_CTX_FACTORY_NAME = "com.sun.jndi.ldap.LdapCtxFactory";
- private static final String LDAP_CONNECT_TIMEOUT_KEY = "com.sun.jndi.ldap.connect.timeout";
- private static final String LDAP_READ_TIMEOUT_KEY = "com.sun.jndi.ldap.read.timeout";
- private static final String SYS_PROP_SSL_KEY_STORE = "javax.net.ssl.keyStore";
- private static final String SYS_PROP_SSL_TRUST_STORE = "javax.net.ssl.trustStore";
- private static final String LDAPS_URL_PREFIX = "ldaps://";
- private static final String SSL_PROTOCOL_VALUE = "ssl";
- private LdapSettings settings = null;
-
- public LdapBasicAuthenticator(LdapSettings settings) {
- this.settings = settings;
- }
-
- public Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException {
- String sanitizedUsername = sanitizeUsername(credentials.getUsername());
- try {
- new InitialDirContext(getContextEnvironment(sanitizedUsername, credentials.getPassword()));
- return Optional.of(new User(sanitizedUsername));
- } catch (javax.naming.AuthenticationException ae) {
- LOGGER.warn(String.format("Authentication failed for user[%s]: wrong username or password", sanitizedUsername));
- return Optional.absent();
- } catch (Exception e) {
- throw new AuthenticationException(String.format("Error occurs while trying to authenticate for user[%s]: %s", sanitizedUsername, e.getMessage()), e);
- }
- }
-
- Hashtable<String, String> getContextEnvironment(String sanitizedUsername, String password) {
- String providerUrl = settings.getProviderUrl();
- if (providerUrl == null) {
- throw new IllegalArgumentException("providerUrl of the ldap service shouldn't be null");
- }
-
- Hashtable<String, String> env = new Hashtable<>();
- env.put(Context.INITIAL_CONTEXT_FACTORY, LDAP_LDAP_CTX_FACTORY_NAME);
- env.put(Context.PROVIDER_URL, providerUrl);
- env.put(LDAP_CONNECT_TIMEOUT_KEY, String.valueOf(settings.getConnectingTimeout().toMilliseconds()));
- env.put(LDAP_READ_TIMEOUT_KEY, String.valueOf(settings.getReadingTimeout().toMilliseconds()));
-
- String strategy = settings.getStrategy();
- if (!"".equals(strategy)) {
- env.put(Context.SECURITY_AUTHENTICATION, strategy);
- }
-
- if (providerUrl.toLowerCase().startsWith(LDAPS_URL_PREFIX)) { // using ldap over ssl to authenticate
- env.put(Context.SECURITY_PROTOCOL, SSL_PROTOCOL_VALUE);
-
- String certificateAbsolutePath = settings.getCertificateAbsolutePath();
- if (certificateAbsolutePath == null || "".equals(certificateAbsolutePath)) {
- throw new RuntimeException("The attribute 'certificateAbsolutePath' must be set when using ldap over ssl to authenticate.");
- }
- if (!new File(certificateAbsolutePath).exists()) {
- throw new RuntimeException(String.format("The file specified not existing: %s", certificateAbsolutePath));
- }
-
- System.setProperty(SYS_PROP_SSL_KEY_STORE, certificateAbsolutePath);
- System.setProperty(SYS_PROP_SSL_TRUST_STORE, certificateAbsolutePath);
- }
-
- env.put(Context.SECURITY_PRINCIPAL, comprisePrincipal(sanitizedUsername));
- env.put(Context.SECURITY_CREDENTIALS, password);
- return env;
- }
-
- String comprisePrincipal(String sanitizedUsername) {
- return settings.getPrincipalTemplate().replaceAll("\\$\\{USERNAME\\}", sanitizedUsername);
- }
-
- String sanitizeUsername(String username) {
- return username.replaceAll("[^a-zA-Z0-9_.]", "");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/authentication/authenticator/SimpleBasicAuthenticator.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/authentication/authenticator/SimpleBasicAuthenticator.java b/eagle-server/src/main/java/org/apache/eagle/server/authentication/authenticator/SimpleBasicAuthenticator.java
deleted file mode 100644
index ede3b06..0000000
--- a/eagle-server/src/main/java/org/apache/eagle/server/authentication/authenticator/SimpleBasicAuthenticator.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.eagle.server.authentication.authenticator;
-
-import com.google.common.base.Optional;
-import io.dropwizard.auth.AuthenticationException;
-import io.dropwizard.auth.Authenticator;
-import io.dropwizard.auth.basic.BasicCredentials;
-import org.apache.eagle.common.authentication.User;
-import org.apache.eagle.server.authentication.config.SimpleSettings;
-
-public class SimpleBasicAuthenticator implements Authenticator<BasicCredentials, User> {
- private String acceptedUsername = null;
- private String acceptedPassword = null;
-
- public SimpleBasicAuthenticator(SimpleSettings settings) {
- acceptedUsername = settings.getUsername();
- acceptedPassword = settings.getPassword();
- }
-
- public Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException {
- String username = credentials.getUsername();
- if (acceptedUsername.equals(username) && acceptedPassword.equals(credentials.getPassword())) {
- return Optional.of(new User(username));
- }
- return Optional.absent();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/authentication/config/AuthenticationSettings.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/authentication/config/AuthenticationSettings.java b/eagle-server/src/main/java/org/apache/eagle/server/authentication/config/AuthenticationSettings.java
deleted file mode 100644
index 501ca13..0000000
--- a/eagle-server/src/main/java/org/apache/eagle/server/authentication/config/AuthenticationSettings.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.eagle.server.authentication.config;
-
-import io.dropwizard.Configuration;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class AuthenticationSettings extends Configuration {
- private boolean enabled = false;
- private String mode = null;
- private boolean caching = false;
- private String cachePolicy = null;
- private boolean authorization = false;
- private boolean annotated = true;
- private SimpleSettings simple = new SimpleSettings();
- private LdapSettings ldap = new LdapSettings();
-
- @JsonProperty
- public boolean isEnabled() {
- return enabled;
- }
-
- @JsonProperty
- public AuthenticationSettings setEnabled(boolean enabled) {
- this.enabled = enabled;
- return this;
- }
-
- @JsonProperty
- public String getMode() {
- return mode;
- }
-
- @JsonProperty
- public AuthenticationSettings setMode(String mode) {
- this.mode = mode;
- return this;
- }
-
- @JsonProperty
- public boolean needsCaching() {
- return caching;
- }
-
- @JsonProperty
- public AuthenticationSettings setCaching(boolean caching) {
- this.caching = caching;
- return this;
- }
-
- @JsonProperty
- public String getCachePolicy() {
- return cachePolicy;
- }
-
- @JsonProperty
- public AuthenticationSettings setCachePolicy(String cachePolicy) {
- this.cachePolicy = cachePolicy;
- return this;
- }
-
- @JsonProperty
- public boolean needsAuthorization() {
- return authorization;
- }
-
- @JsonProperty
- public AuthenticationSettings setAuthorization(boolean authorization) {
- this.authorization = authorization;
- return this;
- }
-
- @JsonProperty
- public boolean byAnnotated() {
- return annotated;
- }
-
- @JsonProperty
- public AuthenticationSettings setAnnotated(boolean annotated) {
- this.annotated = annotated;
- return this;
- }
-
- @JsonProperty("ldap")
- public LdapSettings getLdap() {
- return ldap;
- }
-
- @JsonProperty("ldap")
- public AuthenticationSettings setLdap(LdapSettings ldap) {
- this.ldap = ldap;
- return this;
- }
-
- @JsonProperty("simple")
- public SimpleSettings getSimple() {
- return simple;
- }
-
- @JsonProperty("simple")
- public AuthenticationSettings setSimple(SimpleSettings simple) {
- this.simple = simple;
- return this;
- }
-}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/authentication/config/LdapSettings.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/authentication/config/LdapSettings.java b/eagle-server/src/main/java/org/apache/eagle/server/authentication/config/LdapSettings.java
deleted file mode 100644
index ea2d896..0000000
--- a/eagle-server/src/main/java/org/apache/eagle/server/authentication/config/LdapSettings.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.eagle.server.authentication.config;
-
-import io.dropwizard.util.Duration;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class LdapSettings {
-
- private String providerUrl = "";
- private String strategy = "";
- private String principalTemplate = "";
- private String certificateAbsolutePath = "";
- private Duration connectingTimeout = Duration.parse("500ms");
- private Duration readingTimeout = Duration.parse("500ms");
-
- @JsonProperty
- public String getProviderUrl() {
- return providerUrl;
- }
-
- @JsonProperty
- public LdapSettings setProviderUrl(String providerUrl) {
- this.providerUrl = providerUrl;
- return this;
- }
-
- @JsonProperty
- public String getPrincipalTemplate() {
- return principalTemplate;
- }
-
- @JsonProperty
- public LdapSettings setPrincipalTemplate(String principalTemplate) {
- this.principalTemplate = principalTemplate;
- return this;
- }
-
- @JsonProperty
- public String getStrategy() {
- return strategy;
- }
-
- @JsonProperty
- public LdapSettings setStrategy(String strategy) {
- this.strategy = strategy;
- return this;
- }
-
- @JsonProperty
- public Duration getConnectingTimeout() {
- return connectingTimeout;
- }
-
- @JsonProperty
- public LdapSettings setConnectingTimeout(Duration connectingTimeout) {
- this.connectingTimeout = connectingTimeout;
- return this;
- }
-
- @JsonProperty
- public Duration getReadingTimeout() {
- return readingTimeout;
- }
-
- @JsonProperty
- public LdapSettings setReadingTimeout(Duration readingTimeout) {
- this.readingTimeout = readingTimeout;
- return this;
- }
-
- @JsonProperty
- public String getCertificateAbsolutePath() {
- return certificateAbsolutePath;
- }
-
- @JsonProperty
- public LdapSettings setCertificateAbsolutePath(String certificateAbsolutePath) {
- this.certificateAbsolutePath = certificateAbsolutePath;
- return this;
- }
-}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/authentication/config/SimpleSettings.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/authentication/config/SimpleSettings.java b/eagle-server/src/main/java/org/apache/eagle/server/authentication/config/SimpleSettings.java
deleted file mode 100644
index 35cfd70..0000000
--- a/eagle-server/src/main/java/org/apache/eagle/server/authentication/config/SimpleSettings.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.eagle.server.authentication.config;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-public class SimpleSettings {
- private String username = null;
- private String password = null;
-
- @JsonProperty
- public String getUsername() {
- return username;
- }
-
- @JsonProperty
- public SimpleSettings setUsername(String username) {
- this.username = username;
- return this;
- }
-
- @JsonProperty
- public String getPassword() {
- return password;
- }
-
- @JsonProperty
- public SimpleSettings setPassword(String password) {
- this.password = password;
- return this;
- }
-}
http://git-wip-us.apache.org/repos/asf/eagle/blob/94b597b7/eagle-server/src/main/java/org/apache/eagle/server/resource/AuthenticationResource.java
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/java/org/apache/eagle/server/resource/AuthenticationResource.java b/eagle-server/src/main/java/org/apache/eagle/server/resource/AuthenticationResource.java
new file mode 100644
index 0000000..f14cb71
--- /dev/null
+++ b/eagle-server/src/main/java/org/apache/eagle/server/resource/AuthenticationResource.java
@@ -0,0 +1,65 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.eagle.server.resource;
+
+import io.dropwizard.auth.Auth;
+import org.apache.eagle.common.security.User;
+import org.apache.eagle.common.rest.RESTResponse;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+@Path("/auth")
+public class AuthenticationResource {
+ @GET
+ @Path("/principal")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response getCurrentPrincipal(@Auth(required = false) User user) {
+ if (user != null) {
+ return RESTResponse.of(user)
+ .status(true, Response.Status.OK)
+ .build();
+ } else {
+ return RESTResponse.builder()
+ .message("No authorized principal found")
+ .status(false, Response.Status.OK)
+ .build();
+ }
+ }
+
+ @GET
+ @Path("/validate")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response validate(@Auth User user) {
+ return RESTResponse.of(user)
+ .message("Validated successfully as " + user.getName())
+ .status(true, Response.Status.OK).build();
+ }
+
+ @POST
+ @Path("/login")
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response login(@Auth User user) {
+ return RESTResponse.of(user)
+ .message("Login successfully as " + user.getName())
+ .status(true, Response.Status.OK).build();
+ }
+}
\ No newline at end of file