This is an automated email from the ASF dual-hosted git repository.
pzampino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new 89bae58 KNOX-2105 - KnoxShell support for token renewal and
revocation (#180)
89bae58 is described below
commit 89bae580c9757bd9cb2821b95c6a07f482b8a340
Author: Phil Zampino <[email protected]>
AuthorDate: Thu Nov 7 21:33:34 2019 -0500
KNOX-2105 - KnoxShell support for token renewal and revocation (#180)
* KNOX-2105 - KnoxShell support for token renewal and revocation
---
.../apache/knox/gateway/shell/ErrorResponse.java | 4 +-
.../knox/token/AbstractTokenLifecycleRequest.java | 82 ++++++++++++
.../knox/gateway/shell/knox/token/Renew.java | 41 ++++++
.../knox/gateway/shell/knox/token/Revoke.java | 41 ++++++
.../knox/gateway/shell/knox/token/Token.java | 21 +++-
.../shell/knox/token/TokenLifecycleResponse.java | 28 +++++
.../knox/gateway/shell/knox/token/TokenTest.java | 137 +++++++++++++++++++++
7 files changed, 350 insertions(+), 4 deletions(-)
diff --git
a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/ErrorResponse.java
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/ErrorResponse.java
index 58a5ed6..bf625a3 100644
---
a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/ErrorResponse.java
+++
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/ErrorResponse.java
@@ -19,7 +19,7 @@ package org.apache.knox.gateway.shell;
import org.apache.http.HttpResponse;
-class ErrorResponse extends RuntimeException {
+public class ErrorResponse extends RuntimeException {
HttpResponse response;
@@ -28,7 +28,7 @@ class ErrorResponse extends RuntimeException {
this.response = response;
}
- public HttpResponse getReponse() {
+ public HttpResponse getResponse() {
return response;
}
diff --git
a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/AbstractTokenLifecycleRequest.java
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/AbstractTokenLifecycleRequest.java
new file mode 100644
index 0000000..bf48214
--- /dev/null
+++
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/AbstractTokenLifecycleRequest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.knox.gateway.shell.knox.token;
+
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.StringEntity;
+import org.apache.knox.gateway.shell.AbstractRequest;
+import org.apache.knox.gateway.shell.ErrorResponse;
+import org.apache.knox.gateway.shell.KnoxSession;
+import org.apache.knox.gateway.shell.KnoxShellException;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.concurrent.Callable;
+
+public abstract class AbstractTokenLifecycleRequest extends
AbstractRequest<TokenLifecycleResponse> {
+
+ AbstractTokenLifecycleRequest(final KnoxSession session, final String token)
{
+ this(session, token, null);
+ }
+
+ AbstractTokenLifecycleRequest(final KnoxSession session, final String token,
final String doAsUser) {
+ super(session, doAsUser);
+ this.token = token;
+ try {
+ URIBuilder uri = uri(Token.SERVICE_PATH, "/", getOperation());
+ requestURI = uri.build();
+ } catch (URISyntaxException e) {
+ throw new KnoxShellException(e);
+ }
+ }
+
+ protected abstract String getOperation();
+
+ private URI requestURI;
+
+ private HttpPost httpPostRequest;
+
+ private String token;
+
+ public URI getRequestURI() {
+ return requestURI;
+ }
+
+ public HttpPost getRequest() {
+ return httpPostRequest;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ @Override
+ protected Callable<TokenLifecycleResponse> callable() {
+ return () -> {
+ httpPostRequest = new HttpPost(requestURI);
+ httpPostRequest.setEntity(new StringEntity(token));
+ try {
+ return new TokenLifecycleResponse(execute(httpPostRequest));
+ } catch (ErrorResponse e) {
+ return new TokenLifecycleResponse(e.getResponse());
+ }
+ };
+ }
+}
+
+
diff --git
a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/Renew.java
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/Renew.java
new file mode 100644
index 0000000..6bfbe4d
--- /dev/null
+++
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/Renew.java
@@ -0,0 +1,41 @@
+/*
+ * 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.knox.gateway.shell.knox.token;
+
+import org.apache.knox.gateway.shell.KnoxSession;
+
+public class Renew {
+
+ public static class Request extends AbstractTokenLifecycleRequest {
+
+ public static final String OPERATION = "renew";
+
+ Request(final KnoxSession session, final String token) {
+ super(session, token);
+ }
+
+ Request(final KnoxSession session, final String token, final String
doAsUser) {
+ super(session, token, doAsUser);
+ }
+
+ @Override
+ protected String getOperation() {
+ return OPERATION;
+ }
+ }
+
+}
diff --git
a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/Revoke.java
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/Revoke.java
new file mode 100644
index 0000000..a9015ea
--- /dev/null
+++
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/Revoke.java
@@ -0,0 +1,41 @@
+/*
+ * 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.knox.gateway.shell.knox.token;
+
+import org.apache.knox.gateway.shell.KnoxSession;
+
+public class Revoke {
+
+ public static class Request extends AbstractTokenLifecycleRequest {
+
+ public static final String OPERATION = "revoke";
+
+ Request(final KnoxSession session, final String token) {
+ super(session, token);
+ }
+
+ Request(final KnoxSession session, final String token, final String
doAsUser) {
+ super(session, token, doAsUser);
+ }
+
+ @Override
+ protected String getOperation() {
+ return OPERATION;
+ }
+ }
+
+}
diff --git
a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/Token.java
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/Token.java
index 90478c0..0fccfc8 100644
---
a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/Token.java
+++
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/Token.java
@@ -23,11 +23,28 @@ public class Token {
static String SERVICE_PATH = "/knoxtoken/api/v1/token";
- public static Get.Request get(KnoxSession session) {
+ public static Get.Request get(final KnoxSession session) {
return new Get.Request(session);
}
- public static Get.Request get(KnoxSession session, String doAsUser) {
+ public static Get.Request get(final KnoxSession session, final String
doAsUser) {
return new Get.Request(session, doAsUser);
}
+
+ public static Renew.Request renew(final KnoxSession session, final String
token) {
+ return new Renew.Request(session, token);
+ }
+
+ public static Renew.Request renew(final KnoxSession session, final String
token, final String doAsUser) {
+ return new Renew.Request(session, token, doAsUser);
+ }
+
+ public static Revoke.Request revoke(final KnoxSession session, final String
token) {
+ return new Revoke.Request(session, token);
+ }
+
+ public static Revoke.Request revoke(final KnoxSession session, final String
token, final String doAsUser) {
+ return new Revoke.Request(session, token, doAsUser);
+ }
+
}
diff --git
a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/TokenLifecycleResponse.java
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/TokenLifecycleResponse.java
new file mode 100644
index 0000000..0a513ed
--- /dev/null
+++
b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/knox/token/TokenLifecycleResponse.java
@@ -0,0 +1,28 @@
+/*
+ * 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.knox.gateway.shell.knox.token;
+
+import org.apache.http.HttpResponse;
+import org.apache.knox.gateway.shell.BasicResponse;
+
+public class TokenLifecycleResponse extends BasicResponse {
+
+ TokenLifecycleResponse(HttpResponse response) {
+ super(response);
+ }
+
+}
diff --git
a/gateway-shell/src/test/java/org/apache/knox/gateway/shell/knox/token/TokenTest.java
b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/knox/token/TokenTest.java
index 49cb998..b347472 100644
---
a/gateway-shell/src/test/java/org/apache/knox/gateway/shell/knox/token/TokenTest.java
+++
b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/knox/token/TokenTest.java
@@ -19,16 +19,25 @@ package org.apache.knox.gateway.shell.knox.token;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpRequest;
+import org.apache.http.util.EntityUtils;
import org.apache.knox.gateway.shell.KnoxSession;
import org.junit.Test;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.concurrent.Callable;
+
public class TokenTest {
@Test
@@ -51,6 +60,48 @@ public class TokenTest {
testToken(true, "userA");
}
+
+ @Test
+ public void testTokenRenewalWithNoDoAs() throws Exception {
+ testRenewToken(false, null);
+ }
+
+ @Test
+ public void testTokenRenewalWithNullDoAs() throws Exception {
+ testRenewToken(true, null);
+ }
+
+ @Test
+ public void testTokenRenewalWithEmptyDoAs() throws Exception {
+ testRenewToken(true, "");
+ }
+
+ @Test
+ public void testTokenRenewalWithDoAs() throws Exception {
+ testRenewToken(true, "userA");
+ }
+
+ @Test
+ public void testTokenRevocationWithNoDoAs() throws Exception {
+ testRevokeToken(false, null);
+ }
+
+ @Test
+ public void testTokenRecationWithNullDoAs() throws Exception {
+ testRevokeToken(true, null);
+ }
+
+ @Test
+ public void testTokenRevocationWithEmptyDoAs() throws Exception {
+ testRevokeToken(true, "");
+ }
+
+ @Test
+ public void testTokenRevocationWithDoAs() throws Exception {
+ testRevokeToken(true, "userA");
+ }
+
+
private void testToken(boolean setDoAsUser, String doAsUser) {
KnoxSession knoxSession = createMock(KnoxSession.class);
expect(knoxSession.base()).andReturn("http://localhost/base").atLeastOnce();
@@ -76,4 +127,90 @@ public class TokenTest {
verify(knoxSession);
}
+
+ private void testRenewToken(boolean setDoAsUser, String doAsUser) throws
Exception {
+ final String testToken = "RENEW+ABCDEFG123456";
+
+ final KnoxSession knoxSession = createMockKnoxSession();
+
+ Renew.Request request = (setDoAsUser)
+ ? Token.renew(knoxSession, testToken, doAsUser)
+ : Token.renew(knoxSession, testToken);
+
+ if (setDoAsUser) {
+ assertEquals(doAsUser, request.getDoAsUser());
+ } else {
+ assertNull(request.getDoAsUser());
+ }
+
+ testTokenLifecyle(request, testToken);
+
+ assertSame(knoxSession, request.getSession());
+ verify(knoxSession);
+ }
+
+
+ private void testRevokeToken(boolean setDoAsUser, String doAsUser) throws
Exception {
+ final String testToken = "REVOKE+ABCDEFG123456";
+
+ final KnoxSession knoxSession = createMockKnoxSession();
+
+ Revoke.Request request = (setDoAsUser)
+ ? Token.revoke(knoxSession, testToken,
doAsUser)
+ : Token.revoke(knoxSession, testToken);
+
+ if (setDoAsUser) {
+ assertEquals(doAsUser, request.getDoAsUser());
+ } else {
+ assertNull(request.getDoAsUser());
+ }
+
+ testTokenLifecyle(request, testToken);
+
+ assertSame(knoxSession, request.getSession());
+ verify(knoxSession);
+ }
+
+ private KnoxSession createMockKnoxSession() throws Exception {
+ KnoxSession knoxSession = createMock(KnoxSession.class);
+
expect(knoxSession.base()).andReturn("http://localhost/base").atLeastOnce();
+
expect(knoxSession.getHeaders()).andReturn(Collections.emptyMap()).atLeastOnce();
+
expect(knoxSession.executeNow(isA(HttpRequest.class))).andReturn(null).atLeastOnce();
+ replay(knoxSession);
+ return knoxSession;
+ }
+
+ private void testTokenLifecyle(AbstractTokenLifecycleRequest request, final
String testToken) throws Exception {
+
+ final String expectedEndpointPath =
+ request.getSession().base()+ "/knoxtoken/api/v1/token/" +
request.getOperation();
+
+ String doAsUser = request.getDoAsUser();
+ if (doAsUser != null && doAsUser.isEmpty()) {
+ doAsUser = null;
+ }
+
+ assertEquals(expectedEndpointPath + (doAsUser != null ? ("?doAs=" +
doAsUser) : ""),
+ request.getRequestURI().toString());
+
+ assertEquals(testToken, request.getToken());
+
+ Callable<TokenLifecycleResponse> callable = request.callable();
+ try {
+ callable.call();
+ } catch (Exception e) {
+ // expected
+ }
+
+ HttpEntity entity = request.getRequest().getEntity();
+ assertNotNull("Missing expected POST data.", entity);
+ String postData = null;
+ try {
+ postData = EntityUtils.toString(entity);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ assertEquals(testToken, postData);
+ }
+
}
\ No newline at end of file