knox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pzamp...@apache.org
Subject [knox] branch master updated: KNOX-2105 - KnoxShell support for token renewal and revocation (#180)
Date Fri, 08 Nov 2019 02:33:44 GMT
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 <pzampino@apache.org>
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


Mime
View raw message