diff options
Diffstat (limited to 'sdnr/wt/oauth-provider/oauth-core/src/test')
26 files changed, 2658 insertions, 0 deletions
diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestAuthHttpServlet.java b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestAuthHttpServlet.java new file mode 100644 index 000000000..3e9205733 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestAuthHttpServlet.java @@ -0,0 +1,404 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.oauthprovider.test; + +import java.util.Set; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; +import org.junit.Ignore; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.google.common.util.concurrent.FluentFuture; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.jolokia.osgi.security.Authenticator; +import org.json.JSONArray; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.internal.matchers.Any; +import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPClient; +import org.onap.ccsdk.features.sdnr.wt.common.test.ServletOutputStreamToByteArrayOutputStream; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.CustomObjectMapper; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.InvalidConfigurationException; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OdlPolicy; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.UserTokenPayload; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.http.AuthHttpServlet; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.http.HeadersOnlyHttpServletRequest; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.test.helper.OdlJsonMapper; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.test.helper.OdlXmlMapper; +import org.opendaylight.aaa.api.Claim; +import org.opendaylight.aaa.api.IdMService; +import org.apache.shiro.authc.BearerToken; +import org.opendaylight.aaa.api.PasswordCredentialAuth; +import org.opendaylight.aaa.api.PasswordCredentials; +import org.opendaylight.aaa.shiro.web.env.AAAShiroWebEnvironment; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.ReadTransaction; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.aaa.app.config.rev170619.ShiroConfiguration; +import org.opendaylight.yang.gen.v1.urn.opendaylight.aaa.app.config.rev170619.ShiroConfigurationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.aaa.rev161214.HttpAuthorization; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.aaa.rev161214.http.authorization.Policies; +import org.opendaylight.yangtools.util.concurrent.FluentFutures; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + + +public class TestAuthHttpServlet { + + private static final String TESTCONFIGFILE = TestConfig.TEST_CONFIG_FILENAME; + private static final String TESTSHIROCONFIGFILE = "src/test/resources/aaa-app-config.test.xml"; + private static final String MDSALDYNAUTHFILENAME = "src/test/resources/mdsalDynAuthData.json"; + private static TestServlet servlet; + private static DataBroker dataBroker = loadDynamicMdsalAuthDataBroker(); + private static Authenticator odlAuthenticator = mock(Authenticator.class); + private static IdMService odlIdentityService = mock(IdMService.class); + private static PasswordCredentialAuth passwordCredentialAuth; + private static TokenCreator tokenCreator; +// private static final HttpServletRequest authreq = new HeadersOnlyHttpServletRequest( +// Map.of("Authorization", BaseHTTPClient.getAuthorizationHeaderValue("admin@sdn", "admin"))); + + @BeforeClass + public static void init() throws IllegalArgumentException, Exception { + + try { + Config config = createConfigFile(); + tokenCreator = TokenCreator.getInstance(config); + servlet = new TestServlet(); + } catch (IOException | InvalidConfigurationException e) { + fail(e.getMessage()); + } + servlet.setDataBroker(dataBroker); + passwordCredentialAuth = mock(PasswordCredentialAuth.class); + + servlet.setPasswordCredentialAuth(passwordCredentialAuth); + } + + private static DataBroker loadDynamicMdsalAuthDataBroker() { + DataBroker dataBroker = mock(DataBroker.class); + ReadTransaction rotx = mock(ReadTransaction.class); + InstanceIdentifier<Policies> iif = InstanceIdentifier.create(HttpAuthorization.class).child(Policies.class); + try { + when(rotx.read(LogicalDatastoreType.CONFIGURATION, iif)) + .thenReturn(loadDataBrokerFile(MDSALDYNAUTHFILENAME, Policies.class)); + } catch (IOException e) { + fail("problem init databroker read" + e.getMessage()); + } + when(dataBroker.newReadOnlyTransaction()).thenReturn(rotx); + return dataBroker; + } + + private static <T> FluentFuture<Optional<T>> loadDataBrokerFile(String fn, Class<T> clazz) throws IOException { + return FluentFutures.immediateFluentFuture(Optional.ofNullable(readJson(new File(fn), clazz))); + } + + private static ShiroConfiguration loadShiroConfig(String filename) + throws JsonParseException, JsonMappingException, IOException { + OdlXmlMapper mapper = new OdlXmlMapper(); + return mapper.readValue(new File(filename), ShiroConfigurationBuilder.class).build(); + } + + private static Config createConfigFile() throws IOException, InvalidConfigurationException { + return Config.getInstance(TESTCONFIGFILE); + + } + + @Test + public void testValidLoginRedirect() { + + HttpServletRequest req = mock(HttpServletRequest.class); + when(req.getRequestURI()).thenReturn("/oauth/login/keycloak"); + HttpServletResponse resp = mock(HttpServletResponse.class); + try { + servlet.doGet(req, resp); + } catch (ServletException | IOException e) { + fail(e.getMessage()); + } + verify(resp).setStatus(302); + verify(resp).setHeader("Location", + "http://10.20.11.160:8080/auth/realms/onap/protocol/openid-connect/auth?client_id=odlux.app&response" + + "_type=code&scope=openid&redirect_uri=http%3A%2F%2Fnasp.diasf.de%2Foauth%2Fredirect%2Fkeycloak"); + } + + @Test + public void testInValidLoginRedirect() { + + HttpServletRequest req = mock(HttpServletRequest.class); + when(req.getRequestURI()).thenReturn("/oauth/login/unknownproviderid"); + HttpServletResponse resp = mock(HttpServletResponse.class); + ServletOutputStreamToByteArrayOutputStream printOut = new ServletOutputStreamToByteArrayOutputStream(); + try { + when(resp.getOutputStream()).thenReturn(printOut); + servlet.doGet(req, resp); + } catch (ServletException | IOException e) { + fail(e.getMessage()); + } + verify(resp).setStatus(404); + } + + @Test + public void testValidLogin() { + + HttpServletRequest req = mock(HttpServletRequest.class); + when(req.getRequestURI()).thenReturn("/oauth/login"); + when(req.getParameter("username")).thenReturn("admin"); + when(req.getParameter("password")).thenReturn("admin"); + Claim claim = new Claim() { + @Override + public String clientId() { + return "admin"; + } + + @Override + public String userId() { + return "admin"; + } + + @Override + public String user() { + return null; + } + + @Override + public String domain() { + return "sdn"; + } + + @Override + public Set<String> roles() { + return Set.of("admin"); + } + }; + when(passwordCredentialAuth.authenticate(any(PasswordCredentials.class))).thenReturn(claim); + HttpServletResponse resp = mock(HttpServletResponse.class); + ServletOutputStreamToByteArrayOutputStream printOut = new ServletOutputStreamToByteArrayOutputStream(); + try { + when(resp.getOutputStream()).thenReturn(printOut); + servlet.doPost(req, resp); + } catch (ServletException | IOException e) { + fail(e.getMessage()); + } + verify(resp).setStatus(200); + } + + @Test + public void testGetProviders() { + + HttpServletRequest req = mock(HttpServletRequest.class); + when(req.getRequestURI()).thenReturn("/oauth/providers"); + HttpServletResponse resp = mock(HttpServletResponse.class); + ServletOutputStreamToByteArrayOutputStream printOut = new ServletOutputStreamToByteArrayOutputStream(); + try { + when(resp.getOutputStream()).thenReturn(printOut); + servlet.doGet(req, resp); + } catch (ServletException | IOException e) { + fail(e.getMessage()); + } + verify(resp).setStatus(200); + String responseBody = printOut.getByteArrayOutputStream().toString(StandardCharsets.UTF_8); + System.out.println(responseBody); + JSONArray a = new JSONArray(responseBody); + assertEquals(1, a.length()); + assertEquals("keycloak", a.getJSONObject(0).getString("id")); + assertEquals("OSNL Keycloak Provider", a.getJSONObject(0).getString("title")); + assertEquals("/oauth/login/keycloak", a.getJSONObject(0).getString("loginUrl")); + + } + + @Test +/* + @Ignore +*/ + public void testPoliciesAnon() { + + HttpServletRequest req = mock(HttpServletRequest.class); + when(req.getRequestURI()).thenReturn("/oauth/policies"); + HttpServletResponse resp = mock(HttpServletResponse.class); + ServletOutputStreamToByteArrayOutputStream printOut = new ServletOutputStreamToByteArrayOutputStream(); + try { + when(resp.getOutputStream()).thenReturn(printOut); + servlet.doGet(req, resp); + } catch (ServletException | IOException e) { + fail(e.getMessage()); + } + verify(resp).setStatus(200); + String responseBody = printOut.getByteArrayOutputStream().toString(StandardCharsets.UTF_8); + System.out.println(responseBody); + OdlPolicy[] anonPolicies = null; + try { + anonPolicies = readJson(responseBody, OdlPolicy[].class); + } catch (JsonProcessingException e) { + fail("unable to read anon policies response"); + } + assertEquals(9, anonPolicies.length); + OdlPolicy pApidoc = find(anonPolicies, "/apidoc/**"); + assertNotNull(pApidoc); + assertAllEquals(false, pApidoc); + OdlPolicy pOauth = find(anonPolicies, "/oauth/**"); + assertNotNull(pOauth); + assertAllEquals(true, pOauth); + OdlPolicy pRestconf = find(anonPolicies, "/rests/**"); + assertNotNull(pRestconf); + assertAllEquals(false, pRestconf); + } + + @Test + public void testPoliciesBasicAuth() { + + HttpServletRequest req = mock(HttpServletRequest.class); + when(req.getRequestURI()).thenReturn("/oauth/policies"); + when(req.getHeader("Authorization")).thenReturn(BaseHTTPClient.getAuthorizationHeaderValue("admin", "admin")); + when(odlIdentityService.listRoles("admin@sdn", "sdn")).thenReturn(Arrays.asList("admin")); + HttpServletResponse resp = mock(HttpServletResponse.class); + ServletOutputStreamToByteArrayOutputStream printOut = new ServletOutputStreamToByteArrayOutputStream(); + try { + when(resp.getOutputStream()).thenReturn(printOut); + servlet.doGet(req, resp); + } catch (ServletException | IOException e) { + fail(e.getMessage()); + } + verify(resp).setStatus(200); + String responseBody = printOut.getByteArrayOutputStream().toString(StandardCharsets.UTF_8); + System.out.println(responseBody); + OdlPolicy[] anonPolicies = null; + try { + anonPolicies = readJson(responseBody, OdlPolicy[].class); + } catch (JsonProcessingException e) { + fail("unable to read anon policies response"); + } + assertEquals(9, anonPolicies.length); + OdlPolicy pApidoc = find(anonPolicies, "/apidoc/**"); + assertNotNull(pApidoc); + assertAllEquals(false, pApidoc); + OdlPolicy pOauth = find(anonPolicies, "/oauth/**"); + assertNotNull(pOauth); + assertAllEquals(true, pOauth); + OdlPolicy pRestconf = find(anonPolicies, "/rests/**"); + assertNotNull(pRestconf); + assertAllEquals(false, pRestconf); + } + + @Test + public void testPoliciesBearer() { + HttpServletRequest req = mock(HttpServletRequest.class); + when(req.getRequestURI()).thenReturn("/oauth/policies"); + String token = createToken("admin", Arrays.asList("admin", "provision")).getToken(); + when(req.getHeader("Authorization")).thenReturn(String.format("Bearer %s", token)); + HttpServletResponse resp = mock(HttpServletResponse.class); + ServletOutputStreamToByteArrayOutputStream printOut = new ServletOutputStreamToByteArrayOutputStream(); + try { + when(resp.getOutputStream()).thenReturn(printOut); + servlet.doGet(req, resp); + } catch (ServletException | IOException e) { + fail(e.getMessage()); + } + verify(resp).setStatus(200); + String responseBody = printOut.getByteArrayOutputStream().toString(StandardCharsets.UTF_8); + System.out.println(responseBody); + OdlPolicy[] anonPolicies = null; + try { + anonPolicies = readJson(responseBody, OdlPolicy[].class); + } catch (JsonProcessingException e) { + fail("unable to read anon policies response"); + } + assertEquals(9, anonPolicies.length); + OdlPolicy pApidoc = find(anonPolicies, "/apidoc/**"); + assertNotNull(pApidoc); + assertAllEquals(false, pApidoc); + OdlPolicy pOauth = find(anonPolicies, "/oauth/**"); + assertNotNull(pOauth); + assertAllEquals(true, pOauth); + OdlPolicy pRestconf = find(anonPolicies, "/rests/**"); + assertNotNull(pRestconf); + assertAllEquals(true, pRestconf); + } + + private static BearerToken createToken(String username, List<String> roles) { + UserTokenPayload data = new UserTokenPayload(); + data.setPreferredUsername(username); + data.setFamilyName(""); + data.setGivenName(username); + data.setExp(tokenCreator.getDefaultExp()); + data.setRoles(roles); + return tokenCreator.createNewJWT(data); + } + + private static void assertAllEquals(boolean b, OdlPolicy p) { + assertEquals(b, p.getMethods().isGet()); + assertEquals(b, p.getMethods().isPost()); + assertEquals(b, p.getMethods().isPut()); + assertEquals(b, p.getMethods().isDelete()); + assertEquals(b, p.getMethods().isPatch()); + } + + private static OdlPolicy find(OdlPolicy[] policies, String path) { + for (OdlPolicy p : policies) { + if (path.equals(p.getPath())) { + return p; + } + } + return null; + } + + private static <T> T readJson(String data, Class<T> clazz) throws JsonMappingException, JsonProcessingException { + CustomObjectMapper mapper = new CustomObjectMapper(); + return mapper.readValue(data, clazz); + } + + private static <T> T readJson(File file, Class<T> clazz) throws IOException { + OdlJsonMapper mapper = new OdlJsonMapper(); + return mapper.readValue(file, clazz); + } + + private static class TestServlet extends AuthHttpServlet { + + private static final long serialVersionUID = 1L; + + public TestServlet() throws IllegalArgumentException, Exception { + super(TESTSHIROCONFIGFILE); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + super.doGet(req, resp); + } + + @Override + public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + super.doPost(req, resp); + } + } +} diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestConfig.java b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestConfig.java new file mode 100644 index 000000000..80ae8cf95 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestConfig.java @@ -0,0 +1,80 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.oauthprovider.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import java.io.IOException; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.InvalidConfigurationException; + +public class TestConfig { + + public static String TEST_CONFIG_FILENAME = "src/test/resources/test.config.json"; + public static String TEST_OOMCONFIG_FILENAME = "src/test/resources/oom.test.config.json"; + public static String TEST_RS256_FILENAME = "src/test/resources/test.configRS256.json"; + public static String TEST_RS256INVALID_FILENAME = "src/test/resources/test.configRS256-invalid.json"; + public static String TEST_RS512_FILENAME = "src/test/resources/test.configRS512.json"; + + + @Test + public void test() throws IOException, InvalidConfigurationException { + + Config config = Config.load(TEST_CONFIG_FILENAME); + System.out.println("config="+config); + assertEquals(60*60,config.getTokenLifetime()); + assertNotNull(config.getAlgorithm()); + assertNotNull(config.getTokenSecret()); + //assertNotNull(config.getPublicKey()); + assertEquals(Config.TOKENALG_HS256, config.getAlgorithm()); + } + @Test + public void testOom() throws IOException, InvalidConfigurationException { + + Config config = Config.load(TEST_OOMCONFIG_FILENAME); + System.out.println("config="+config); + assertEquals(30*60,config.getTokenLifetime()); + + } + @Test + public void testRS256() throws IOException, InvalidConfigurationException { + + Config config = Config.load(TEST_RS256_FILENAME); + System.out.println("config="+config); + assertEquals(60*60,config.getTokenLifetime()); + + } + @Test + public void testRS512() throws IOException, InvalidConfigurationException { + + Config config = Config.load(TEST_RS512_FILENAME); + System.out.println("config="+config); + assertEquals(60*60,config.getTokenLifetime()); + + } + @Test(expected = InvalidConfigurationException.class) + public void testRS256Invalid() throws IOException, InvalidConfigurationException { + + Config.load(TEST_RS256INVALID_FILENAME); + } +} diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestDeserializer.java b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestDeserializer.java new file mode 100644 index 000000000..421b61919 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestDeserializer.java @@ -0,0 +1,101 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.oauthprovider.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.common.http.BaseHTTPResponse; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.KeycloakUserTokenPayload; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OAuthResponseData; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.http.client.MappedBaseHttpResponse; + +public class TestDeserializer { + + @Test + public void test1() throws IOException { + final String token = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ1OHNXaTF4QWxjT1pyelY4X0l2VjliMlJTaFdZUWV4aXZYUXNYLTFTME" + + "RNIn0.eyJleHAiOjE2MTAzNjE2OTQsImlhdCI6MTYxMDM2MTM5NCwianRpIjoiOWRhOThmMTYtOTEyOS00N2NmLTgzOGQtNWQzYmVkYzYyZTJjIiwiaXNzIjoiaHR0cDovLzEwLjIwLjExLjE2MDo4MDgwL2F1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6IjE4MzhjNGYyLTVmZTMtNGYwYy1iMmQyLWQzNjRiMjdhNDk5NyIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFkbWluLWNsaSIsInNlc3Npb25fc3RhdGUiOiJjYzcxZmMxZi1hZGQ0LTRhODYtYWU1ZS1jMzRkZjQwM2M3NzIiLCJhY3IiOiIxIiwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiJ9.PUT4NzCM1ej3sNMMCkQa1NuQQwDgn19G-OnWL4NgLvZ3ocJUZ1Yfr9KAPkrJHaiK_HXQqwTA-Ma6Qn7BBMoXNdFjwu0k_HpqyUbBDilGN4wpkGiUeS1p5SW4T_hnWJtwCJ5BYkEvF6WaEbi7MFCbEVO9LVcUvsa-7St1WZ8V8RVfbWgjAu7ejlxe6RYUDMYzIKDj5F5y1-qCyoKzGIjt5ajcA9FWrexHifLJECKO8ZG08Wp7xQld1sYPOdde6XHMwiyNelTwd_EzCBgUw_8664rETGDVtyfuYchowo5Z6fmn4U87L6EGjEuxiAE8f3USy_jh6UF0LnvyTyq_9I" + + "M1VA"; + final String response = + "{\"access_token\":\"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ1OHNXaTF4QWxjT1pyelY4X0l2VjliMlJTaFdZUWV4aXZYUXNYLTFTME" + + "RNIn0.eyJleHAiOjE2MTAzNjE2OTQsImlhdCI6MTYxMDM2MTM5NCwianRpIjoiOWRhOThmMTYtOTEyOS00N2NmLTgzOGQtNWQzYmVkYzYyZTJjIiwiaXNzIjoiaHR0cDovLzEwLjIwLjExLjE2MDo4MDgwL2F1dGgvcmVhbG1zL21hc3RlciIsInN1YiI6IjE4MzhjNGYyLTVmZTMtNGYwYy1iMmQyLWQzNjRiMjdhNDk5NyIsInR5cCI6IkJlYXJlciIsImF6cCI6I" + + "mFkbWluLWNsaSIsInNlc3Npb25fc3RhdGUiOiJjYzcxZmMxZi1hZGQ0LTRhODYtYWU1ZS1jMzRkZjQwM2M3NzIiLCJhY3IiOiIxIiwic2NvcGUiOiJlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiJ9.PUT4NzCM1ej3sNMMCkQa1NuQQwDgn19G-OnWL4NgLvZ3ocJUZ1Yfr9KAPkrJHaiK_HX" + + "QqwTA-Ma6Qn7BBMoXNdFjwu0k_HpqyUbBDilGN4wpkGiUeS1p5SW4T_hnWJtwCJ5BYkEvF6WaEbi7MFCbEVO9LVcUvsa-7St1WZ8V8RVfbWgjAu7ejlxe6RYUDMYzIKDj5F5y1-qCyoKzGIjt5ajcA9FWrexHifLJECKO8ZG08Wp7xQld1sYPOdde6XHMwiyNelTwd_EzCBgUw_8664rETGDVtyfuYchowo5Z6fmn4U87L6EGjEuxiAE8f3USy_jh6UF0LnvyTyq_9I" + + "M1VA\",\"expires_in\":300,\"refresh_expires_in\":1800,\"refresh_token\":\"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI1NzdiN2Q3MC00NzMwLTQ0MDMtODk4My04ZjJmYTg4M2U2M2EifQ.eyJleHAiOjE2MTAzNjMxOTQsImlhdCI6MTYxMDM2MTM5NCwianRpIjoiMmNjMGY4YWYtNWY2OC00YmFhLWEyOTctNjMxMjk2YzhmY2" + + "U5IiwiaXNzIjoiaHR0cDovLzEwLjIwLjExLjE2MDo4MDgwL2F1dGgvcmVhbG1zL21hc3RlciIsImF1ZCI6Imh0dHA6Ly8xMC4yMC4xMS4xNjA6ODA4MC9hdXRoL3JlYWxtcy9tYXN0ZXIiLCJzdWIiOiIxODM4YzRmMi01ZmUzLTRmMGMtYjJkMi1kMzY0YjI3YTQ5OTciLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoiYWRtaW4tY2xpIiwic2Vzc2lvbl9zdGF0ZSI6I" + + "mNjNzFmYzFmLWFkZDQtNGE4Ni1hZTVlLWMzNGRmNDAzYzc3MiIsInNjb3BlIjoiZW1haWwgcHJvZmlsZSJ9.qutqcFuQW-GzaCVNMfiYrbmHYD34GYwBqIbaQbJSY-g\",\"token_type\":\"bearer\",\"not-before-policy\":0,\"session_state\":\"cc71fc1f-add4-4a86-ae5e-c34df403c772\",\"scope\":\"email profile\"} "; + + BaseHTTPResponse res = new BaseHTTPResponse(200, response); + OAuthResponseData data = new MappedBaseHttpResponse<>(res,OAuthResponseData.class).body; + assertEquals(token,data.getAccess_token()); + + } + + @Test + public void testUserPayloadDeser() throws JsonMappingException, JsonProcessingException { + final String payload = "{\n" + + " \"exp\": 1610362593,\n" + + " \"iat\": 1610361393,\n" + + " \"jti\": \"09bd6f2c-5dba-44a0-bd76-cd0d440137d0\",\n" + + " \"iss\": \"http://10.20.11.160:8080/auth/realms/onap\",\n" + + " \"aud\": \"account\",\n" + + " \"sub\": \"446a24bc-d8a0-43dd-afa5-e56eed75deb8\",\n" + + " \"typ\": \"Bearer\",\n" + + " \"azp\": \"admin-cli\",\n" + + " \"session_state\": \"db2c96f4-cc9b-47e8-a83f-a01c50d656f2\",\n" + + " \"acr\": \"1\",\n" + + " \"realm_access\": {\n" + + " \"roles\": [\n" + + " \"provision\",\n" + + " \"offline_access\",\n" + + " \"uma_authorization\"\n" + + " ]\n" + + " },\n" + + " \"resource_access\": {\n" + + " \"account\": {\n" + + " \"roles\": [\n" + + " \"manage-account\",\n" + + " \"manage-account-links\",\n" + + " \"view-profile\"\n" + + " ]\n" + + " }\n" + + " },\n" + + " \"scope\": \"profile email\",\n" + + " \"email_verified\": false,\n" + + " \"name\": \"Luke Skywalker\",\n" + + " \"preferred_username\": \"luke.skywalker\",\n" + + " \"given_name\": \"Luke\",\n" + + " \"family_name\": \"Skywalker\",\n" + + " \"email\": \"luke.skywalker@sdnr.onap.org\"\n" + + "}"; + + ObjectMapper mapper = new ObjectMapper(); + KeycloakUserTokenPayload data = mapper.readValue(payload,KeycloakUserTokenPayload.class); + assertNotNull(data.getRealmAccess()); + assertEquals(3, data.getRealmAccess().getRoles().size()); + } +} diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestGitlabAuthService.java b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestGitlabAuthService.java new file mode 100644 index 000000000..6c2390ea0 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestGitlabAuthService.java @@ -0,0 +1,198 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.oauthprovider.test; + +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.nio.file.Files; +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OAuthProviderConfig; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.UnableToConfigureOAuthService; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.GitlabProviderService; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator; + +public class TestGitlabAuthService { + + private static HttpServer server; + private static ExecutorService httpThreadPool; + private static GitlabProviderServiceToTest oauthService; + private static final int PORT = randomPort(50000, 55000); + private static final String GITURL = String.format("http://127.0.0.1:%d", PORT); + private static final String OAUTH_SECRET = "oauthsecret"; + private static final String TOKENCREATOR_SECRET = "secret"; + private static final String REDIRECT_URI = "/odlux/token?"; + + @BeforeClass + public static void init() throws IllegalArgumentException, Exception { + + TokenCreator tokenCreator = TokenCreator.getInstance(Config.TOKENALG_HS256, TOKENCREATOR_SECRET, "issuer", 30*60); + OAuthProviderConfig config = new OAuthProviderConfig("git", GITURL, null, "odlux.app", OAUTH_SECRET, "openid", + "gitlab test", "", null, false); + oauthService = new GitlabProviderServiceToTest(config, REDIRECT_URI, tokenCreator); + try { + initGitlabTestWebserver(PORT, "/"); + } catch (IOException e) { + fail(e.getMessage()); + } + } + + @AfterClass + public static void close() { + stopTestWebserver(); + } + + @Test + public void test() { + HttpServletRequest req; + HttpServletResponse resp = null; + String host = "http://localhost:8412"; + final String state = "stateabc"; + try { + req = mock(HttpServletRequest.class); + resp = mock(HttpServletResponse.class); + when(req.getParameter("code")).thenReturn("abcdefg"); + when(req.getParameter("state")).thenReturn(state); + oauthService.addState(state); + oauthService.handleRedirect(req, resp, host); + } catch (IOException e) { + fail(e.getMessage()); + } + verify(resp).setStatus(302); + //verify(resp).setHeader("Location",any(String.class)); + } + + public void test2() { + oauthService.sendLoginRedirectResponse(null, null); + } + + public static class GitlabProviderServiceToTest extends GitlabProviderService { + + public GitlabProviderServiceToTest(OAuthProviderConfig config, String redirectUri, TokenCreator tokenCreator) throws UnableToConfigureOAuthService { + super(config, redirectUri, tokenCreator); + } + + public void addState(String state) { + this.randomIds.add(state); + } + } + + private static int randomPort(int min, int max) { + Random random = new Random(); + return random.nextInt(max + 1 - min) + min; + } + + public static void initGitlabTestWebserver(int port, String baseUri) throws IOException { + server = HttpServer.create(new InetSocketAddress("127.0.0.1", port), 0); + httpThreadPool = Executors.newFixedThreadPool(5); + server.setExecutor(httpThreadPool); + server.createContext(baseUri, new MyHandler()); + //server.createContext("/", new MyRootHandler()); + server.setExecutor(null); // creates a default executor + server.start(); + System.out.println("http server started"); + } + + public static void stopTestWebserver() { + if (server != null) { + server.stop(0); + httpThreadPool.shutdownNow(); + System.out.println("http server stopped"); + } + } + + private static String loadResourceFileContent(String filename) { + try { + return Files.readString(new File(filename).toPath()); + } catch (IOException e) { + fail(e.getMessage()); + } + return null; + } + + public static class MyHandler implements HttpHandler { + private static final String GITLAB_TOKEN_ENDPOINT = "/oauth/token"; + private static final String GITLAB_USER_ENDPOINT = "/api/v4/user"; + private static final String GITLAB_GROUP_ENDPOINT = "/api/v4/groups?min_access_level=10"; + private static final String GITLAB_TOKEN_RESPONSE = + loadResourceFileContent("src/test/resources/oauth/gitlab-token-response.json"); + private static final String GITLAB_USER_RESPONSE = + loadResourceFileContent("src/test/resources/oauth/gitlab-user-response.json"); + private static final String GITLAB_GROUP_RESPONSE = + loadResourceFileContent("src/test/resources/oauth/gitlab-groups-response.json"); + + @Override + public void handle(HttpExchange t) throws IOException { + final String method = t.getRequestMethod(); + final String uri = t.getRequestURI().toString(); + System.out.println(String.format("req received: %s %s", method, t.getRequestURI())); + OutputStream os = null; + try { + if (method.equals("GET")) { + if (uri.equals(GITLAB_USER_ENDPOINT)) { + t.sendResponseHeaders(200, GITLAB_USER_RESPONSE.length()); + os = t.getResponseBody(); + os.write(GITLAB_USER_RESPONSE.getBytes()); + } else if (uri.equals(GITLAB_GROUP_ENDPOINT)) { + t.sendResponseHeaders(200, GITLAB_GROUP_RESPONSE.length()); + os = t.getResponseBody(); + os.write(GITLAB_GROUP_RESPONSE.getBytes()); + } + } else if (method.equals("POST")) { + if (uri.equals(GITLAB_TOKEN_ENDPOINT)) { + t.sendResponseHeaders(200, GITLAB_TOKEN_RESPONSE.length()); + os = t.getResponseBody(); + os.write(GITLAB_TOKEN_RESPONSE.getBytes()); + } else { + t.sendResponseHeaders(404, 0); + } + } else { + t.sendResponseHeaders(404, 0); + } + System.out.println("req handled successful"); + + } catch (Exception e) { + System.out.println(e.getMessage()); + } finally { + if (os != null) { + os.close(); + } + } + } + } +} diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestKeycloakAuthService.java b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestKeycloakAuthService.java new file mode 100644 index 000000000..acc7c6b36 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestKeycloakAuthService.java @@ -0,0 +1,196 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.oauthprovider.test; + +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.nio.file.Files; +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OAuthProviderConfig; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.UnableToConfigureOAuthService; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.KeycloakProviderService; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator; + +public class TestKeycloakAuthService { + + private static HttpServer server; + private static ExecutorService httpThreadPool; + private static KeycloakProviderServiceToTest oauthService; + private static final int PORT = randomPort(50000, 55000); + private static final String KEYCLOAKURL = String.format("http://127.0.0.1:%d", PORT); + private static final String OAUTH_SECRET = "oauthsecret"; + private static final String TOKENCREATOR_SECRET = "secret"; + private static final String REDIRECT_URI = "/odlux/token?"; + + @BeforeClass + public static void init() throws IllegalArgumentException, Exception { + + TokenCreator tokenCreator = TokenCreator.getInstance(Config.TOKENALG_HS256, TOKENCREATOR_SECRET, "issuer", 30*60); + OAuthProviderConfig config = new OAuthProviderConfig("kc", KEYCLOAKURL, null, "odlux.app", OAUTH_SECRET, + "openid", "keycloak test", "onap",null, false); + oauthService = new KeycloakProviderServiceToTest(config, REDIRECT_URI, tokenCreator); + try { + initKeycloakTestWebserver(PORT, "/"); + } catch (IOException e) { + fail(e.getMessage()); + } + } + + @AfterClass + public static void close() { + stopTestWebserver(); + } + + @Test + public void test() { + HttpServletRequest req; + HttpServletResponse resp = null; + String host = "http://localhost:8412"; + final String state = "stateabc"; + try { + req = mock(HttpServletRequest.class); + resp = mock(HttpServletResponse.class); + when(req.getParameter("code")).thenReturn("abcdefg"); + when(req.getParameter("state")).thenReturn(state); + oauthService.handleRedirect(req, resp, host); + } catch (IOException e) { + fail(e.getMessage()); + } + verify(resp).setStatus(302); + //verify(resp).setHeader("Location",any(String.class)); + } + + public void test2() { + oauthService.sendLoginRedirectResponse(null, null); + } + @Ignore + @Test + public void test3() { + HttpServletResponse resp = mock(HttpServletResponse.class); + String token = ""; + try { + oauthService.sendLogoutRedirectResponse(token, resp,"http://sdnr.onap/odlux/index.html"); + verify(resp).setStatus(302); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + public static class KeycloakProviderServiceToTest extends KeycloakProviderService { + + public KeycloakProviderServiceToTest(OAuthProviderConfig config, String redirectUri, + TokenCreator tokenCreator) throws UnableToConfigureOAuthService { + super(config, redirectUri, tokenCreator); + } + } + + private static int randomPort(int min, int max) { + Random random = new Random(); + return random.nextInt(max + 1 - min) + min; + } + + public static void initKeycloakTestWebserver(int port, String baseUri) throws IOException { + server = HttpServer.create(new InetSocketAddress("127.0.0.1", port), 0); + httpThreadPool = Executors.newFixedThreadPool(5); + server.setExecutor(httpThreadPool); + server.createContext(baseUri, new MyHandler()); + //server.createContext("/", new MyRootHandler()); + server.setExecutor(null); // creates a default executor + server.start(); + System.out.println("http server started"); + } + + public static void stopTestWebserver() { + if (server != null) { + server.stop(0); + httpThreadPool.shutdownNow(); + System.out.println("http server stopped"); + } + } + + private static String loadResourceFileContent(String filename) { + try { + return Files.readString(new File(filename).toPath()); + } catch (IOException e) { + fail(e.getMessage()); + } + return null; + } + + public static class MyHandler implements HttpHandler { + private static final String KEYCLOAK_TOKEN_ENDPOINT = "/auth/realms/onap/protocol/openid-connect/token"; + private static final String KEYCLOAK_LOGOUT_ENDPOINT = "/auth/realms/onap/protocol/openid-connect/logout"; + private static final String KEYCLOAK_TOKEN_RESPONSE = + loadResourceFileContent("src/test/resources/oauth/keycloak-token-response.json"); + + @Override + public void handle(HttpExchange t) throws IOException { + final String method = t.getRequestMethod(); + final String uri = t.getRequestURI().toString(); + System.out.println(String.format("req received: %s %s", method, t.getRequestURI())); + OutputStream os = null; + try { + if("GET".equals(method)){ + if(KEYCLOAK_LOGOUT_ENDPOINT.equals(uri)){ + t.sendResponseHeaders(200, 0); + } + } + else if ("POST".equals(method)) { + if (uri.equals(KEYCLOAK_TOKEN_ENDPOINT)) { + t.sendResponseHeaders(200, KEYCLOAK_TOKEN_RESPONSE.length()); + os = t.getResponseBody(); + os.write(KEYCLOAK_TOKEN_RESPONSE.getBytes()); + } else { + t.sendResponseHeaders(404, 0); + } + } else { + t.sendResponseHeaders(404, 0); + } + System.out.println("req handled successful"); + + } catch (Exception e) { + System.out.println(e.getMessage()); + } finally { + if (os != null) { + os.close(); + } + } + } + } +} diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestPolicy.java b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestPolicy.java new file mode 100644 index 000000000..31d72944c --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestPolicy.java @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.oauthprovider.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.OdlPolicy; + +public class TestPolicy { + + private static final String PATH_1 = "/p1/**"; + + @Test + public void testPolicyAllowAll() { + OdlPolicy p = OdlPolicy.allowAll(PATH_1); + assertTrue(p.getMethods().isGet()); + assertTrue(p.getMethods().isPost()); + assertTrue(p.getMethods().isPut()); + assertTrue(p.getMethods().isDelete()); + assertTrue(p.getMethods().isPatch()); + assertEquals(PATH_1,p.getPath()); + } + + @Test + public void testPolicyDenyAll() { + OdlPolicy p = OdlPolicy.denyAll(PATH_1); + assertFalse(p.getMethods().isGet()); + assertFalse(p.getMethods().isPost()); + assertFalse(p.getMethods().isPut()); + assertFalse(p.getMethods().isDelete()); + assertFalse(p.getMethods().isPatch()); + assertEquals(PATH_1,p.getPath()); + } + +} diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestProperty.java b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestProperty.java new file mode 100644 index 000000000..2d03bab1d --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestProperty.java @@ -0,0 +1,42 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.oauthprovider.test; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import org.junit.Ignore; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config; + +public class TestProperty { + + @Ignore + @Test + public void test() { + String hostname = Config.getProperty("${HOSTNAME}", null); + System.out.println(hostname); + assertNotNull(hostname); + hostname = Config.getProperty("${HOSTNAME2}", null); + System.out.println(hostname); + assertNull(hostname); + } +} diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRSAAlgorithms.java b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRSAAlgorithms.java new file mode 100644 index 000000000..84d8e0a96 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRSAAlgorithms.java @@ -0,0 +1,108 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.oauthprovider.test; + +import static org.junit.Assert.fail; +import com.auth0.jwt.JWT; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.auth0.jwt.interfaces.JWTVerifier; +import java.io.IOException; +import java.security.Security; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.util.Date; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.RSAKeyReader; + +/** + * + * @author jack + * + */ +public class TestRSAAlgorithms { + + private static final String ISSUER = "jwttest"; + private static final String SUBJECT = "meandmymonkey"; + + @BeforeClass + public static void init() { + Security.addProvider( + new BouncyCastleProvider() + ); + } + + /** + * private and public key were generated in ubuntu 20.04 with + * $ ssh-keygen -t rsa -b 4096 -m PEM -P "" -f jwtRS512.key + * $ openssl rsa -in jwtRS512.key -pubout -outform PEM -out jwtRS512.key.pub + */ + @Test + public void testRSA512() { + RSAPrivateKey privKey = null; + RSAPublicKey pubKey = null; + try { + privKey = RSAKeyReader.getPrivateKey("file://src/test/resources/jwtRS512.key"); + pubKey = RSAKeyReader.getPublicKey("file://src/test/resources/jwtRS512.key.pub"); + } catch (IOException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + verifyAlg(Algorithm.RSA512(pubKey, privKey)); + } + + /** + * private and public key were generated in ubuntu 20.04 with + * $ openssl genrsa 2048 -out rsa-2048bit-jwtRS256.key + * $ openssl rsa -in jwtRS256.key -pubout > jwtRS256.key.pub + */ + @Test + public void testRSA256() { + RSAPrivateKey privKey = null; + RSAPublicKey pubKey = null; + try { + privKey = RSAKeyReader.getPrivateKey("file://src/test/resources/jwtRS256.key"); + pubKey = RSAKeyReader.getPublicKey("file://src/test/resources/jwtRS256.key.pub"); + } catch (IOException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + verifyAlg(Algorithm.RSA512(pubKey, privKey)); + } + + private static void verifyAlg(Algorithm a) { + long now = new Date().getTime(); + final String token = JWT.create().withIssuer(ISSUER).withExpiresAt(new Date(now+10000)) + .withIssuedAt(new Date(now)) + .withSubject(SUBJECT) + .sign(a); + try { + JWTVerifier verifier = JWT.require(a).withIssuer(ISSUER).build(); + verifier.verify(token); + + } catch (JWTVerificationException e) { + fail(e.getMessage()); + } + } +} diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRealm.java b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRealm.java new file mode 100644 index 000000000..ebf01a1ba --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/TestRealm.java @@ -0,0 +1,219 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.oauthprovider.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import com.auth0.jwt.interfaces.DecodedJWT; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.AuthenticationInfo; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.authc.BearerToken; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.subject.PrincipalCollection; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.OAuth2Realm; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.Config; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.data.UserTokenPayload; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.AuthService; +import org.onap.ccsdk.features.sdnr.wt.oauthprovider.providers.TokenCreator; +import org.opendaylight.aaa.api.Authentication; +import org.opendaylight.aaa.api.TokenStore; +import org.opendaylight.aaa.api.shiro.principal.ODLPrincipal; +import org.opendaylight.aaa.shiro.realm.TokenAuthRealm; +import org.opendaylight.aaa.tokenauthrealm.auth.AuthenticationManager; +import org.opendaylight.aaa.tokenauthrealm.auth.TokenAuthenticators; + +public class TestRealm { + + private static OAuth2RealmToTest realm; + private static TokenCreator tokenCreator; + + @BeforeClass + public static void init() throws IllegalArgumentException, Exception { + + try { + Config config = Config.getInstance(TestConfig.TEST_CONFIG_FILENAME); + tokenCreator = TokenCreator.getInstance(config); + TokenAuthRealm.prepareForLoad(new AuthenticationManager(), new TokenAuthenticators(), new TokenStore() { + @Override + public void put(String token, Authentication auth) { + + } + + @Override + public Authentication get(String token) { + return null; + } + + @Override + public boolean delete(String token) { + return false; + } + + @Override + public long tokenExpiration() { + return 0; + } + }); + realm = new OAuth2RealmToTest(); + } catch (IOException e) { + fail(e.getMessage()); + } + } + + + @Test + public void testTokenSupport() { + assertTrue(realm.supports(new UsernamePasswordToken())); + assertTrue(realm.supports(new BearerToken(""))); + } + + + @Test + public void testAuthorizationInfo() { + //bearer token use case + PrincipalCollection c = mock(PrincipalCollection.class); + final List<String> roles = Arrays.asList("admin", "provision"); + UserTokenPayload userData = createUserData("", roles); + + DecodedJWT decodedJwt = tokenCreator.verify(tokenCreator.createNewJWT(userData).getToken()); + when(c.getPrimaryPrincipal()).thenReturn(decodedJwt); + + AuthorizationInfo ai = realm.doGetAuthorizationInfo(c); + for (String role : roles) { + assertTrue(ai.getRoles().contains(role)); + } + assertEquals(roles.size(), ai.getRoles().size()); + //odl token use case + ODLPrincipal principal = mock(ODLPrincipal.class); + when(principal.getRoles()).thenReturn(new HashSet<String>(roles)); + PrincipalCollection c2 = mock(PrincipalCollection.class); + when(c2.getPrimaryPrincipal()).thenReturn(principal); + ai = realm.doGetAuthorizationInfo(c2); + for (String role : roles) { + assertTrue(ai.getRoles().contains(role)); + } + assertEquals(roles.size(), ai.getRoles().size()); + + } + + @Test + public void testUrlTrimming(){ + final String internalUrl="https://test.identity.onap:49333"; + final String externalUrl="https://test.identity.onap:49333"; + final String testUrl1 = "/my/token/endpoint"; + final String testUrl2 = internalUrl+testUrl1; + final String testUrl3 = externalUrl+testUrl1; + + assertEquals(testUrl1, AuthService.trimUrl(internalUrl, testUrl1)); + assertEquals(testUrl1, AuthService.trimUrl(internalUrl, testUrl2)); + assertEquals(testUrl1, AuthService.trimUrl(externalUrl, testUrl3)); + + assertEquals(testUrl2, AuthService.extendUrl(internalUrl, testUrl3)); + + + + } + @Test + public void testAssertCredentialsMatch() { + //bearer token use case + UserTokenPayload userData = createUserData("", Arrays.asList("admin", "provision")); + AuthenticationToken atoken = new BearerToken(tokenCreator.createNewJWT(userData).getToken()); + AuthenticationInfo ai = null; + try { + realm.assertCredentialsMatch(atoken, ai); + } catch (AuthenticationException e) { + fail(e.getMessage()); + } + //odl token use case + atoken = new UsernamePasswordToken("admin", "admin"); + try { + realm.assertCredentialsMatch(atoken, ai); + } catch (AuthenticationException e) { + fail(e.getMessage()); + } + } + + @Test + public void testAuthenticationInfo() { + //bearer token use case + UserTokenPayload userData = createUserData("", Arrays.asList("admin", "provision")); + AuthenticationToken atoken = new BearerToken(tokenCreator.createNewJWT(userData).getToken()); + AuthenticationInfo ai = null; + try { + ai = realm.doGetAuthenticationInfo(atoken); + } catch (AuthenticationException e) { + fail(e.getMessage()); + } + //odl token use case + ai=null; + atoken = new UsernamePasswordToken("admin", "admin"); + try { + ai = realm.doGetAuthenticationInfo(atoken); + } catch (AuthenticationException e) { + fail(e.getMessage()); + } + } + + private static UserTokenPayload createUserData(String username, List<String> roles) { + UserTokenPayload userData = new UserTokenPayload(); + userData.setExp(tokenCreator.getDefaultExp()); + userData.setFamilyName(""); + userData.setGivenName(""); + userData.setPreferredUsername(username); + userData.setRoles(roles); + return userData; + } + + public static class OAuth2RealmToTest extends OAuth2Realm { + + public OAuth2RealmToTest() throws IllegalArgumentException, Exception { + super(); + } + + @Override + public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg) { + return super.doGetAuthorizationInfo(arg); + } + + @Override + public void assertCredentialsMatch(AuthenticationToken atoken, AuthenticationInfo ai) + throws AuthenticationException { + super.assertCredentialsMatch(atoken, ai); + } + + @Override + public AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { + return super.doGetAuthenticationInfo(token); + } + } +} diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/helper/OdlJsonMapper.java b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/helper/OdlJsonMapper.java new file mode 100644 index 000000000..7d51b2fe8 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/helper/OdlJsonMapper.java @@ -0,0 +1,65 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.oauthprovider.test.helper; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.mapperextensions.YangToolsBuilderAnnotationIntrospector; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.mapperextensions.YangToolsModule; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.aaa.rev161214.http.permission.Permissions; + +public class OdlJsonMapper extends ObjectMapper { + + private static final long serialVersionUID = 1L; + + + public OdlJsonMapper() { + this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + this.setSerializationInclusion(Include.NON_NULL); + this.setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE); + this.enable(MapperFeature.USE_GETTERS_AS_SETTERS); + YangToolsBuilderAnnotationIntrospector introspector = new YangToolsBuilderAnnotationIntrospector(); + //introspector.addDeserializer(Main.class, ShiroMainBuilder.class.getName()); + //introspector.addDeserializer(Permissions.class,PermissionsBuilder.class.getName()); + this.setAnnotationIntrospector(introspector); + this.registerModule(new YangToolsModule()); + } + + /* public static class PermissionsBuilder implements Builder<Permissions> { + private Permissions _value; + + public PermissionsBuilder() { + + } + public PermissionsBuilder(Permissions value) { + this._value = value; + } + + @Override + public Permissions build() { + return this._value; + } + }*/ +} diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/helper/OdlXmlMapper.java b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/helper/OdlXmlMapper.java new file mode 100644 index 000000000..b965878e8 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/java/org/onap/ccsdk/features/sdnr/wt/oauthprovider/test/helper/OdlXmlMapper.java @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.oauthprovider.test.helper; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import org.onap.ccsdk.features.sdnr.wt.yang.mapper.mapperextensions.YangToolsBuilderAnnotationIntrospector; + +public class OdlXmlMapper extends XmlMapper{ + + private static final long serialVersionUID = 1L; + + + public OdlXmlMapper() { + this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + this.setSerializationInclusion(Include.NON_NULL); + this.setPropertyNamingStrategy(PropertyNamingStrategy.KEBAB_CASE); + this.enable(MapperFeature.USE_GETTERS_AS_SETTERS); + YangToolsBuilderAnnotationIntrospector introspector = new YangToolsBuilderAnnotationIntrospector(); + //introspector.addDeserializer(Main.class, ShiroMainBuilder.class.getName()); + + this.setAnnotationIntrospector(introspector); + } +} diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/aaa-app-config.test.xml b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/aaa-app-config.test.xml new file mode 100644 index 000000000..e46508d68 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/aaa-app-config.test.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" ?> + + +<shiro-configuration xmlns="urn:opendaylight:aaa:app:config"> + + + <main> + <pair-key>tokenAuthRealm</pair-key> + <pair-value>org.onap.ccsdk.features.sdnr.wt.oauthprovider.OAuth2Realm</pair-value> + </main> + + <main> + <pair-key>securityManager.realms</pair-key> + <pair-value>$tokenAuthRealm</pair-value> + </main> + + <main> + <pair-key>anyroles</pair-key> + <pair-value>org.opendaylight.aaa.shiro.filters.AnyRoleHttpAuthenticationFilter</pair-value> + </main> + <main> + <pair-key>authcBearer</pair-key> + <pair-value>org.opendaylight.aaa.shiro.filters.ODLHttpAuthenticationFilter2</pair-value> + </main> + + <main> + <pair-key>accountingListener</pair-key> + <pair-value>org.opendaylight.aaa.shiro.filters.AuthenticationListener</pair-value> + </main> + <main> + <pair-key>securityManager.authenticator.authenticationListeners</pair-key> + <pair-value>$accountingListener</pair-value> + </main> + + <main> + <pair-key>dynamicAuthorization</pair-key> + <pair-value>org.opendaylight.aaa.shiro.realm.MDSALDynamicAuthorizationFilter</pair-value> + </main> + + <urls> + <pair-key>/**/operations/cluster-admin**</pair-key> + <pair-value>dynamicAuthorization</pair-value> + </urls> + <urls> + <pair-key>/**/v1/**</pair-key> + <pair-value>authcBearer, roles[admin]</pair-value> + </urls> + <urls> + <pair-key>/**/config/aaa*/**</pair-key> + <pair-value>authcBearer, roles[admin]</pair-value> + </urls> + <urls> + <pair-key>/oauth/**</pair-key> + <pair-value>anon</pair-value> + </urls> + <urls> + <pair-key>/odlux/**</pair-key> + <pair-value>anon</pair-value> + </urls> + <urls> + <pair-key>/apidoc/**</pair-key> + <pair-value>authcBasic, roles[admin]</pair-value> + </urls> + <urls> + <pair-key>/test123/**</pair-key> + <pair-value>authcBasic</pair-value> + </urls> + <urls> + <pair-key>/rests/**</pair-key> + <pair-value>authcBearer, anyroles["admin,provision"]</pair-value> + </urls> + <urls> + <pair-key>/**</pair-key> + <pair-value>authcBearer, anyroles["admin,provision"]</pair-value> + </urls> +</shiro-configuration> + diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/jwtRS256.key b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/jwtRS256.key new file mode 100644 index 000000000..c0c15e014 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/jwtRS256.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAyzd6BwZLS1UKchZENYyVycHZWp9iRTtLx31dZHfG8h0PLawG +y+dXPEW8W/zVB13/Rdci9HXCnskBhzkFu9Ep+nI7X5C+lO3vxxNnGQ1CrRyHxHbb +BYlm6J55l6tQox5qVcWe4iMbLm7F2eNKFPqEUu8OInjmLFZvS9C0qtfpqdeoyt4G +XucUHcGZ/0E6yeq882+zYyb4pWN5PogAsP2KYeT1T6P0VCw4tda9GtokD3zOSaOg +IvhIqe9jLAVcqWkxpuhV+IQdULBOxcJziW3AdQcB5IFQ7/SfZ9SnO5OpDTe02R5q +bjH9k0iihrpI9HnlVrHqIEtFwDjuoPSeAOBjjwIDAQABAoIBAQCOfNeTFVa1+2rX +k8U/xtNAJCvC3v6IjIsV1VEmoNVd7gI2g+hAEHWaTUtFNIIqKD5VOgPIZMmRjF8F +8XWTu5UzheUbnOIEitEVRQWFC0c1GkwX9T6dIzqE4JlhPz3LIghtG6PL69GjPQh9 +PmEzVHRzsiq3AQ5jCDgBcNU89SdhbhPsfNpDq9+GaWUaVJ4MmJw52qLeSW0nh4NZ +fMSINAfGZ/3Q2Nfe55zIk4KICyatKYLUMdcwynMwWYdZzg1e/4gxemdWdgFVUdPl +rE6y404m+FrHl/nntL153u0C24jtEU0CJvLasu7hLjzAoANBzohcXxLY46jeNqk9 +yS4juMgBAoGBAPxn9hRH5vMxFCfT23/s1RnUB9Sal6OL8/hZ8OpwrnLaLmWDvvr5 +FBcDThhrHnJTLj0pOAxFX8kLjKgQdWB0ZqrEsG1R9AAVHxM4hXc92kDsAk4QJgCG +tKDtzk9PKy8Jt1LnOF9n6NDLZuZim9Sv7qim6tt0L7K/mGrlCN4Gq6E3AoGBAM4c +N2r0vObiSboryfY4xNSUZ1qLWAEJz4gyUQljSrlu2Gj5DK4rrTEd8Qyk9ehUdjuR +giejpdjIvmjQ7NNPUogJbIoSbtKmx+k8qF7ieRulJjVBiJZLwNtGhiB4e6oZdhNl +fJETn8MhkbOt8Sa1eEiR9u2O7IAYVwZLU/khkNxpAoGARxqKSgBPYSbsRKP767et ++I6wfgXmvd3JJqc/pOuFWTl5ZIOOo2jTbgAyWdKjSxV/qx8XeO16JEqqnxWz2y4v +Vd/+y20QzY0lqeZ8QrEb8LoLlC4cZn2MGOGlAtaMlb2o9SPJz6aYAWmrXS9eMrY1 +BzGua4/5d+Ndbo+CxfkfFFUCgYEAjFimW8w+/TDFZ2H96g2J6f8LyZns2PgnOuSY +Tb4w2cfi0MgVnFvdWP68bxG86PDqeXGBoSBMBCvdjF4HhXQUDNHt+K7Ii+RJaEaH +l+S69tokBEuViFIZBrclCeNAwfkIb/jBM8CbHzIylpkxBly3hSLvc5/I5wir6XtN +uOzkSVECgYEAy2oGf68OkNL74/WKDmQvnRxWkn78rCTzVAe0iJmJ3rAdak/Jb2Lj +iihXn0XPsedZOZStbZYCG6GtcZCRypPi9HjO6DRRYFv3+aicjS7tVuJ3u39e5nIR +K6eMAgFn1TAToc3gt/hUCnmreZ4ZUfQfuFK21Lqmn1FYJtck9ZHx0sw= +-----END RSA PRIVATE KEY----- diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/jwtRS256.key.pub b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/jwtRS256.key.pub new file mode 100644 index 000000000..add863aef --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/jwtRS256.key.pub @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyzd6BwZLS1UKchZENYyV +ycHZWp9iRTtLx31dZHfG8h0PLawGy+dXPEW8W/zVB13/Rdci9HXCnskBhzkFu9Ep ++nI7X5C+lO3vxxNnGQ1CrRyHxHbbBYlm6J55l6tQox5qVcWe4iMbLm7F2eNKFPqE +Uu8OInjmLFZvS9C0qtfpqdeoyt4GXucUHcGZ/0E6yeq882+zYyb4pWN5PogAsP2K +YeT1T6P0VCw4tda9GtokD3zOSaOgIvhIqe9jLAVcqWkxpuhV+IQdULBOxcJziW3A +dQcB5IFQ7/SfZ9SnO5OpDTe02R5qbjH9k0iihrpI9HnlVrHqIEtFwDjuoPSeAOBj +jwIDAQAB +-----END PUBLIC KEY----- diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/jwtRS512.key b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/jwtRS512.key new file mode 100644 index 000000000..6b4e8c7bc --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/jwtRS512.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKQIBAAKCAgEA5vZBjfLjlUPK0b/F8FbGAyT1jXNVv2vjl+ZGUlThDX1jn0Wh +XER5CL9CfkHKjJE47r8pQsO6nX9s5y+XzmAU9+QggtaDA+g0Px+cvCJQzJbtDbh0 +94m3uC50S+SSnYvr7vY1zy+jdswf/pXg1z059FokRxGso36SkSv81NYbN/WQrTKo +gY6jkZXfPP8/sn8KV8uf7jYy2ZyHtakM9c9oCopWH78mhf9ioUNbgJsAxZmiohQU +N5a3GbLS/nsTBOcVxUezvjvfb732iChKoARj3NiNN7HFHpXEXfiZ10OjrtAb9Y1K +9RZsu/MKcFxBhDZusXjee6/x+NluQwT3RybgkCyV/i97Sroc37wOqimxtoSJ+MZY +ZXNAUGNbNySkjvIGL8jWMj6w/zvyiHVbQg+DqY2Qds7Tdk29swYsMQQlz9v0FS/p +GFVWo+5HTm+3MMlaMjSofw6j5/sE4OvJ4RCcnX8Cj1Zq9PrsMLLSF5MBOCSiclpI +C1EYQ9Oi6XrcL3bbyyKGwB/u1X1HHnUmhRdKdVwKpSHR54XlfBDDoYtVnb1HTTxX +MuiGU0XQRLvdnytJX1Lk6NJg/UUUKhrVXiH05CZsxlPFjDlhEhp4Jh+f/mdf6llX +vsXn8k9ujBZBBD6PI4X7GkKB45H9zicbwt65f/MjhEohkbL5oZAKySzaUuMCAwEA +AQKCAgBF7uLCnH0UwUY0ZKEGuP+UDCjd/8JDB+QOJoe8fj722rTDkU3epk0PvPnh +SQKPtZlLkU5pDOMAtYjAJ8ULlERFGypM868QC8tmIahPvwRALqLwuJ2SJn0eo9JK ++Jb8ZVW3MY3xgjc4zW4SpEdEZSGbP4AklNF1X+n5UxxnRb1QIGcCSoiDUjFs77h8 +u70JyzXSh7GRa4/SHHdrJhjqhTa3mlOhoTuE72Np+P9H3adKLc70zKeifVxLx73j +mFiV73LEHYXrYC2zpA12BN0zvqCOSnPYHVfWfvrKiW/romt5j0IoA/Riabva3SiY +BRdBdUnnKvYS9Z+K/itI18QYI0lzSuLiaCTCo/3N/2MkuRMwS3Mvae7kK43/6c3w +sXobp8KBRMnpnT+AHENIHVJ35XKkWfTY9xMg/JkKbAXY06TitKW53ds03vb9Y9n2 +3SKBUcpbTkJJbJ50E/BiglLVxlllzVJiUIMNDGUmZO7eYQx9fs16cz4JkhzKcN+F +zYg4BVXL8blWU6AjXzexjTNuic/IxkqJruG05tCFwVxHjhajb9xQ1ANDMcXnwPmt +VKpU4KxrGqFgsVdZ5SE9gdu1g+zf96DdhXjHhZCfq6fsf2TYXD2SsUhx4kk9zOE/ +I4tXwf7Q7Ol24qlV9W8enc3gr1nk+buutl+I55LSM4bG4M3uQQKCAQEA/rkulfhl +wxStbVIICRl6iuC1nhqlxOBZAbc45pRgEDyTO5IfxnVA6kVCa5DkQ5cWZOoshKg9 +MNfHbo9JIYZzElnM/XxpmqIsHpQ+ZXe5XVaaYz9DogNnH2iLtQGVVLPphtxJxTqW +A6944GuhmZ9DmRwn0nN2nU0nUqBtLFio9+b7nChDaJj5aIkLHjx3p9ytjzzJP5nM +0lKSo9BD97+AhCaIT7NxjKSRWRs7ftf7Bv5vxPXrpgUN8ltkg4YVIzGX7UMXT+ga +H2kf+QkAJX1+9kbNMjkqhOH7zkv1DVqCVup9XewA2GltxoJZIVH04+QmgNWcS+XP +cbxe0r95tuMTqQKCAQEA6B6WYpC9UxXLPfOJdWDzSO3oh13RgQo1uEHdU9rc9vfi +vYZZsSL06uR7v6fuiuyAAayZgCTS1xr69MCAJR2056E3RthktAzOkfCJrcIyEHmy +b9yekRyL+R8P4HxV76AYqY52PhdgDntGoXb7hcGKt6hvkmcR41cnRHRjrb7zkEVy +55JY1woEVtt6otxHKZSnx5nlQct73Lv65QDfosfkESOmbE2W4G87XBk36I2YBywU +kNEr49tnI09qyEPJLjTTGxFdMeqXbnCgzSwqlBlrQE8NYJBsy2GBL0EWOYeRXkuz +RFug3o89uAOircy2virMhl6EOA0EKakWR4ZQCKlJqwKCAQEA40aBnYhL6/sIHtGh +n9Te9Qk4o4AtRnPSluhPWdUrvXD/AZkIxv+Z0y3G7MkUEoa9kX8sB5VBO9Jb/HbW +jpYzGD2N3OLkKvfmG8azwb9IYlLCYClzhBw7J9gVR4TJJBF/HThyjgsPDOzFEqCW +SMbE/tkTYwBo5kOQAXZo0res07yB5bw7IRnU94PHqsvTC7CoH3TiL+Bf042fj5Bl +BKoW1lK3Lz3x48Z2daYJuMynC398ZKX0A2bhIcyP65Z4R7WZVDaXl1GF9V7MC10P +h2PpI37a2aQOHxCvp0s4tBh80WZaQ7Iusumm7Acj1coVkjzgafWuhj3fkSC9DpeP +1zHXOQKCAQBCiVIOWvMKN/sUfRTwAqR6SUgYVXpShPy1Hpw1B03DtXbXYQWg0yZl +lq0qWRb116kx0aoGo4eUhXVeZzfUa9mJdBsGQc1MF0e3ab3tgvca5eeSTSle61Hs +TU0dykZP9BJduCqIzeaJAClU62haBQqgbrXcv5LPGhJ1eu9/xHbI6j9vxfGVYpev +1iYnPQFhF+2oN6MR4yRUN8ZJkqCIZsgnaZKxBOS03O2lDs2J6dykYaxbfroYDLJZ +2s//K/8lMZs57RZL0rUpwTs21Ow3m7m0q3RoM74b5o1DYGLghs3Su9xdQe6xHVpR +vykIrN/NTzNlaP55mrGQx5lNU2Dpuq0VAoIBAQDVCfAJlu+wkZmeXm1zUOFjOMvq +el3t55RCQ/SuhIpaNf2CWD6SOZfHfTxJ8nuYE+FJmjL6r9Z4a8ND0VPttuyBG6gY +siuZUE31+2OBvdKBhi4stqGZWMKJqYsDFH7QIfu7wSS1kuJ/vA7MB9f7IsrHJb2z +QBJoVMZoXhh4tqyFVatEp6yYSE4uKLvlKQSJ6W8DEuPggoiNPbhxQq2ctFUyup/S +9MsfJ9tj99mjlPSelMUXsHcsprIZBuhskfeidTe+gy43TBm0G8l7xeAGWkBlWQMR +L843JjebD6QCnPIS4nrW7kCRM8lv1ZId6D5Jq1Coc8b1ZrezfII7/eNgZZCv +-----END RSA PRIVATE KEY----- diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/jwtRS512.key.pub b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/jwtRS512.key.pub new file mode 100644 index 000000000..7191c95f8 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/jwtRS512.key.pub @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5vZBjfLjlUPK0b/F8FbG +AyT1jXNVv2vjl+ZGUlThDX1jn0WhXER5CL9CfkHKjJE47r8pQsO6nX9s5y+XzmAU +9+QggtaDA+g0Px+cvCJQzJbtDbh094m3uC50S+SSnYvr7vY1zy+jdswf/pXg1z05 +9FokRxGso36SkSv81NYbN/WQrTKogY6jkZXfPP8/sn8KV8uf7jYy2ZyHtakM9c9o +CopWH78mhf9ioUNbgJsAxZmiohQUN5a3GbLS/nsTBOcVxUezvjvfb732iChKoARj +3NiNN7HFHpXEXfiZ10OjrtAb9Y1K9RZsu/MKcFxBhDZusXjee6/x+NluQwT3Rybg +kCyV/i97Sroc37wOqimxtoSJ+MZYZXNAUGNbNySkjvIGL8jWMj6w/zvyiHVbQg+D +qY2Qds7Tdk29swYsMQQlz9v0FS/pGFVWo+5HTm+3MMlaMjSofw6j5/sE4OvJ4RCc +nX8Cj1Zq9PrsMLLSF5MBOCSiclpIC1EYQ9Oi6XrcL3bbyyKGwB/u1X1HHnUmhRdK +dVwKpSHR54XlfBDDoYtVnb1HTTxXMuiGU0XQRLvdnytJX1Lk6NJg/UUUKhrVXiH0 +5CZsxlPFjDlhEhp4Jh+f/mdf6llXvsXn8k9ujBZBBD6PI4X7GkKB45H9zicbwt65 +f/MjhEohkbL5oZAKySzaUuMCAwEAAQ== +-----END PUBLIC KEY----- diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/mdsalDynAuthData.json b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/mdsalDynAuthData.json new file mode 100644 index 000000000..a1627682b --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/mdsalDynAuthData.json @@ -0,0 +1,694 @@ +{ + "policies": [ + { + "resource": "/restconf/**", + "index": 0, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + } + ] + }, + { + "resource": "/auth/v1/**", + "index": 1, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + } + ] + }, + { + "resource": "/config/aaa*/**", + "index": 2, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + } + ] + }, + { + "resource": "/jolokia/**", + "index": 3, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "monitor", + "actions": [ + "get" + ] + }, + { + "role": "raftstate", + "actions": [ + "get" + ] + } + ] + }, + { + "resource": "/rests/data/network-topology:network-topology/topology=topology-netconf/node=513250004/**", + "index": 4, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "provisioner", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "huawei", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "planner", + "actions": [ + "get" + ] + }, + { + "role": "monitor", + "actions": [ + "get" + ] + } + ] + }, + { + "resource": "/rests/data/network-topology:network-topology/topology=topology-netconf/node=513250005/**", + "index": 5, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "provisioner", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "huawei", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "planner", + "actions": [ + "get" + ] + }, + { + "role": "monitor", + "actions": [ + "get" + ] + } + ] + }, + { + "resource": "/rests/data/network-topology:network-topology/topology=topology-netconf/node=513250006/**", + "index": 6, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "provisioner", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "siae", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "planner", + "actions": [ + "get" + ] + }, + { + "role": "monitor", + "actions": [ + "get" + ] + } + ] + }, + { + "resource": "/rests/data/network-topology:network-topology/topology=topology-netconf/node=513250007/**", + "index": 7, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "provisioner", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "siae", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "planner", + "actions": [ + "get" + ] + }, + { + "role": "monitor", + "actions": [ + "get" + ] + } + ] + }, + { + "resource": "/rests/data/network-topology:network-topology/topology=topology-netconf/node=513250008/**", + "index": 8, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "provisioner", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "siae", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "planner", + "actions": [ + "get" + ] + }, + { + "role": "monitor", + "actions": [ + "get" + ] + } + ] + }, + { + "resource": "/rests/data/network-topology:network-topology/topology=topology-netconf/node=513250009/**", + "index": 9, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "provisioner", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "siae", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "planner", + "actions": [ + "get" + ] + }, + { + "role": "monitor", + "actions": [ + "get" + ] + } + ] + }, + { + "resource": "/rests/data/network-topology:network-topology/topology=topology-netconf/node=513250010/**", + "index": 10, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "provisioner", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "ericsson", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "planner", + "actions": [ + "get" + ] + }, + { + "role": "monitor", + "actions": [ + "get" + ] + } + ] + }, + { + "resource": "/rests/data/network-topology:network-topology/topology=topology-netconf/node=513250011/**", + "index": 11, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "provisioner", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "ericsson", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "planner", + "actions": [ + "get" + ] + }, + { + "role": "monitor", + "actions": [ + "get" + ] + } + ] + }, + { + "resource": "/rests/data/network-topology:network-topology/topology=topology-netconf/node=513559991A/**", + "index": 14, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "provisioner", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "ericsson", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "planner", + "actions": [ + "get" + ] + }, + { + "role": "monitor", + "actions": [ + "get" + ] + } + ] + }, + { + "resource": "/rests/data/network-topology:network-topology/topology=topology-netconf/node=513559991B/**", + "index": 15, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "provisioner", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "ericsson", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "planner", + "actions": [ + "get" + ] + }, + { + "role": "monitor", + "actions": [ + "get" + ] + } + ] + }, + { + "resource": "/rests/data/network-topology:network-topology/topology=topology-netconf/node=513250012/**", + "index": 12, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "provisioner", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "zte", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "planner", + "actions": [ + "get" + ] + }, + { + "role": "monitor", + "actions": [ + "get" + ] + } + ] + }, + { + "resource": "/rests/data/network-topology:network-topology/topology=topology-netconf/node=513250013/**", + "index": 13, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "provisioner", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "zte", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "planner", + "actions": [ + "get" + ] + }, + { + "role": "monitor", + "actions": [ + "get" + ] + } + ] + }, + { + "resource": "/rests/data/network-topology:network-topology/topology=topology-netconf/**", + "index": 16, + "permissions": [ + { + "role": "admin", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "provisioner", + "actions": [ + "put", + "get", + "patch", + "delete", + "post" + ] + }, + { + "role": "planner", + "actions": [ + "get" + ] + }, + { + "role": "monitor", + "actions": [ + "get" + ] + } + ] + } + ] + } diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oauth/gitlab-groups-response.json b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oauth/gitlab-groups-response.json new file mode 100644 index 000000000..85fc37cc8 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oauth/gitlab-groups-response.json @@ -0,0 +1,112 @@ +[ + { + "id": 51, + "web_url": "https://my-git-server.com/groups/group1", + "name": "Group1", + "path": "group1", + "description": "", + "visibility": "private", + "share_with_group_lock": false, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "project_creation_level": "developer", + "auto_devops_enabled": null, + "subgroup_creation_level": "maintainer", + "emails_disabled": null, + "mentions_disabled": null, + "lfs_enabled": true, + "avatar_url": null, + "request_access_enabled": true, + "full_name": "Group1", + "full_path": "group1", + "parent_id": null + }, + { + "id": 69, + "web_url": "https://my-git-server.com/groups/group2", + "name": "Group2", + "path": "group2", + "description": "", + "visibility": "private", + "share_with_group_lock": false, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "project_creation_level": "developer", + "auto_devops_enabled": null, + "subgroup_creation_level": "owner", + "emails_disabled": null, + "mentions_disabled": null, + "lfs_enabled": true, + "avatar_url": null, + "request_access_enabled": true, + "full_name": "Group2", + "full_path": "group2", + "parent_id": null + }, + { + "id": 24, + "web_url": "https://my-git-server.com/groups/group3", + "name": "group3", + "path": "group3", + "description": "", + "visibility": "private", + "share_with_group_lock": false, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "project_creation_level": "developer", + "auto_devops_enabled": null, + "subgroup_creation_level": "owner", + "emails_disabled": null, + "mentions_disabled": null, + "lfs_enabled": true, + "avatar_url": null, + "request_access_enabled": false, + "full_name": "group3", + "full_path": "group3", + "parent_id": null + }, + { + "id": 22, + "web_url": "https://my-git-server.com/groups/group4", + "name": "group4", + "path": "group4", + "description": "custom desc", + "visibility": "private", + "share_with_group_lock": false, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "project_creation_level": "developer", + "auto_devops_enabled": null, + "subgroup_creation_level": "owner", + "emails_disabled": null, + "mentions_disabled": null, + "lfs_enabled": true, + "avatar_url": "https://my-git-server.com/uploads/-/system/group/avatar/22/Factory_1b.svg.png", + "request_access_enabled": true, + "full_name": "group4", + "full_path": "group4", + "parent_id": null + }, + { + "id": 5, + "web_url": "https://my-git-server.com/groups/group5", + "name": "group5", + "path": "group5", + "description": "my group 5", + "visibility": "private", + "share_with_group_lock": false, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "project_creation_level": "developer", + "auto_devops_enabled": null, + "subgroup_creation_level": "owner", + "emails_disabled": null, + "mentions_disabled": null, + "lfs_enabled": true, + "avatar_url": "https://my-git-server.com/uploads/-/system/group/avatar/5/mylogo.png", + "request_access_enabled": true, + "full_name": "group5", + "full_path": "group5", + "parent_id": null + } +]
\ No newline at end of file diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oauth/gitlab-token-response.json b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oauth/gitlab-token-response.json new file mode 100644 index 000000000..0a6bd7231 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oauth/gitlab-token-response.json @@ -0,0 +1,7 @@ +{ + "access_token":"asfhoipmspaodm-asndfoiasnf-aisjdaisjj", + "expires_in":12345, + "refresh_expires_in":123456, + "refresh_token":"asdsadasd", + "token_type":"bearer" +}
\ No newline at end of file diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oauth/gitlab-user-response.json b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oauth/gitlab-user-response.json new file mode 100644 index 000000000..b08332b41 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oauth/gitlab-user-response.json @@ -0,0 +1,32 @@ +{ + "id": 21, + "name": "me", + "username": "my-username", + "state": "active", + "avatar_url": "https://my-git-server.com/uploads/-/system/user/avatar/21/avatar.png", + "web_url": "https://my-git-server.com/my-username", + "created_at": "2017-05-15T14:49:38.396Z", + "bio": "", + "location": "", + "public_email": "", + "skype": "", + "linkedin": "", + "twitter": "", + "website_url": "", + "organization": "", + "last_sign_in_at": "2021-02-12T12:56:34.094Z", + "confirmed_at": "2018-01-18T09:49:08.463Z", + "last_activity_on": "2021-02-15", + "email": "me@my-server.com", + "theme_id": null, + "color_scheme_id": 1, + "projects_limit": 0, + "current_sign_in_at": "2021-02-15T03:17:12.140Z", + "identities": [], + "can_create_group": false, + "can_create_project": false, + "two_factor_enabled": false, + "external": false, + "private_profile": false, + "is_admin": true +}
\ No newline at end of file diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oauth/keycloak-token-response.json b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oauth/keycloak-token-response.json new file mode 100644 index 000000000..c62ed9458 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oauth/keycloak-token-response.json @@ -0,0 +1,11 @@ +{ + "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJkbWFSWXRkaHFkVXFDV2lmRWdNRHFBcWVBcU8tMnFoTDBjdnByelRGdWRRIn0.eyJleHAiOjE2MTExMzU5MjEsImlhdCI6MTYxMTEzNDEyMSwiYXV0aF90aW1lIjoxNjExMTM0MDkxLCJqdGkiOiIzYzFlZmMzZi1lMjFiLTQ3MzktYTY1YS1jNjY1M2ZhOGRjNTQiLCJpc3MiOiJodHRwOi8vMTAuMjAuMTEuMTYwOjgwODAvYXV0aC9yZWFsbXMvb25hcCIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiI0NDZhMjRiYy1kOGEwLTQzZGQtYWZhNS1lNTZlZWQ3NWRlYjgiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJvZGx1eC5hcHAiLCJzZXNzaW9uX3N0YXRlIjoiMTI5YjRhNjMtNzBhMS00MjFmLWEzM2YtOWFjZDkyZTIzM2ZmIiwiYWNyIjoiMSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJwcm92aXNpb24iLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwibmFtZSI6Ikx1a2UgU2t5d2Fsa2VyIiwicHJlZmVycmVkX3VzZXJuYW1lIjoibHVrZS5za3l3YWxrZXIiLCJnaXZlbl9uYW1lIjoiTHVrZSIsImZhbWlseV9uYW1lIjoiU2t5d2Fsa2VyIiwiZW1haWwiOiJsdWtlLnNreXdhbGtlckBzZG5yLm9uYXAub3JnIn0.tn2NrEGYLRq1u0DkqxD2iDM72hFrDBPGA_q23S-htiRH113yt14a0CzJxU9El0YDobbzog9xm0ELbx6W4jYsGguMABqIi4W5wtTqfbaCh7gmF208CqNpwzA7nG2palMLbBPpmGXiagUm4qLWQxrBP_VOaeW_kK0VHLaiTRJ-4vHuOXSNPYEDQZNCI2QCJQS_dn83K_JI4ecBHl8UeHFLB65BqmocpDHUvf2h835xuNFFQpXJWMcPM_j_FmFQeOSUDM4HmqgdVU9_b4APnDEVFiUezQdoEOfEYNsNlhCoXlaEEn2tCZfEkZ7k72DlhqJMQzomdaGKPk2g8XhKJNwMJg", + "expires_in": 1800, + "refresh_expires_in": 1800, + "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJhOGUzMDUwZS0wZmQxLTRjYjQtYjRiZS1jMDVlOGY4OGJhZGUifQ.eyJleHAiOjE2MTExMzU5MjEsImlhdCI6MTYxMTEzNDEyMSwianRpIjoiZmZiYWE3NDktZGVkNi00ZWMzLWI4MjYtYTI4NWY0ODY1ZGI0IiwiaXNzIjoiaHR0cDovLzEwLjIwLjExLjE2MDo4MDgwL2F1dGgvcmVhbG1zL29uYXAiLCJhdWQiOiJodHRwOi8vMTAuMjAuMTEuMTYwOjgwODAvYXV0aC9yZWFsbXMvb25hcCIsInN1YiI6IjQ0NmEyNGJjLWQ4YTAtNDNkZC1hZmE1LWU1NmVlZDc1ZGViOCIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJvZGx1eC5hcHAiLCJzZXNzaW9uX3N0YXRlIjoiMTI5YjRhNjMtNzBhMS00MjFmLWEzM2YtOWFjZDkyZTIzM2ZmIiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCJ9.mt9VHtiBZycHcEuVCOZVjjtyoOGYNaDVvtcA1NPScIQ", + "token_type": "bearer", + "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJkbWFSWXRkaHFkVXFDV2lmRWdNRHFBcWVBcU8tMnFoTDBjdnByelRGdWRRIn0.eyJleHAiOjE2MTExMzU5MjEsImlhdCI6MTYxMTEzNDEyMSwiYXV0aF90aW1lIjoxNjExMTM0MDkxLCJqdGkiOiJjZjUzZTc0ZC1kYjZiLTQ4YTUtODkyOS1jYzU3YjY3YjAxN2QiLCJpc3MiOiJodHRwOi8vMTAuMjAuMTEuMTYwOjgwODAvYXV0aC9yZWFsbXMvb25hcCIsImF1ZCI6Im9kbHV4LmFwcCIsInN1YiI6IjQ0NmEyNGJjLWQ4YTAtNDNkZC1hZmE1LWU1NmVlZDc1ZGViOCIsInR5cCI6IklEIiwiYXpwIjoib2RsdXguYXBwIiwic2Vzc2lvbl9zdGF0ZSI6IjEyOWI0YTYzLTcwYTEtNDIxZi1hMzNmLTlhY2Q5MmUyMzNmZiIsImF0X2hhc2giOiJSUXdDclpkQmFKV0VFdmxsRVNxRjV3IiwiYWNyIjoiMSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwibmFtZSI6Ikx1a2UgU2t5d2Fsa2VyIiwicHJlZmVycmVkX3VzZXJuYW1lIjoibHVrZS5za3l3YWxrZXIiLCJnaXZlbl9uYW1lIjoiTHVrZSIsImZhbWlseV9uYW1lIjoiU2t5d2Fsa2VyIiwiZW1haWwiOiJsdWtlLnNreXdhbGtlckBzZG5yLm9uYXAub3JnIn0.rueTNrnvRa4PMo7NS8l4xxRhhNiGzXLmtcUeyWnj3AjFaUoNKuS9l85K3KjRT3zjq494YsepIGuK33I20rvFwDLclcJNHuumAgBnR5dRBi5fLhm7x8YkebhdTHPiYL4hfygpZ7APN1PtcDZnb-uEjjT-RAtjnfk3r-oP6CtqWzI5MjOPnf5HaEwWpkuTjmJf3kyyf_pdhhVkgTwuC-kD8iMjyRIzuZJxVwWVA3S43eL0R7MaIDlpJrOp9EBRfMlObAypc1bLtKwopT0sBla1CM9GmUU2ZYbQb79-hey0rd7CWx1uBkZUxt5myiExBm3pI46boXLP7dzjzxHUKg0m-A", + "not-before-policy": 1611134054, + "session_state": "129b4a63-70a1-421f-a33f-9acd92e233ff", + "scope": "openid profile email" +}
\ No newline at end of file diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oom.test.config.json b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oom.test.config.json new file mode 100644 index 000000000..4e5707fa1 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/oom.test.config.json @@ -0,0 +1,21 @@ +{ + "tokenSecret": "secret", + "tokenIssuer": "ONAP SDNC", + "publicUrl": "https://sdnc.onap:30205", + "redirectUri": "null", + "supportOdlUsers": "true", + "providers": [ + { + "id": "htgit", + "type": "GITLAB", + "url": "https://git-.com", + "clientId": "f52440b7dcd4bb75", + "secret": "9bd45916f52440b7dcd4bb75", + "scope": "api+openid+read_user+profile", + "title": " Gitlab", + "roleMapping": { + "mygitlabgroup": "admin" + } + } + ] +}
\ No newline at end of file diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/test.config.json b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/test.config.json new file mode 100644 index 000000000..a55576b9e --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/test.config.json @@ -0,0 +1,20 @@ +{ + "tokenSecret": "secret2134", + "tokenIssuer": "ONAP SDNC", + "publicUrl": "http://nasp.diasf.de", + "redirectUri": "/index.html#redirect=", + "supportOdlUsers": "true", + "tokenLifetime":3600, + "providers": [ + { + "id": "keycloak", + "type": "KEYCLOAK", + "url": "http://10.20.11.160:8080", + "clientId": "odlux.app", + "secret": "5da4ea3d-8cc9-4669-bd7e-3ecb91d120cd", + "scope": "openid", + "title": "OSNL Keycloak Provider", + "realmName":"onap" + } + ] +}
\ No newline at end of file diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/test.configRS256-invalid.json b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/test.configRS256-invalid.json new file mode 100644 index 000000000..30b80c45a --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/test.configRS256-invalid.json @@ -0,0 +1,24 @@ +{ + "tokenSecret": "", + "tokenPubKey": "file:///src/test/resources/jwtRS256.key.pub", + "algorithm":"RS256", + "tokenIssuer": "ONAP SDNC", + "publicUrl": "http://nasp.diasf.de", + "redirectUri": "/index.html#redirect=", + "supportOdlUsers": "true", + "tokenLifetime":3600, + "providers": [ + { + "id": "keycloak", + "type": "KEYCLOAK", + "url": "http://10.20.11.160:8080", + "clientId": "odlux.app", + "secret": "5da4ea3d-8cc9-4669-bd7e-3ecb91d120cd", + "publickey": "", + "algorithm":"RS256", + "scope": "openid", + "title": "OSNL Keycloak Provider", + "realmName":"onap" + } + ] +}
\ No newline at end of file diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/test.configRS256.json b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/test.configRS256.json new file mode 100644 index 000000000..02a4e8f5f --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/test.configRS256.json @@ -0,0 +1,22 @@ +{ + "tokenSecret": "file:///src/test/resources/jwtRS256.key", + "tokenPubKey": "file:///src/test/resources/jwtRS256.key.pub", + "algorithm":"RS256", + "tokenIssuer": "ONAP SDNC", + "publicUrl": "http://nasp.diasf.de", + "redirectUri": "/index.html#redirect=", + "supportOdlUsers": "true", + "tokenLifetime":3600, + "providers": [ + { + "id": "keycloak", + "type": "KEYCLOAK", + "url": "http://10.20.11.160:8080", + "clientId": "odlux.app", + "secret": "5da4ea3d-8cc9-4669-bd7e-3ecb91d120cd", + "scope": "openid", + "title": "OSNL Keycloak Provider", + "realmName":"onap" + } + ] +}
\ No newline at end of file diff --git a/sdnr/wt/oauth-provider/oauth-core/src/test/resources/test.configRS512.json b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/test.configRS512.json new file mode 100644 index 000000000..eddc6c362 --- /dev/null +++ b/sdnr/wt/oauth-provider/oauth-core/src/test/resources/test.configRS512.json @@ -0,0 +1,22 @@ +{ + "tokenSecret": "file:///src/test/resources/jwtRS512.key", + "tokenPubKey": "file:///src/test/resources/jwtRS512.key.pub", + "algorithm":"RS512", + "tokenIssuer": "ONAP SDNC", + "publicUrl": "http://nasp.diasf.de", + "redirectUri": "/index.html#redirect=", + "supportOdlUsers": "true", + "tokenLifetime":3600, + "providers": [ + { + "id": "keycloak", + "type": "KEYCLOAK", + "url": "http://10.20.11.160:8080", + "clientId": "odlux.app", + "secret": "5da4ea3d-8cc9-4669-bd7e-3ecb91d120cd", + "scope": "openid", + "title": "OSNL Keycloak Provider", + "realmName":"onap" + } + ] +}
\ No newline at end of file |