2 * ============LICENSE_START=======================================================
3 * ONAP : ccsdk features
4 * ================================================================================
5 * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.ccsdk.features.sdnr.wt.oauthprovider.test;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
27 import static org.mockito.Mockito.mock;
28 import static org.mockito.Mockito.when;
29 import com.auth0.jwt.interfaces.DecodedJWT;
30 import java.io.IOException;
31 import java.util.Arrays;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.function.Supplier;
36 import org.apache.shiro.authc.AuthenticationException;
37 import org.apache.shiro.authc.AuthenticationInfo;
38 import org.apache.shiro.authc.AuthenticationToken;
39 import org.apache.shiro.authc.BearerToken;
40 import org.apache.shiro.authc.UsernamePasswordToken;
41 import org.apache.shiro.authz.AuthorizationInfo;
42 import org.apache.shiro.subject.PrincipalCollection;
43 import org.junit.BeforeClass;
44 import org.junit.Test;
45 import org.onap.ccsdk.features.sdnr.wt.oauthprovider.OAuth2Realm;
46 import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config;
47 import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.UserTokenPayload;
48 import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.AuthService;
49 import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator;
50 import org.opendaylight.aaa.api.Authentication;
51 import org.opendaylight.aaa.api.AuthenticationService;
52 import org.opendaylight.aaa.api.TokenStore;
53 import org.opendaylight.aaa.api.shiro.principal.ODLPrincipal;
54 import org.opendaylight.aaa.shiro.realm.TokenAuthRealm;
55 import org.opendaylight.aaa.tokenauthrealm.auth.AuthenticationManager;
56 import org.opendaylight.aaa.tokenauthrealm.auth.TokenAuthenticators;
57 import org.opendaylight.mdsal.binding.api.DataBroker;
59 public class TestRealm {
61 private static OAuth2RealmToTest realm;
62 private static TokenCreator tokenCreator;
64 private static final AuthenticationManager authManager = new AuthenticationManager();
65 private static final TokenAuthenticators tokenAuth = new TokenAuthenticators();
67 private static final TokenStore tokenStore = new TokenStore(){
70 public void put(String token, Authentication auth) {
75 public Authentication get(String token) {
80 public boolean delete(String token) {
85 public long tokenExpiration() {
90 public static void init() throws IllegalArgumentException, Exception {
91 TokenAuthRealm.prepareForLoad(authManager,tokenAuth,tokenStore);
93 Config config = Config.getInstance(TestConfig.TEST_CONFIG_FILENAME);
94 tokenCreator = TokenCreator.getInstance(config);
95 realm = new OAuth2RealmToTest();
96 } catch (IOException e) {
103 public void testTokenSupport() {
104 assertTrue(realm.supports(new UsernamePasswordToken()));
105 assertTrue(realm.supports(new BearerToken("")));
110 public void testAuthorizationInfo() {
111 //bearer token use case
112 PrincipalCollection c = mock(PrincipalCollection.class);
113 final List<String> roles = Arrays.asList("admin", "provision");
114 UserTokenPayload userData = createUserData("", roles);
116 DecodedJWT decodedJwt = tokenCreator.verify(tokenCreator.createNewJWT(userData).getToken());
117 when(c.getPrimaryPrincipal()).thenReturn(decodedJwt);
119 AuthorizationInfo ai = realm.doGetAuthorizationInfo(c);
120 for (String role : roles) {
121 assertTrue(ai.getRoles().contains(role));
123 assertEquals(roles.size(), ai.getRoles().size());
125 ODLPrincipal principal = mock(ODLPrincipal.class);
126 when(principal.getRoles()).thenReturn(new HashSet<String>(roles));
127 PrincipalCollection c2 = mock(PrincipalCollection.class);
128 when(c2.getPrimaryPrincipal()).thenReturn(principal);
129 ai = realm.doGetAuthorizationInfo(c2);
130 for (String role : roles) {
131 assertTrue(ai.getRoles().contains(role));
133 assertEquals(roles.size(), ai.getRoles().size());
138 public void testUrlTrimming(){
139 final String internalUrl="https://test.identity.onap:49333";
140 final String externalUrl="https://test.identity.onap:49333";
141 final String testUrl1 = "/my/token/endpoint";
142 final String testUrl2 = internalUrl+testUrl1;
143 final String testUrl3 = externalUrl+testUrl1;
145 assertEquals(testUrl1, AuthService.trimUrl(internalUrl, testUrl1));
146 assertEquals(testUrl1, AuthService.trimUrl(internalUrl, testUrl2));
147 assertEquals(testUrl1, AuthService.trimUrl(externalUrl, testUrl3));
149 assertEquals(testUrl2, AuthService.extendUrl(internalUrl, testUrl3));
155 public void testAssertCredentialsMatch() {
156 //bearer token use case
157 UserTokenPayload userData = createUserData("", Arrays.asList("admin", "provision"));
158 AuthenticationToken atoken = new BearerToken(tokenCreator.createNewJWT(userData).getToken());
159 AuthenticationInfo ai = null;
161 realm.assertCredentialsMatch(atoken, ai);
162 } catch (AuthenticationException e) {
163 fail(e.getMessage());
166 atoken = new UsernamePasswordToken("admin", "admin");
168 realm.assertCredentialsMatch(atoken, ai);
169 } catch (AuthenticationException e) {
170 fail(e.getMessage());
175 public void testAuthenticationInfo() {
176 //bearer token use case
177 UserTokenPayload userData = createUserData("", Arrays.asList("admin", "provision"));
178 AuthenticationToken atoken = new BearerToken(tokenCreator.createNewJWT(userData).getToken());
179 AuthenticationInfo ai = null;
181 ai = realm.doGetAuthenticationInfo(atoken);
182 } catch (AuthenticationException e) {
183 fail(e.getMessage());
187 atoken = new UsernamePasswordToken("admin", "admin");
189 ai = realm.doGetAuthenticationInfo(atoken);
190 } catch (AuthenticationException e) {
191 fail(e.getMessage());
195 private static UserTokenPayload createUserData(String username, List<String> roles) {
196 UserTokenPayload userData = new UserTokenPayload();
197 userData.setExp(tokenCreator.getDefaultExp());
198 userData.setFamilyName("");
199 userData.setGivenName("");
200 userData.setPreferredUsername(username);
201 userData.setRoles(roles);
205 public static class OAuth2RealmToTest extends OAuth2Realm {
207 public OAuth2RealmToTest() throws IllegalArgumentException, Exception {
212 public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg) {
213 return super.doGetAuthorizationInfo(arg);
217 public void assertCredentialsMatch(AuthenticationToken atoken, AuthenticationInfo ai)
218 throws AuthenticationException {
219 super.assertCredentialsMatch(atoken, ai);
223 public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
224 return super.doGetAuthenticationInfo(token);