PageRenderTime 43ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/openid-connect-server/src/test/java/org/mitre/oauth2/service/impl/TestDefaultIntrospectionResultAssembler.java

http://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server
Java | 362 lines | 239 code | 80 blank | 43 comment | 0 complexity | 18f8c391c318cb487b5f1f8d93ccf943 MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright 2018 The MIT Internet Trust Consortium
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *******************************************************************************/
  16. package org.mitre.oauth2.service.impl;
  17. import static com.google.common.collect.Sets.newHashSet;
  18. import static org.mockito.BDDMockito.given;
  19. import java.text.ParseException;
  20. import java.text.SimpleDateFormat;
  21. import java.util.Date;
  22. import java.util.Map;
  23. import java.util.Set;
  24. import javax.swing.text.DateFormatter;
  25. import org.junit.Test;
  26. import org.mitre.oauth2.model.OAuth2AccessTokenEntity;
  27. import org.mitre.oauth2.model.OAuth2RefreshTokenEntity;
  28. import org.mitre.oauth2.service.IntrospectionResultAssembler;
  29. import org.mitre.openid.connect.model.UserInfo;
  30. import org.mitre.uma.model.Permission;
  31. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  32. import org.springframework.security.core.Authentication;
  33. import org.springframework.security.oauth2.provider.OAuth2Authentication;
  34. import org.springframework.security.oauth2.provider.OAuth2Request;
  35. import com.google.common.collect.ImmutableMap;
  36. import com.google.common.collect.ImmutableSet;
  37. import static org.hamcrest.CoreMatchers.equalTo;
  38. import static org.hamcrest.CoreMatchers.is;
  39. import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
  40. import static org.mockito.Mockito.mock;
  41. import static org.junit.Assert.assertThat;
  42. public class TestDefaultIntrospectionResultAssembler {
  43. private IntrospectionResultAssembler assembler = new DefaultIntrospectionResultAssembler();
  44. private static DateFormatter dateFormat = new DateFormatter(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"));
  45. @Test
  46. public void shouldAssembleExpectedResultForAccessToken() throws ParseException {
  47. // given
  48. OAuth2AccessTokenEntity accessToken = accessToken(new Date(123 * 1000L), scopes("foo", "bar"), null, "Bearer",
  49. oauth2AuthenticationWithUser(oauth2Request("clientId"), "name"));
  50. UserInfo userInfo = userInfo("sub");
  51. Set<String> authScopes = scopes("foo", "bar", "baz");
  52. // when
  53. Map<String, Object> result = assembler.assembleFrom(accessToken, userInfo, authScopes);
  54. // then
  55. Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
  56. .put("sub", "sub")
  57. .put("exp", 123L)
  58. .put("expires_at", dateFormat.valueToString(new Date(123 * 1000L)))
  59. .put("scope", "bar foo")
  60. .put("active", Boolean.TRUE)
  61. .put("user_id", "name")
  62. .put("client_id", "clientId")
  63. .put("token_type", "Bearer")
  64. .build();
  65. assertThat(result, is(equalTo(expected)));
  66. }
  67. @Test
  68. public void shouldAssembleExpectedResultForAccessToken_withPermissions() throws ParseException {
  69. // given
  70. OAuth2AccessTokenEntity accessToken = accessToken(new Date(123 * 1000L), scopes("foo", "bar"),
  71. permissions(permission(1L, "foo", "bar")),
  72. "Bearer", oauth2AuthenticationWithUser(oauth2Request("clientId"), "name"));
  73. UserInfo userInfo = userInfo("sub");
  74. Set<String> authScopes = scopes("foo", "bar", "baz");
  75. // when
  76. Map<String, Object> result = assembler.assembleFrom(accessToken, userInfo, authScopes);
  77. // then
  78. Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
  79. .put("sub", "sub")
  80. .put("exp", 123L)
  81. .put("expires_at", dateFormat.valueToString(new Date(123 * 1000L)))
  82. .put("permissions", new ImmutableSet.Builder<>()
  83. .add(new ImmutableMap.Builder<String, Object>()
  84. .put("resource_set_id", "1") // note that the resource ID comes out as a string
  85. .put("scopes", new ImmutableSet.Builder<>()
  86. .add("bar")
  87. .add("foo")
  88. .build())
  89. .build())
  90. .build())
  91. // note that scopes are not included if permissions are included
  92. .put("active", Boolean.TRUE)
  93. .put("user_id", "name")
  94. .put("client_id", "clientId")
  95. .put("token_type", "Bearer")
  96. .build();
  97. assertThat(result, is(equalTo(expected)));
  98. }
  99. @Test
  100. public void shouldAssembleExpectedResultForAccessTokenWithoutUserInfo() throws ParseException {
  101. // given
  102. OAuth2AccessTokenEntity accessToken = accessToken(new Date(123 * 1000L), scopes("foo", "bar"), null, "Bearer",
  103. oauth2AuthenticationWithUser(oauth2Request("clientId"), "name"));
  104. Set<String> authScopes = scopes("foo", "bar", "baz");
  105. // when
  106. Map<String, Object> result = assembler.assembleFrom(accessToken, null, authScopes);
  107. // then
  108. Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
  109. .put("sub", "name")
  110. .put("exp", 123L)
  111. .put("expires_at", dateFormat.valueToString(new Date(123 * 1000L)))
  112. .put("scope", "bar foo")
  113. .put("active", Boolean.TRUE)
  114. .put("user_id", "name")
  115. .put("client_id", "clientId")
  116. .put("token_type", "Bearer")
  117. .build();
  118. assertThat(result, is(equalTo(expected)));
  119. }
  120. @Test
  121. public void shouldAssembleExpectedResultForAccessTokenWithoutExpiry() {
  122. // given
  123. OAuth2AccessTokenEntity accessToken = accessToken(null, scopes("foo", "bar"), null, "Bearer",
  124. oauth2AuthenticationWithUser(oauth2Request("clientId"), "name"));
  125. UserInfo userInfo = userInfo("sub");
  126. Set<String> authScopes = scopes("foo", "bar", "baz");
  127. // when
  128. Map<String, Object> result = assembler.assembleFrom(accessToken, userInfo, authScopes);
  129. // then
  130. Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
  131. .put("sub", "sub")
  132. .put("scope", "bar foo")
  133. .put("active", Boolean.TRUE)
  134. .put("user_id", "name")
  135. .put("client_id", "clientId")
  136. .put("token_type", "Bearer")
  137. .build();
  138. assertThat(result, is(equalTo(expected)));
  139. }
  140. @Test
  141. public void shouldAssembleExpectedResultForAccessTokenWithoutUserAuthentication() throws ParseException {
  142. // given
  143. OAuth2AccessTokenEntity accessToken = accessToken(new Date(123 * 1000L), scopes("foo", "bar"), null, "Bearer",
  144. oauth2Authentication(oauth2Request("clientId"), null));
  145. Set<String> authScopes = scopes("foo", "bar", "baz");
  146. // when
  147. Map<String, Object> result = assembler.assembleFrom(accessToken, null, authScopes);
  148. // then `user_id` should not be present
  149. Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
  150. .put("sub", "clientId")
  151. .put("exp", 123L)
  152. .put("expires_at", dateFormat.valueToString(new Date(123 * 1000L)))
  153. .put("scope", "bar foo")
  154. .put("active", Boolean.TRUE)
  155. .put("client_id", "clientId")
  156. .put("token_type", "Bearer")
  157. .build();
  158. assertThat(result, is(equalTo(expected)));
  159. }
  160. @Test
  161. public void shouldAssembleExpectedResultForRefreshToken() throws ParseException {
  162. // given
  163. OAuth2RefreshTokenEntity refreshToken = refreshToken(new Date(123 * 1000L),
  164. oauth2AuthenticationWithUser(oauth2Request("clientId", scopes("foo", "bar")), "name"));
  165. UserInfo userInfo = userInfo("sub");
  166. Set<String> authScopes = scopes("foo", "bar", "baz");
  167. // when
  168. Map<String, Object> result = assembler.assembleFrom(refreshToken, userInfo, authScopes);
  169. // then
  170. Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
  171. .put("sub", "sub")
  172. .put("exp", 123L)
  173. .put("expires_at", dateFormat.valueToString(new Date(123 * 1000L)))
  174. .put("scope", "bar foo")
  175. .put("active", Boolean.TRUE)
  176. .put("user_id", "name")
  177. .put("client_id", "clientId")
  178. .build();
  179. assertThat(result, is(equalTo(expected)));
  180. }
  181. @Test
  182. public void shouldAssembleExpectedResultForRefreshTokenWithoutUserInfo() throws ParseException {
  183. // given
  184. OAuth2RefreshTokenEntity refreshToken = refreshToken(new Date(123 * 1000L),
  185. oauth2AuthenticationWithUser(oauth2Request("clientId", scopes("foo", "bar")), "name"));
  186. Set<String> authScopes = scopes("foo", "bar", "baz");
  187. // when
  188. Map<String, Object> result = assembler.assembleFrom(refreshToken, null, authScopes);
  189. // then
  190. Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
  191. .put("sub", "name")
  192. .put("exp", 123L)
  193. .put("expires_at", dateFormat.valueToString(new Date(123 * 1000L)))
  194. .put("scope", "bar foo")
  195. .put("active", Boolean.TRUE)
  196. .put("user_id", "name")
  197. .put("client_id", "clientId")
  198. .build();
  199. assertThat(result, is(equalTo(expected)));
  200. }
  201. @Test
  202. public void shouldAssembleExpectedResultForRefreshTokenWithoutExpiry() {
  203. // given
  204. OAuth2RefreshTokenEntity refreshToken = refreshToken(null,
  205. oauth2AuthenticationWithUser(oauth2Request("clientId", scopes("foo", "bar")), "name"));
  206. UserInfo userInfo = userInfo("sub");
  207. Set<String> authScopes = scopes("foo", "bar", "baz");
  208. // when
  209. Map<String, Object> result = assembler.assembleFrom(refreshToken, userInfo, authScopes);
  210. // then
  211. Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
  212. .put("sub", "sub")
  213. .put("scope", "bar foo")
  214. .put("active", Boolean.TRUE)
  215. .put("user_id", "name")
  216. .put("client_id", "clientId")
  217. .build();
  218. assertThat(result, is(equalTo(expected)));
  219. }
  220. @Test
  221. public void shouldAssembleExpectedResultForRefreshTokenWithoutUserAuthentication() throws ParseException {
  222. // given
  223. OAuth2RefreshTokenEntity refreshToken = refreshToken(null,
  224. oauth2Authentication(oauth2Request("clientId", scopes("foo", "bar")), null));
  225. Set<String> authScopes = scopes("foo", "bar", "baz");
  226. // when
  227. Map<String, Object> result = assembler.assembleFrom(refreshToken, null, authScopes);
  228. // then `user_id` should not be present
  229. Map<String, Object> expected = new ImmutableMap.Builder<String, Object>()
  230. .put("sub", "clientId")
  231. .put("scope", "bar foo")
  232. .put("active", Boolean.TRUE)
  233. .put("client_id", "clientId")
  234. .build();
  235. assertThat(result, is(equalTo(expected)));
  236. }
  237. private UserInfo userInfo(String sub) {
  238. UserInfo userInfo = mock(UserInfo.class);
  239. given(userInfo.getSub()).willReturn(sub);
  240. return userInfo;
  241. }
  242. private OAuth2AccessTokenEntity accessToken(Date exp, Set<String> scopes, Set<Permission> permissions, String tokenType, OAuth2Authentication authentication) {
  243. OAuth2AccessTokenEntity accessToken = mock(OAuth2AccessTokenEntity.class, RETURNS_DEEP_STUBS);
  244. given(accessToken.getExpiration()).willReturn(exp);
  245. given(accessToken.getScope()).willReturn(scopes);
  246. given(accessToken.getPermissions()).willReturn(permissions);
  247. given(accessToken.getTokenType()).willReturn(tokenType);
  248. given(accessToken.getAuthenticationHolder().getAuthentication()).willReturn(authentication);
  249. return accessToken;
  250. }
  251. private OAuth2RefreshTokenEntity refreshToken(Date exp, OAuth2Authentication authentication) {
  252. OAuth2RefreshTokenEntity refreshToken = mock(OAuth2RefreshTokenEntity.class, RETURNS_DEEP_STUBS);
  253. given(refreshToken.getExpiration()).willReturn(exp);
  254. given(refreshToken.getAuthenticationHolder().getAuthentication()).willReturn(authentication);
  255. return refreshToken;
  256. }
  257. private OAuth2Authentication oauth2AuthenticationWithUser(OAuth2Request request, String username) {
  258. UsernamePasswordAuthenticationToken userAuthentication = new UsernamePasswordAuthenticationToken(username, "somepassword");
  259. return oauth2Authentication(request, userAuthentication);
  260. }
  261. private OAuth2Authentication oauth2Authentication(OAuth2Request request, Authentication userAuthentication) {
  262. return new OAuth2Authentication(request, userAuthentication);
  263. }
  264. private OAuth2Request oauth2Request(String clientId) {
  265. return oauth2Request(clientId, null);
  266. }
  267. private OAuth2Request oauth2Request(String clientId, Set<String> scopes) {
  268. return new OAuth2Request(null, clientId, null, true, scopes, null, null, null, null);
  269. }
  270. private Set<String> scopes(String... scopes) {
  271. return newHashSet(scopes);
  272. }
  273. private Set<Permission> permissions(Permission... permissions) {
  274. return newHashSet(permissions);
  275. }
  276. private Permission permission(Long resourceSetId, String... scopes) {
  277. Permission permission = mock(Permission.class, RETURNS_DEEP_STUBS);
  278. given(permission.getResourceSet().getId()).willReturn(resourceSetId);
  279. given(permission.getScopes()).willReturn(scopes(scopes));
  280. return permission;
  281. }
  282. }