Skip to content
This repository was archived by the owner on Jun 30, 2023. It is now read-only.

Commit 33c2e0f

Browse files
committed
support AuthLevel.REQUIRED annotation
It is currently not easy to support all AuthLevel modes, but REQUIRED is likely to be the the most used and easy to implement, so support is added here.
1 parent 058d3ad commit 33c2e0f

3 files changed

Lines changed: 86 additions & 8 deletions

File tree

endpoints-framework/src/main/java/com/google/api/server/spi/request/RestServletRequestParamReader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public RestServletRequestParamReader(EndpointMethod method,
5858
HttpServletRequest servletRequest, ServletContext servletContext,
5959
ApiSerializationConfig serializationConfig, ApiMethodConfig methodConfig,
6060
Map<String, String> rawPathParameters) {
61-
super(method, servletRequest, servletContext, serializationConfig);
61+
super(method, servletRequest, servletContext, serializationConfig, methodConfig);
6262
this.rawPathParameters = rawPathParameters;
6363
ImmutableMap.Builder<String, ApiParameterConfig> builder = ImmutableMap.builder();
6464
for (ApiParameterConfig config : methodConfig.getParameterConfigs()) {

endpoints-framework/src/main/java/com/google/api/server/spi/request/ServletRequestParamReader.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@
2020
import com.google.api.server.spi.IoUtil;
2121
import com.google.api.server.spi.ServiceException;
2222
import com.google.api.server.spi.auth.common.User;
23+
import com.google.api.server.spi.config.AuthLevel;
2324
import com.google.api.server.spi.config.Named;
2425
import com.google.api.server.spi.config.annotationreader.AnnotationUtil;
26+
import com.google.api.server.spi.config.model.ApiMethodConfig;
2527
import com.google.api.server.spi.config.model.ApiSerializationConfig;
2628
import com.google.api.server.spi.config.model.StandardParameters;
2729
import com.google.api.server.spi.response.BadRequestException;
30+
import com.google.api.server.spi.response.UnauthorizedException;
2831
import com.google.api.server.spi.types.DateAndTime;
2932
import com.google.api.server.spi.types.SimpleDate;
3033
import com.google.appengine.api.datastore.Blob;
@@ -135,6 +138,10 @@ protected Object[] deserializeParams(JsonNode node) throws IOException, IllegalA
135138
if (User.class.isAssignableFrom(clazz)) {
136139
// User type parameter requires no Named annotation (ignored if present)
137140
User user = getUser();
141+
if (user == null && methodConfig != null
142+
&& methodConfig.getAuthLevel() == AuthLevel.REQUIRED) {
143+
throw new UnauthorizedException("Valid user credentials are required.");
144+
}
138145
if (user == null || clazz.isAssignableFrom(user.getClass())) {
139146
params[i] = user;
140147
logger.log(Level.FINE, "deserialize: User injected into param[{0}]", i);
@@ -146,7 +153,12 @@ protected Object[] deserializeParams(JsonNode node) throws IOException, IllegalA
146153
}
147154
} else if (APPENGINE_USER_CLASS_NAME.equals(clazz.getName())) {
148155
// User type parameter requires no Named annotation (ignored if present)
149-
params[i] = getAppEngineUser();
156+
com.google.appengine.api.users.User appEngineUser = getAppEngineUser();
157+
if (appEngineUser == null && methodConfig != null
158+
&& methodConfig.getAuthLevel() == AuthLevel.REQUIRED) {
159+
throw new UnauthorizedException("Valid user credentials are required.");
160+
}
161+
params[i] = appEngineUser;
150162
logger.log(Level.FINE, "deserialize: App Engine User injected into param[{0}]", i);
151163
} else if (clazz == HttpServletRequest.class) {
152164
// HttpServletRequest type parameter requires no Named annotation (ignored if present)
@@ -279,11 +291,17 @@ public Blob deserialize(JsonParser jsonParser, DeserializationContext context)
279291
protected final HttpServletRequest servletRequest;
280292
private final ServletContext servletContext;
281293
protected final ObjectReader objectReader;
294+
protected final ApiMethodConfig methodConfig;
282295

283-
public ServletRequestParamReader(EndpointMethod method, HttpServletRequest servletRequest,
284-
ServletContext servletContext, ApiSerializationConfig serializationConfig) {
296+
public ServletRequestParamReader(
297+
EndpointMethod method,
298+
HttpServletRequest servletRequest,
299+
ServletContext servletContext,
300+
ApiSerializationConfig serializationConfig,
301+
ApiMethodConfig methodConfig) {
285302
super(method);
286303

304+
this.methodConfig = methodConfig;
287305
this.servletRequest = servletRequest;
288306
this.servletContext = servletContext;
289307

endpoints-framework/src/test/java/com/google/api/server/spi/request/ServletRequestParamReaderTest.java

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@
2525

2626
import com.google.api.server.spi.EndpointMethod;
2727
import com.google.api.server.spi.auth.common.User;
28+
import com.google.api.server.spi.config.AuthLevel;
2829
import com.google.api.server.spi.config.Named;
2930
import com.google.api.server.spi.config.Nullable;
31+
import com.google.api.server.spi.config.model.ApiMethodConfig;
32+
import com.google.api.server.spi.response.UnauthorizedException;
3033
import com.google.api.server.spi.testing.TestEndpoint;
3134
import com.google.api.server.spi.testing.TestEndpoint.Request;
3235
import com.google.api.server.spi.types.DateAndTime;
@@ -39,6 +42,7 @@
3942
import org.junit.Test;
4043
import org.junit.runner.RunWith;
4144
import org.mockito.Mock;
45+
import org.mockito.Mockito;
4246
import org.mockito.runners.MockitoJUnitRunner;
4347

4448
import java.io.ByteArrayInputStream;
@@ -640,7 +644,7 @@ public void user(TestUser user) {}
640644
final TestUser user = new TestUser("test");
641645
Method method = TestUserEndpoint.class.getDeclaredMethod("user", TestUser.class);
642646
ParamReader reader = new ServletRequestParamReader(
643-
EndpointMethod.create(method.getDeclaringClass(), method), request, context, null) {
647+
EndpointMethod.create(method.getDeclaringClass(), method), request, context, null, null) {
644648
@Override
645649
User getUser() {
646650
return user;
@@ -768,19 +772,75 @@ public void prettyPrint(@Named("prettyPrint") String prettyPrint) {}
768772
assertEquals(true, params[0]);
769773
}
770774

775+
@Test
776+
public void testUserInjectionThrowsExceptionIfRequired() throws Exception {
777+
@SuppressWarnings("unused")
778+
class TestUser {
779+
@SuppressWarnings("unused")
780+
public void getUser(User user) { }
781+
}
782+
ApiMethodConfig methodConfig = Mockito.mock(ApiMethodConfig.class);
783+
when(methodConfig.getAuthLevel()).thenReturn(AuthLevel.REQUIRED);
784+
methodConfig.setAuthLevel(AuthLevel.REQUIRED);
785+
try {
786+
Method method = TestUser.class.getDeclaredMethod("getUser", User.class);
787+
readParameters(
788+
"{}", EndpointMethod.create(method.getDeclaringClass(), method),
789+
methodConfig,
790+
null,
791+
null);
792+
fail("expected unauthorized method exception");
793+
} catch (UnauthorizedException ex) {
794+
// expected
795+
}
796+
}
797+
798+
@Test
799+
public void testAppEngineUserInjectionThrowsExceptionIfRequired() throws Exception {
800+
@SuppressWarnings("unused")
801+
class TestUser {
802+
@SuppressWarnings("unused")
803+
public void getUser(com.google.appengine.api.users.User user) { }
804+
}
805+
ApiMethodConfig methodConfig = Mockito.mock(ApiMethodConfig.class);
806+
when(methodConfig.getAuthLevel()).thenReturn(AuthLevel.REQUIRED);
807+
methodConfig.setAuthLevel(AuthLevel.REQUIRED);
808+
try {
809+
Method method = TestUser.class
810+
.getDeclaredMethod("getUser", com.google.appengine.api.users.User.class);
811+
readParameters(
812+
"{}",
813+
EndpointMethod.create(method.getDeclaringClass(), method),
814+
methodConfig,
815+
null,
816+
null);
817+
fail("expected unauthorized method exception");
818+
} catch (UnauthorizedException ex) {
819+
// expected
820+
}
821+
}
822+
771823
private Object[] readParameters(String input, Method method) throws Exception {
772824
return readParameters(input, EndpointMethod.create(method.getDeclaringClass(), method));
773825
}
774826

775827
private Object[] readParameters(final String input, EndpointMethod method) throws Exception {
776-
ParamReader reader = new ServletRequestParamReader(method, request, context, null) {
828+
return readParameters(input, method, null, USER, APP_ENGINE_USER);
829+
}
830+
831+
private Object[] readParameters(final String input, EndpointMethod method,
832+
ApiMethodConfig methodConfig, final User user,
833+
final com.google.appengine.api.users.User appEngineUser)
834+
throws Exception {
835+
ParamReader reader = new ServletRequestParamReader(
836+
method, request, context, null, methodConfig) {
777837
@Override
778838
User getUser() {
779-
return USER;
839+
return user;
780840
}
781841
@Override
782842
com.google.appengine.api.users.User getAppEngineUser() {
783-
return APP_ENGINE_USER;
843+
return appEngineUser;
784844
}
785845
};
786846
return readParameters(input, reader);

0 commit comments

Comments
 (0)