This is an automated email from the ASF dual-hosted git repository.

adoroszlai pushed a commit to branch HDDS-4440-s3-performance
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/HDDS-4440-s3-performance by 
this push:
     new c9442d2  HDDS-5778. Client side unit tests (#2810)
c9442d2 is described below

commit c9442d2507173069ca8756e2fc5d804daf5687d5
Author: GeorgeJahad <[email protected]>
AuthorDate: Wed Dec 1 12:22:30 2021 -0800

    HDDS-5778. Client side unit tests (#2810)
    
    Co-authored-by: Neil Joshi <[email protected]>
---
 .../org/apache/hadoop/ozone/s3/TestUgiFilter.java  | 236 +++++++++++++++++++++
 1 file changed, 236 insertions(+)

diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/TestUgiFilter.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/TestUgiFilter.java
new file mode 100644
index 0000000..6a07fda
--- /dev/null
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/TestUgiFilter.java
@@ -0,0 +1,236 @@
+/*
+ * 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.hadoop.ozone.s3;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import java.time.LocalDate;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
+
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.ozone.s3.signature.*;
+import org.apache.hadoop.ozone.s3.exception.OS3Exception;
+
+import org.apache.hadoop.io.Text;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import static 
org.apache.hadoop.ozone.s3.signature.SignatureProcessor.DATE_FORMATTER;
+
+/**
+ * Test class for @{@link UgiFilter}.
+ */
+public class TestUgiFilter {
+
+  private OzoneConfiguration conf;
+  private Text omService;
+  private String curDate;
+  private Map<String, String> headers;
+  private Map<String, String[]> parameters;
+  private UgiFilter filter;
+  private HttpServletRequest request;
+  private HttpServletResponse response;
+  private FilterChain filterChain;
+  private FilterConfig filterConfig;
+
+  private static final String HOST_HEADER = "Host";
+  private static final String ENCODE_HEADER = "Accept-Encoding";
+  private static final String USER_AGENT_HEADER = "User-Agent";
+  private static final String DATE_HEADER = "X-Amz-Date";
+  private static final String ENCRYPT_TYPE_HEADER = "X-Amz-Content-SHA256";
+  private static final String AUTHORIZATION_HEADER = "Authorization";
+  private static final String LENGTH_HEADER = "Content-Length";
+  private static final String USER_STRING = "AKIAIIIE56NH5ZHKLTWQ";
+
+  @Before
+  public void setup() {
+    conf = new OzoneConfiguration();
+    String s3HttpAddr = "localhost:9878";
+    conf.set(S3GatewayConfigKeys.OZONE_S3G_HTTP_ADDRESS_KEY, s3HttpAddr);
+    s3HttpAddr = s3HttpAddr.substring(0, s3HttpAddr.lastIndexOf(":"));
+    conf.set(S3GatewayConfigKeys.OZONE_S3G_DOMAIN_NAME, s3HttpAddr);
+    omService = new Text("127.0.0.1:9862");
+    LocalDate now = LocalDate.now();
+    curDate = DATE_FORMATTER.format(now);
+
+    headers = new HashMap<>();
+    parameters = new HashMap<>();
+
+    headers.put(HOST_HEADER, "localhost:9878");
+    headers.put(ENCODE_HEADER, "identity");
+    headers.put(USER_AGENT_HEADER, "aws-cli/2.1.29 "+
+        "Python/3.8.8 Linux/4.15.0-144-generic "+
+        "exe/x86_64.ubuntu.18 prompt/off "+
+        "command/s3api.create-bucket");
+    headers.put(DATE_HEADER, "20210616T195044Z");
+    headers.put(ENCRYPT_TYPE_HEADER,
+        "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
+    headers.put(AUTHORIZATION_HEADER, "AWS4-HMAC-SHA256 "+
+        "Credential=" + USER_STRING + "/20210616/us-east-1/s3/aws4_request, "+
+        "SignedHeaders=host;x-amz-content-sha256;x-amz-date, "+
+        "Signature=c29b4c46e825d5df56cdde12a61adfa65560a54"+
+        "7c8973b9809621086727a2f2e");
+    headers.put(LENGTH_HEADER, "0");
+  }
+
+  private void createMocks() {
+    filter = new UgiFilter();
+    filter.setOzoneConfiguration(this.conf);
+    filter.setOmService(this.omService);
+
+    request = Mockito.mock(HttpServletRequest.class);
+    response = Mockito.mock(HttpServletResponse.class);
+    filterChain = Mockito.mock(FilterChain.class);
+    filterConfig = Mockito.mock(FilterConfig.class);
+
+    Mockito.when(request.getScheme()).thenReturn("http");
+    Mockito.when(request.getMethod()).thenReturn("PUT");
+    Mockito.when(request.getPathInfo()).thenReturn("/bucket1");
+    Mockito.when(request.getHeaderNames()).thenAnswer(
+        invocation -> Collections.enumeration(headers.keySet()));
+    Mockito.when(request.getHeader(HOST_HEADER)).thenReturn(
+        headers.get(HOST_HEADER));
+    Mockito.when(request.getHeader(ENCODE_HEADER)).thenReturn(
+        headers.get(ENCODE_HEADER));
+    Mockito.when(request.getHeader(USER_AGENT_HEADER)).thenReturn(
+        headers.get(USER_AGENT_HEADER));
+    Mockito.when(request.getHeader(DATE_HEADER)).thenReturn(
+        headers.get(DATE_HEADER));
+    Mockito.when(request.getHeader(ENCRYPT_TYPE_HEADER)).thenReturn(
+        headers.get(ENCRYPT_TYPE_HEADER));
+    Mockito.when(request.getHeader(AUTHORIZATION_HEADER)).thenAnswer(
+        invocation -> headers.get(AUTHORIZATION_HEADER));
+    Mockito.when(request.getHeader(LENGTH_HEADER)).thenReturn(
+        headers.get(LENGTH_HEADER));
+    Mockito.when(request.getParameterMap()).thenReturn(parameters);
+
+    // correct date in authorization header for AuthorizationV4QueryParser
+    // date validator
+    headers.put(AUTHORIZATION_HEADER, headers.
+        get(AUTHORIZATION_HEADER).replace("20210616", curDate));
+
+  }
+
+  @Test
+  public void testUgiFilterDoFilterBadDate() {
+    createMocks();
+    // set incorrect date in authorization header
+    headers.put(AUTHORIZATION_HEADER, headers.
+        get(AUTHORIZATION_HEADER).replace(curDate, "20210616"));
+
+    // Should generate exception because of incorrect date
+    try {
+      filter.init(filterConfig);
+      filter.doFilter(request, response, filterChain);
+      filter.destroy();
+      Assert.fail("Filter should generate OS3 exception.");
+    } catch(Exception e) {
+      Assert.assertTrue(e.getCause() instanceof OS3Exception);
+    }
+  }
+
+  @Test
+  public void testUgiFilterDoFilterGoodDate() {
+    createMocks();
+    // Should not generate exception
+    try {
+      filter.init(filterConfig);
+      filter.doFilter(request, response, filterChain);
+      filter.destroy();
+      // keep Findbugs happy
+      
//http://findbugs.sourceforge.net/bugDescriptions.html#REC_CATCH_EXCEPTION
+    } catch(RuntimeException e) {
+      Assert.fail("Filter should not generate any exceptions.");
+    } catch(Exception e) {
+      Assert.fail("Filter should not generate any exceptions.");
+    }
+  }
+
+  @Test
+  public void testUgiFilterDoFilterBadAwsVersion() {
+    createMocks();
+    // Should generate exception because aws version unrecognized
+    //  by any signature parser
+    headers.put(AUTHORIZATION_HEADER, headers.
+        get(AUTHORIZATION_HEADER).replace("AWS4", "AWS3"));
+    try {
+      filter.init(filterConfig);
+      filter.doFilter(request, response, filterChain);
+      filter.destroy();
+      Assert.fail("Filter should generate OS3 exception.");
+    } catch(Exception e) {
+      Assert.assertTrue(e.getCause().getCause() instanceof OS3Exception);
+    }
+  }
+
+  @Test
+  public void testUgiFilterDoFilterEmptyUser() {
+    createMocks();
+    // Should generate exception because user is empty
+    headers.put(AUTHORIZATION_HEADER, headers.
+        get(AUTHORIZATION_HEADER).replace(USER_STRING, ""));
+    try {
+      filter.init(filterConfig);
+      filter.doFilter(request, response, filterChain);
+      filter.destroy();
+      Assert.fail("Filter should generate OS3 exception.");
+    } catch(Exception e) {
+      Assert.assertTrue(e.getCause() instanceof OS3Exception);
+    }
+
+  }
+
+  @Test
+  public void testUgiFilterStringToSign() throws Exception {
+    // test to ensure http servlet request is parsed correctly for
+    // aws authentication - testing creating aws v4 stringToSign
+
+    final SignatureInfo signatureInfo =
+        new AuthorizationV4HeaderParser(headers.get(AUTHORIZATION_HEADER),
+            headers.get(DATE_HEADER)) {
+          @Override
+          public void validateDateRange(Credential credentialObj) {
+            //NOOP
+          }
+        }.parseSignature();
+
+    String stringToSign =
+        StringToSignProducer.createSignatureBase(signatureInfo,
+            "http",
+            "PUT",
+            "/bucket1",
+            AWSSignatureProcessor.LowerCaseKeyStringMap.fromHeaderMap(headers),
+            StringToSignProducer.fromMultiValueToSingleValueMap(
+                parameters));
+
+    Assert.assertEquals(
+        "String to sign is invalid",
+        "AWS4-HMAC-SHA256\n"+
+            "20210616T195044Z\n"+
+            "20210616/us-east-1/s3/aws4_request\n"+
+            "7bed78b44380d69656995a5050761f6b88ee6ed9d8b6199e467b83ef931bae7b",
+        stringToSign);
+  }
+}
\ No newline at end of file

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to