org.janusgraph.graphdb.tinkerpop.gremlin.server.handler.HttpHMACAuthenticationHandlerTest.java Source code

Java tutorial

Introduction

Here is the source code for org.janusgraph.graphdb.tinkerpop.gremlin.server.handler.HttpHMACAuthenticationHandlerTest.java

Source

// Copyright 2017 JanusGraph Authors
//
// Licensed 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.janusgraph.graphdb.tinkerpop.gremlin.server.handler;

import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpResponseStatus.UNAUTHORIZED;
import static org.easymock.EasyMock.and;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.isA;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.util.Base64;
import java.util.Map;

import org.apache.tinkerpop.gremlin.server.auth.AuthenticatedUser;
import org.apache.tinkerpop.gremlin.server.auth.Authenticator;
import org.easymock.Capture;
import org.easymock.CaptureType;
import org.easymock.EasyMock;
import org.easymock.EasyMockSupport;
import org.easymock.IArgumentMatcher;
import org.junit.jupiter.api.Test;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpResponseStatus;

public class HttpHMACAuthenticationHandlerTest extends EasyMockSupport {

    @Test
    public void testChannelReadBasicAuthNoAuthHeader() {
        final ChannelHandlerContext ctx = createMock(ChannelHandlerContext.class);
        final FullHttpRequest msg = createMock(FullHttpRequest.class);
        final HttpHeaders headers = createMock(HttpHeaders.class);
        final Authenticator authenticator = createMock(Authenticator.class);
        final ChannelFuture cf = createMock(ChannelFuture.class);

        expect(msg.getMethod()).andReturn(HttpMethod.POST);
        expect(msg.headers()).andReturn(headers).anyTimes();
        expect(headers.get(eq("Authorization"))).andReturn(null);
        expect(ctx.writeAndFlush(eqHttpStatus(UNAUTHORIZED))).andReturn(cf);
        expect(cf.addListener(ChannelFutureListener.CLOSE)).andReturn(null);
        expect(msg.release()).andReturn(false);
        HttpHMACAuthenticationHandler handler = new HttpHMACAuthenticationHandler(authenticator);
        replayAll();
        handler.channelRead(ctx, (Object) msg);
        verifyAll();
    }

    @Test
    public void testChannelReadBasicAuthIncorrectScheme() {
        final ChannelHandlerContext ctx = createMock(ChannelHandlerContext.class);
        final FullHttpRequest msg = createMock(FullHttpRequest.class);
        final HttpHeaders headers = createMock(HttpHeaders.class);
        final Authenticator authenticator = createMock(Authenticator.class);
        final ChannelFuture cf = createMock(ChannelFuture.class);

        expect(msg.getMethod()).andReturn(HttpMethod.POST);
        expect(msg.headers()).andReturn(headers).anyTimes();
        expect(headers.get("Authorization")).andReturn("bogus");
        expect(ctx.writeAndFlush(eqHttpStatus(UNAUTHORIZED))).andReturn(cf);
        expect(cf.addListener(ChannelFutureListener.CLOSE)).andReturn(null);
        expect(msg.release()).andReturn(false);

        final HttpHMACAuthenticationHandler handler = new HttpHMACAuthenticationHandler(authenticator);
        replayAll();
        handler.channelRead(ctx, (Object) msg);
        verifyAll();
    }

    @Test
    public void testChannelReadBasicAuth() throws Exception {
        final ChannelHandlerContext ctx = createMock(ChannelHandlerContext.class);
        final FullHttpRequest msg = createMock(FullHttpRequest.class);
        final HttpHeaders headers = createMock(HttpHeaders.class);
        final Authenticator authenticator = createMock(Authenticator.class);
        final String encodedUserNameAndPass = Base64.getEncoder().encodeToString("user:pass".getBytes());
        expect(msg.getMethod()).andReturn(HttpMethod.POST);
        expect(msg.headers()).andReturn(headers).anyTimes();
        expect(msg.getUri()).andReturn("/");
        expect(headers.get(eq("Authorization"))).andReturn("Basic " + encodedUserNameAndPass);
        expect(ctx.fireChannelRead(isA(FullHttpRequest.class))).andReturn(ctx);
        expect(authenticator.authenticate(isA(Map.class))).andReturn(new AuthenticatedUser("foo"));
        final HttpHMACAuthenticationHandler handler = new HttpHMACAuthenticationHandler(authenticator);
        replayAll();
        handler.channelRead(ctx, (Object) msg);
        verifyAll();
    }

    @Test
    public void testChannelReadGetAuthToken() throws Exception {
        final ChannelHandlerContext ctx = createMock(ChannelHandlerContext.class);
        final FullHttpRequest msg = createMock(FullHttpRequest.class);
        final HttpHeaders headers = createMock(HttpHeaders.class);
        final Authenticator authenticator = createMock(Authenticator.class);
        final ChannelFuture cf = createMock(ChannelFuture.class);
        final String encodedUserNameAndPass = Base64.getEncoder().encodeToString("user:pass".getBytes());
        final Capture<Map<String, String>> credMap = EasyMock.newCapture(CaptureType.ALL);
        expect(msg.getMethod()).andReturn(HttpMethod.GET);
        expect(msg.headers()).andReturn(headers).anyTimes();
        expect(msg.getUri()).andReturn("/session");
        expect(headers.get(eq("Authorization"))).andReturn("Basic " + encodedUserNameAndPass);
        expect(authenticator.authenticate(and(isA(Map.class), capture(credMap))))
                .andReturn(new AuthenticatedUser("foo"));
        expect(ctx.writeAndFlush(eqHttpStatus(OK))).andReturn(cf);
        expect(cf.addListener(ChannelFutureListener.CLOSE)).andReturn(null);
        expect(msg.release()).andReturn(false);
        final HttpHMACAuthenticationHandler handler = new HttpHMACAuthenticationHandler(authenticator);
        replayAll();
        handler.channelRead(ctx, (Object) msg);
        verifyAll();
        assertNotNull(credMap.getValue().get(HttpHMACAuthenticationHandler.PROPERTY_GENERATE_TOKEN));
    }

    @Test
    public void testChannelReadTokenAuth() throws Exception {
        final ChannelHandlerContext ctx = createMock(ChannelHandlerContext.class);
        final FullHttpRequest msg = createMock(FullHttpRequest.class);
        final HttpHeaders headers = createMock(HttpHeaders.class);
        final Authenticator authenticator = createMock(Authenticator.class);
        final String encodedToken = Base64.getEncoder().encodeToString("askdjhf823asdlkfsasd".getBytes());
        expect(msg.getMethod()).andReturn(HttpMethod.GET);
        expect(msg.headers()).andReturn(headers).anyTimes();
        expect(msg.getUri()).andReturn("/");
        expect(headers.get(eq("Authorization"))).andReturn("Token " + encodedToken);
        expect(ctx.fireChannelRead(isA(FullHttpRequest.class))).andReturn(ctx);
        expect(authenticator.authenticate(isA(Map.class))).andReturn(new AuthenticatedUser("foo"));
        final HttpHMACAuthenticationHandler handler = new HttpHMACAuthenticationHandler(authenticator);
        replayAll();
        handler.channelRead(ctx, (Object) msg);
        verifyAll();
    }

    private static DefaultFullHttpResponse eqHttpStatus(HttpResponseStatus status) {
        EasyMock.reportMatcher(new WithCorrectHttpResponse(status));
        return null;
    }

    static class WithCorrectHttpResponse implements IArgumentMatcher {
        private HttpResponseStatus expected;

        public WithCorrectHttpResponse(HttpResponseStatus expected) {
            this.expected = expected;
        }

        public boolean matches(Object actual) {
            if (!(actual instanceof DefaultFullHttpResponse)) {
                return false;
            }
            return expected.equals(((DefaultFullHttpResponse) actual).getStatus());
        }

        public void appendTo(StringBuffer buffer) {
            buffer.append("eqHttpStatus(");
            buffer.append(expected.getClass().getName());
            buffer.append(" with status \"");
            buffer.append(expected.toString());
            buffer.append("\")");
        }
    }

}