/** * Copyright (C) 2013-2015 all@code-story.net * * 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 net.codestory.http.annotations; import net.codestory.http.*; import net.codestory.http.filters.basic.BasicAuthFilter; import net.codestory.http.payload.Payload; import net.codestory.http.security.UsersList; import net.codestory.http.testhelpers.AbstractProdWebServerTest; import org.junit.Test; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.function.*; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; public class CustomAnnotationsTest extends AbstractProdWebServerTest { @Test public void around_annotation() { UsersList users = new UsersList.Builder() .addUser("user", "pwd") .addUser("dummy", "pwd") .build(); configure(routes -> routes .filter(new BasicAuthFilter("/", "realm", users)) .registerAroundAnnotation(DummyShallNotPass.class, (annotation, context, payloadSupplier) -> "dummy".equals(context.currentUser().name()) ? Payload.forbidden() : payloadSupplier.apply(context)) .add(new MyResource()) ); get("/").withAuthentication("user", "pwd").should().contain("Hello"); get("/").withAuthentication("dummy", "pwd").should().respond(403); } @Test public void after_annotation() { configure(routes -> routes .registerAfterAnnotation(Header.class, (annotation, context, payload) -> payload.withHeader(annotation.key(), annotation.value())) .add(new MyResource()) ); get("/").should().contain("Hello").haveHeader("theHeader", "theValue"); } @Test public void around_annotation_class() { UsersList users = new UsersList.Builder() .addUser("user", "pwd") .addUser("dummy", "pwd") .build(); configure(routes -> routes .filter(new BasicAuthFilter("/", "realm", users)) .registerAroundAnnotation(DummyShallNotPass.class, ShallNotPass.class) .add(new MyResource()) ); get("/").withAuthentication("user", "pwd").should().contain("Hello"); get("/").withAuthentication("dummy", "pwd").should().respond(403); } @Test public void after_annotation_class() { configure(routes -> routes .registerAfterAnnotation(Header.class, AddHeader.class) .add(new MyResource()) ); get("/").should().contain("Hello").haveHeader("theHeader", "theValue"); } public static class ShallNotPass implements ApplyAroundAnnotation<DummyShallNotPass> { @Override public Payload apply(DummyShallNotPass annotation, Context context, Function<Context, Payload> payloadSupplier) { return "dummy".equals(context.currentUser().name()) ? Payload.forbidden() : payloadSupplier.apply(context); } } public static class AddHeader implements ApplyAfterAnnotation<Header> { @Override public Payload apply(Header annotation, Context context, Payload payload) { return payload.withHeader(annotation.key(), annotation.value()); } } @Target(TYPE) @Retention(RUNTIME) @interface DummyShallNotPass { } @Target(METHOD) @Retention(RUNTIME) @interface Header { String key(); String value(); } @DummyShallNotPass static class MyResource { @Header(key = "theHeader", value = "theValue") @Get("/") public String hello() { return "Hello"; } } }