From 00903933a3e7cb3344fba29ddd1454c6dd4a1782 Mon Sep 17 00:00:00 2001 From: Jerry Flood Date: Sat, 28 Sep 2019 04:56:23 -0400 Subject: Replace CADI interface to AAF Issue-ID: OPTFRA-593 Change-Id: I60b7ce1c79b912554e32aba00fa45c1d3890025a Signed-off-by: Jerry Flood --- cmso-topology/etc/config/topology.properties | 4 + .../org/onap/optf/cmso/aaf/AafAuthProvider.java | 82 ++++ .../onap/optf/cmso/aaf/AafAuthorizationFilter.java | 89 ---- .../java/org/onap/optf/cmso/aaf/AafClient.java | 185 ++++++++ .../org/onap/optf/cmso/aaf/AafClientCache.java | 265 +++++++++++ .../onap/optf/cmso/aaf/AafContainerFilters.java | 82 ++++ .../java/org/onap/optf/cmso/aaf/AafEndpoints.java | 74 +++ .../java/org/onap/optf/cmso/aaf/AafFilter.java | 82 ---- .../main/java/org/onap/optf/cmso/aaf/AafPerm.java | 240 ++++------ .../org/onap/optf/cmso/aaf/AafPermResponse.java | 46 ++ .../java/org/onap/optf/cmso/aaf/AafProperties.java | 52 +++ .../org/onap/optf/cmso/aaf/AafSecurityConfig.java | 56 --- .../java/org/onap/optf/cmso/aaf/AafUserRole.java | 375 ++++++++------- .../onap/optf/cmso/aaf/AafUserRoleProperties.java | 238 +++++----- .../java/org/onap/optf/cmso/aaf/BaseEndpoints.java | 123 +++++ .../org/onap/optf/cmso/aaf/EndpointInterface.java | 41 ++ .../org/onap/optf/cmso/aaf/FilterPriority.java | 42 -- .../org/onap/optf/cmso/aaf/ResponseFormatter.java | 45 -- .../org/onap/optf/cmso/aaf/SecurityConfig.java | 65 +++ .../META-INF/resources/swagger/swagger.json | 516 +++++++++++++++++++++ .../src/main/resources/application.properties | 2 +- 21 files changed, 1943 insertions(+), 761 deletions(-) create mode 100755 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafAuthProvider.java delete mode 100644 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafAuthorizationFilter.java create mode 100755 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafClient.java create mode 100755 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java create mode 100755 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java create mode 100755 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafEndpoints.java delete mode 100644 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafFilter.java mode change 100644 => 100755 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafPerm.java create mode 100755 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafPermResponse.java create mode 100755 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafProperties.java delete mode 100644 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafSecurityConfig.java mode change 100644 => 100755 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafUserRole.java mode change 100644 => 100755 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafUserRoleProperties.java create mode 100755 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/BaseEndpoints.java create mode 100755 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/EndpointInterface.java delete mode 100644 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/FilterPriority.java delete mode 100644 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/ResponseFormatter.java create mode 100755 cmso-topology/src/main/java/org/onap/optf/cmso/aaf/SecurityConfig.java create mode 100644 cmso-topology/src/main/resources/META-INF/resources/swagger/swagger.json (limited to 'cmso-topology') diff --git a/cmso-topology/etc/config/topology.properties b/cmso-topology/etc/config/topology.properties index 5ca252f..af3d8f4 100644 --- a/cmso-topology/etc/config/topology.properties +++ b/cmso-topology/etc/config/topology.properties @@ -28,3 +28,7 @@ # See the License for the specific language governing permissions and # limitations under the License. #------------------------------------------------------------------------------- +aaf.urls=https://aaf-onap-test.osaaf.org:8095 +aaf.user.role.properties=src/main/resources/aaf/AAFUserRoles.properties +aaf.enabled=true +aaf.namespace=org.onap.oof \ No newline at end of file diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafAuthProvider.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafAuthProvider.java new file mode 100755 index 0000000..328bd3e --- /dev/null +++ b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafAuthProvider.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2019 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * 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. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.aaf; + +import java.util.ArrayList; +import org.onap.optf.cmso.aaf.AafClientCache.AuthorizationResult; +import org.onap.optf.cmso.topology.SpringProfiles; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.core.env.Environment; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.WebAuthenticationDetails; +import org.springframework.stereotype.Component; + +@Component +@Profile(SpringProfiles.AAF_AUTHENTICATION) +public class AafAuthProvider implements AuthenticationProvider { + + @Autowired + Environment env; + + @Autowired + AafClientCache clientCache; + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + String name = authentication.getName(); + String password = authentication.getCredentials().toString(); + String sessionId = null; + Object details = authentication.getDetails(); + if (details instanceof WebAuthenticationDetails) { + WebAuthenticationDetails webAuthDetails = (WebAuthenticationDetails) details; + if (webAuthDetails.getSessionId() != null) { + sessionId = webAuthDetails.getRemoteAddress() + ":" + webAuthDetails.getSessionId(); + } + } + if (env.getProperty(AafProperties.aafEnabled.toString(), Boolean.class, true)) { + if (clientCache.authenticate(name, password, sessionId) != AuthorizationResult.Authenticated) { + return null; + } + } + return new UsernamePasswordAuthenticationToken(name, password, new ArrayList<>()); + + } + + @Override + public boolean supports(Class authentication) { + return authentication.equals(UsernamePasswordAuthenticationToken.class); + } +} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafAuthorizationFilter.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafAuthorizationFilter.java deleted file mode 100644 index 36e36f9..0000000 --- a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafAuthorizationFilter.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright © 2019 AT&T Intellectual Property. - * - * 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. - * - * - * Unless otherwise specified, all documentation contained herein is licensed under the Creative - * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except - * in compliance with the License. You may obtain a copy of the License at - * - * https://creativecommons.org/licenses/by/4.0/ - * - * Unless required by applicable law or agreed to in writing, documentation distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package org.onap.optf.cmso.aaf; - -import java.io.IOException; -import java.util.List; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.onap.aaf.cadi.CadiWrap; -import org.onap.aaf.cadi.Permission; -import org.onap.observations.Observation; -import org.onap.optf.cmso.common.exceptions.CmsoException; -import org.onap.optf.cmso.topology.SpringProfiles; -import org.onap.optf.cmso.topology.common.LogMessages; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter; -import org.springframework.context.annotation.Profile; -import org.springframework.stereotype.Component; - -/** - * AAF authorization filter. - */ - -@Component -@Profile(SpringProfiles.AAF_AUTHENTICATION) -public class AafAuthorizationFilter extends OrderedRequestContextFilter { - - @Autowired - AafUserRoleProperties userRoleProperties; - - /** - * Instantiates a new aaf authorization filter. - */ - public AafAuthorizationFilter() { - this.setOrder(FilterPriority.AAF_AUTHORIZATION.getPriority()); - - - } - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws IOException, ServletException { - try { - if (request instanceof CadiWrap) { - CadiWrap cw = (CadiWrap) request; - List perms = cw.getPermissions(cw.getUserPrincipal()); - if (userRoleProperties.processPermissions(request, perms)) { - filterChain.doFilter(request, response); - } else { - Observation.report(LogMessages.UNAUTHORIZED); - ResponseFormatter.errorResponse(request, response, new CmsoException( - LogMessages.UNAUTHORIZED.getStatus(), LogMessages.UNAUTHORIZED, "")); - } - } else { - throw new Exception(); - } - } catch (Exception e) { - Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage()); - ResponseFormatter.errorResponse(request, response, - new CmsoException(LogMessages.UNAUTHORIZED.getStatus(), LogMessages.UNAUTHORIZED, "")); - } - } -} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafClient.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafClient.java new file mode 100755 index 0000000..d550462 --- /dev/null +++ b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafClient.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2019 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * 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. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.aaf; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import javax.ws.rs.ProcessingException; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import org.onap.observations.Mdc; +import org.onap.observations.Observation; +import org.onap.optf.cmso.aaf.AafEndpoints.Endpoint; +import org.onap.optf.cmso.common.BasicAuthenticatorFilter; +import org.onap.optf.cmso.common.PropertiesManagement; +import org.onap.optf.cmso.common.exceptions.CmsoException; +import org.onap.optf.cmso.topology.SpringProfiles; +import org.onap.optf.cmso.topology.common.LogMessages; +import org.onap.optf.cmso.topology.filters.CmsoClientFilters; +import org.onap.optf.cmso.topology.service.rs.models.HealthCheckComponent; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +@Component +@Profile(SpringProfiles.AAF_AUTHENTICATION) +public class AafClient { + private static EELFLogger debug = EELFManager.getInstance().getDebugLogger(); + + @Autowired + Environment env; + + @Autowired + PropertiesManagement pm; + + @Autowired + AafEndpoints aafEndpoints; + + /** + * Gets the authz. + * + * @param auth the auth + * @return the authz + * @throws CmsoException the cmso exception + */ + public Response getAuthz(Map auth) throws CmsoException { + Response response = null; + List endpoints = new ArrayList<>(); + String url = aafEndpoints.getEndpoint(Endpoint.AUTHZ, endpoints); + String user = auth.get("user"); + if (!user.contains("@")) { + user += env.getProperty(AafProperties.aafDefaultUserDomain.toString(), "@csp.att.com"); + } + String pass = auth.get("password"); + while (url != null) { + try { + // Cannot provide changeId. Interesting. + // This should be replaced by fetch + // For now, make a best effort to get the passed changeId + if (!url.endsWith("/")) { + url += "/"; + } + url += user; + response = get(url, user, pass); + return response; + } catch (ProcessingException e) { + Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.toString()); + url = aafEndpoints.getNextEndpoint(Endpoint.AUTHZ, endpoints); + if (url == null || !tryNextUrl(e)) { + throw new CmsoException(Status.INTERNAL_SERVER_ERROR, LogMessages.UNEXPECTED_EXCEPTION, user, + e.getMessage()); + } + } catch (Exception e) { + Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.toString()); + throw new CmsoException(Status.INTERNAL_SERVER_ERROR, LogMessages.UNEXPECTED_EXCEPTION, user, + e.getMessage()); + } + } + return response; + } + + /** + * Gets the. + * + * @param url the url + * @param user the user + * @param pass the pass + * @return the response + */ + public Response get(String url, String user, String pass) { + Client client = ClientBuilder.newClient(); + client.register(new BasicAuthenticatorFilter(user, pass)); + client.register(new CmsoClientFilters()); + WebTarget target = client.target(url); + Invocation.Builder invocationBuilder = target.request(MediaType.APPLICATION_JSON); + debug.debug("AAF URL = " + url); + Response response = invocationBuilder.get(); + debug.debug("AAF URL = " + url + " user=" + user + ":" + response.getStatusInfo().toString()); + return response; + } + + private boolean tryNextUrl(ProcessingException exc) { + if (exc.getCause() instanceof UnknownHostException) { + return true; + } + return true; + } + + /** + * Health check. + * + * @return the health check component + */ + public HealthCheckComponent healthCheck() { + Map mdcSave = Mdc.save(); + HealthCheckComponent hcc = new HealthCheckComponent(); + hcc.setName("AAF"); + hcc.setHealthy(false); + List endpoints = new ArrayList<>(); + try { + String url = aafEndpoints.getEndpoint(AafEndpoints.Endpoint.HEALTHCHECK, endpoints); + String user = ""; + String pass = ""; + + while (url != null) { + try { + hcc.setUrl(url); + Response response = get(url, user, pass); + hcc.setHealthy(true); + hcc.setStatus(response.getStatusInfo().toString()); + } catch (ProcessingException e) { + Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.toString()); + url = aafEndpoints.getNextEndpoint(AafEndpoints.Endpoint.HEALTHCHECK, endpoints); + if (url == null || !tryNextUrl(e)) { + hcc.setStatus(e.getMessage()); + } + } catch (Exception e) { + Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.toString()); + hcc.setStatus(e.getMessage()); + } + } + } finally { + Mdc.restore(mdcSave); + } + return hcc; + } +} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java new file mode 100755 index 0000000..1b2facb --- /dev/null +++ b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2019 AT&T Intellectual Property. Modifications Copyright © 2018 IBM. + * + * 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. + * + * + * Unless otherwise specified, all documentation contained herein is licensed under the Creative + * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except + * in compliance with the License. You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.optf.cmso.aaf; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.security.Principal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.core.Response; +import javax.xml.bind.DatatypeConverter; +import org.onap.observations.Observation; +import org.onap.optf.cmso.topology.SpringProfiles; +import org.onap.optf.cmso.topology.common.LogMessages; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.core.env.Environment; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.web.authentication.WebAuthenticationDetails; +import org.springframework.stereotype.Component; + +/** + * The Class AafClientCache. + */ +@Component +@Profile(SpringProfiles.AAF_AUTHENTICATION) +public class AafClientCache { + private static EELFLogger debug = EELFManager.getInstance().getDebugLogger(); + + @Autowired + Environment env; + + @Autowired + AafClient aafClient; + + @Autowired + AafUserRoleProperties aafUserRoleProperties; + + public enum AuthorizationResult { + + Authorized(0), AuthenticationFailure(401), AuthorizationFailure(403), Authenticated(0),; + private final int status; + + AuthorizationResult(int status) { + this.status = status; + } + + public int getStatus() { + return status; + } + } + + private Map cache = new HashMap<>(); + private Long cacheAge = 0L; + + /** + * Authorize. + * + * @param requestContext the request context + * @return the authorization result + */ + public AuthorizationResult authorize(ContainerRequestContext requestContext) { + if (!env.getProperty(AafProperties.aafEnabled.toString(), Boolean.class, true)) { + return AuthorizationResult.Authorized; + } + Map auth = getUserPasssword(requestContext); + String permissions = getPermissions(auth); + if (permissions == null) { + return AuthorizationResult.AuthenticationFailure; + } + return processPermissions(auth, permissions); + } + + /** + * Authenticate. + * + * @param user the user + * @param password the password + * @param sessionId the session id + * @return the authorization result + */ + public AuthorizationResult authenticate(String user, String password, String sessionId) { + Map auth = new HashMap<>(); + auth.put("user", user); + auth.put("password", password); + if (sessionId != null) { + auth.put("sessionId", sessionId); + } + if (getPermissions(auth) == null) { + return AuthorizationResult.AuthenticationFailure; + } + return AuthorizationResult.Authenticated; + } + + + private String getPermissions(Map auth) { + long now = System.currentTimeMillis(); + Long timeout = env.getProperty(AafProperties.aafCacheTimeout.toString(), Long.class, 300L); + String permissions = null; + // Do caching logic + // Serializes calls to AAF + // We will not cache authentication failures... + synchronized (cache) { + debug.debug("AAF cache now=" + now + ", cacheAge=" + cacheAge + " timeout=" + timeout); + if (cacheAge != 0 && now > (cacheAge + (timeout * 1000))) { + debug.debug("Clearing the AAF cache now=" + now + ", cacheAge=" + cacheAge + " timeout=" + timeout); + cache.clear(); + cacheAge = now; + } + if (cacheAge == 0) { + cacheAge = now; + } + permissions = cache.get(getCacheKey(auth)); + if (permissions == null) { + if (!auth.get("password").equals("")) { + permissions = getPermissionsFromAaf(auth); + if (permissions != null) { + cache.put(getCacheKey(auth), permissions); + } + } + } + } + return permissions; + } + + private String getCacheKey(Map auth) { + if (auth.get("sessionId") != null) { + return auth.get("user") + "|" + auth.get("sessionId"); + } + return auth.get("user") + "|" + auth.get("password"); + } + + + private String getPermissionsFromAaf(Map auth) { + try { + Response response = aafClient.getAuthz(auth); + debug.debug("AAF authorization: " + response.getStatusInfo().toString()); + switch (response.getStatus()) { + case 200: + String permissions = response.readEntity(String.class); + return permissions; + case 401: + return null; + default: + Observation.report(LogMessages.UNEXPECTED_RESPONSE, "AAF", response.getStatusInfo().toString(), + auth.get("user")); + } + } catch (Exception e) { + Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage()); + } + return null; + } + + private AuthorizationResult processPermissions(Map auth, String permissions) { + try { + List perms = aafUserRoleProperties.getForUrlMethod(auth.get("path"), auth.get("method")); + ObjectMapper om = new ObjectMapper(); + AafPermResponse resp = om.readValue(permissions, AafPermResponse.class); + int tested = 0; + int passed = 0; + for (AafUserRole perm : perms) { + for (AafPerm test : perm.getAafPerms()) { + tested++; + for (AafPerm userPerm : resp.getPerm()) { + + if (test.ok(userPerm)) { + passed++; + break; + } + } + } + } + // All permissions must be OK + if (tested > 0 && tested == passed) { + return AuthorizationResult.Authorized; + } else { + return AuthorizationResult.AuthorizationFailure; + } + } catch (Exception e) { + Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage()); + } + return AuthorizationResult.AuthenticationFailure; + } + + private Map getUserPasssword(ContainerRequestContext requestContext) { + + String header = requestContext.getHeaderString("Authorization"); + Map userPassword = getUserPasswordFromAuthorizationHeader(header); + // Add other stuff.... + userPassword.put("path", requestContext.getUriInfo().getAbsolutePath().getPath()); + userPassword.put("method", requestContext.getMethod()); + Principal principal = requestContext.getSecurityContext().getUserPrincipal(); + if (principal instanceof UsernamePasswordAuthenticationToken) { + UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) principal; + Object object = token.getDetails(); + if (object instanceof WebAuthenticationDetails) { + WebAuthenticationDetails details = (WebAuthenticationDetails) object; + if (details.getSessionId() != null) { + String sessionId = details.getRemoteAddress() + ":" + details.getSessionId(); + userPassword.put("sessionId", sessionId); + userPassword.put("user", token.getName()); + } + + } + } + return userPassword; + } + + private Map getUserPasswordFromAuthorizationHeader(String header) { + Map userPassword = new HashMap<>(); + userPassword.put("user", ""); + userPassword.put("password", ""); + if (header != null) { + String[] auth = header.split("Basic "); + if (auth.length == 2) { + String token = getToken(auth[1]); + if (token.contains(":")) { + String[] tokens = token.split(":"); + userPassword.put("user", tokens[0]); + if (tokens.length == 2) { + userPassword.put("password", tokens[1]); + } + } + } + } + return userPassword; + } + + private String getToken(String auth) { + try { + String token = new String(DatatypeConverter.parseBase64Binary(auth)); + return token; + } catch (Exception e) { + return auth; + } + } + +} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java new file mode 100755 index 0000000..595017b --- /dev/null +++ b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2019 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * 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. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.aaf; + +import java.io.IOException; +import javax.annotation.Priority; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.ext.Provider; +import org.onap.observations.Observation; +import org.onap.optf.cmso.aaf.AafClientCache.AuthorizationResult; +import org.onap.optf.cmso.topology.SpringProfiles; +import org.onap.optf.cmso.topology.common.LogMessages; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Component; + +@Priority(1) +@Provider +@Component +@Profile(SpringProfiles.AAF_AUTHENTICATION) +public class AafContainerFilters implements ContainerRequestFilter { + + @Autowired + AafClientCache aafClientCache; + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + ResponseBuilder builder = null; + AuthorizationResult status = null; + try { + status = aafClientCache.authorize(requestContext); + } catch (Exception e) { + Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage()); + status = AuthorizationResult.AuthenticationFailure; + } + switch (status) { + case AuthenticationFailure: + builder = Response.status(Response.Status.UNAUTHORIZED).entity(""); + builder.header("WWW-Authenticate", "Basic realm=\"Realm\""); + throw new WebApplicationException(builder.build()); + case AuthorizationFailure: + builder = Response.status(Response.Status.FORBIDDEN).entity(""); + throw new WebApplicationException(builder.build()); + case Authorized: + case Authenticated: + default: + } + } +} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafEndpoints.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafEndpoints.java new file mode 100755 index 0000000..e9c9181 --- /dev/null +++ b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafEndpoints.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2019 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * 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. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.aaf; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +/** + * Intent is to use AAF vanity URL however, this allows us to support a list of URLs. + * + */ +@Component +public class AafEndpoints extends BaseEndpoints { + + @Autowired + Environment env; + + public enum Endpoint implements EndpointInterface { + AUTHZ(AafProperties.aafAuthzPath, "/authz/perms/user/"), HEALTHCHECK(AafProperties.aafHealthCheckPath, "/"),; + + private final AafProperties pathName; + private final String defaultPath; + + private Endpoint(AafProperties pathname, String defaultPath) { + this.pathName = pathname; + this.defaultPath = defaultPath; + } + + @Override + public AafProperties getPathName() { + return pathName; + } + + @Override + public String defaultPath() { + return defaultPath; + } + + @Override + public EndpointInterface[] getValues() { + return Endpoint.values(); + } + } +} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafFilter.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafFilter.java deleted file mode 100644 index a72a979..0000000 --- a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafFilter.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright © 2019 AT&T Intellectual Property. - * - * 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. - * - * - * Unless otherwise specified, all documentation contained herein is licensed under the Creative - * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except - * in compliance with the License. You may obtain a copy of the License at - * - * https://creativecommons.org/licenses/by/4.0/ - * - * Unless required by applicable law or agreed to in writing, documentation distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package org.onap.optf.cmso.aaf; - -import java.io.IOException; -import java.util.Properties; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.onap.aaf.cadi.PropAccess; -import org.onap.aaf.cadi.filter.CadiFilter; -import org.onap.observations.Observation; -import org.onap.optf.cmso.common.exceptions.CmsoException; -import org.onap.optf.cmso.topology.Application; -import org.onap.optf.cmso.topology.SpringProfiles; -import org.onap.optf.cmso.topology.common.LogMessages; -import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter; -import org.springframework.context.annotation.Profile; -import org.springframework.stereotype.Component; - -/** - * AAF authentication filter. - */ - -@Component -@Profile(SpringProfiles.AAF_AUTHENTICATION) -public class AafFilter extends OrderedRequestContextFilter { - - private final CadiFilter cadiFilter; - - /** - * Instantiates a new aaf filter. - * - * @throws IOException Signals that an I/O exception has occurred. - * @throws ServletException the servlet exception - */ - public AafFilter() throws IOException, ServletException { - Properties cadiProperties = new Properties(); - cadiProperties.load(Application.class.getClassLoader().getResourceAsStream("cadi.properties")); - cadiFilter = new CadiFilter(new PropAccess(cadiProperties)); - this.setOrder(FilterPriority.AAF_AUTHENTICATION.getPriority()); - } - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws IOException, ServletException { - cadiFilter.doFilter(request, response, filterChain); - if (response.getStatus() == 401) { - Observation.report(LogMessages.UNAUTHENTICATED); - ResponseFormatter.errorResponse(request, response, - new CmsoException(LogMessages.UNAUTHENTICATED.getStatus(), - LogMessages.UNAUTHENTICATED, "")); - } - } - - -} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafPerm.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafPerm.java old mode 100644 new mode 100755 index 278f3ab..d324f18 --- a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafPerm.java +++ b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafPerm.java @@ -1,137 +1,103 @@ -/* - * Copyright © 2019 AT&T Intellectual Property. - * - * 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. - * - * - * Unless otherwise specified, all documentation contained herein is licensed under the Creative - * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except - * in compliance with the License. You may obtain a copy of the License at - * - * https://creativecommons.org/licenses/by/4.0/ - * - * Unless required by applicable law or agreed to in writing, documentation distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package org.onap.optf.cmso.aaf; - -import java.util.HashSet; -import java.util.Set; -import org.onap.aaf.cadi.aaf.AAFPermission; - - -/** - * The Class AafPerm. - */ -public class AafPerm { - private String type; - private String instance; - private String action; - private Set actions = new HashSet<>(); - - /** - * Gets the action. - * - * @return the action - */ - public String getAction() { - return action; - } - - /** - * Sets the action. - * - * @param action the new action - */ - public void setAction(String action) { - this.action = action; - String[] list = action.split(","); - for (String a : list) { - actions.add(a); - } - } - - /** - * Gets the type. - * - * @return the type - */ - public String getType() { - return type; - } - - /** - * Sets the type. - * - * @param type the new type - */ - public void setType(String type) { - this.type = type; - } - - /** - * Gets the single instance of AafPerm. - * - * @return single instance of AafPerm - */ - public String getInstance() { - return instance; - } - - /** - * Sets the instance. - * - * @param instance the new instance - */ - public void setInstance(String instance) { - this.instance = instance; - } - - /** - * Gets the actions. - * - * @return the actions - */ - public Set getActions() { - return actions; - } - - /** - * Sets the actions. - * - * @param actions the new actions - */ - public void setActions(Set actions) { - this.actions = actions; - } - - /** - * Matches. - * - * @param userPerm the user perm - * @return true, if successful - */ - public boolean matches(AAFPermission userPerm) { - if (type.equals(userPerm.getType())) { - if (userPerm.getInstance().equals("*") || instance.equals("*") || userPerm.getInstance().equals(instance)) { - for (String userAction : userPerm.getAction().split(",")) { - if (userAction.equals("*") || actions.contains("*") || actions.contains(userAction)) { - return true; - } - } - } - } - return false; - } -} +/* + * Copyright (c) 2019 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * 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. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.aaf; + +import java.util.HashSet; +import java.util.Set; + + +public class AafPerm { + private String type; + private String instance; + private String action; + private Set actions = new HashSet<>(); + + public String getAction() { + return action; + } + + /** + * Initialize the actions. + * + * @param action action list + */ + public void setAction(String action) { + this.action = action; + String[] list = action.split(","); + for (String a : list) { + actions.add(a); + } + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getInstance() { + return instance; + } + + public void setInstance(String instance) { + this.instance = instance; + } + + public Set getActions() { + return actions; + } + + public void setActions(Set actions) { + this.actions = actions; + } + + /** + * Are permissions ok. + * + * @param userPerm user permissions + * @return true = permissions ok + */ + public boolean ok(AafPerm userPerm) { + if (type.equals(userPerm.getType())) { + if (userPerm.getInstance().equals("*") || instance.equals("*") || userPerm.getInstance().equals(instance)) { + for (String userAction : userPerm.getActions()) { + if (userAction.equals("*") || actions.contains("*") || actions.contains(userAction)) { + return true; + } + } + } + } + return false; + } +} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafPermResponse.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafPermResponse.java new file mode 100755 index 0000000..caf2b62 --- /dev/null +++ b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafPermResponse.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * 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. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.aaf; + +import java.util.List; + +public class AafPermResponse { + private List perm; + + public List getPerm() { + return perm; + } + + public void setPerm(List list) { + this.perm = list; + } +} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafProperties.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafProperties.java new file mode 100755 index 0000000..00758e5 --- /dev/null +++ b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafProperties.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * 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. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.aaf; + +public enum AafProperties { + mechidUser("mechid.user"), mechidPass("mechid.pass"), aafUrls("aaf.urls"), aafAuthzPath( + "aaf.path.authz"), aafHealthCheckPath("aaf.path.healthcheck"), aafCacheTimeout( + "aaf.cache.timeout"), aafUserRoleProperties( + "aaf.user.role.properties"), aafDefaultUserDomain( + "aaf.default.user.domain"), aafEnabled( + "aaf.enabled"), aafNamespace( + "aaf.namespace"),; + private final String text; + + private AafProperties(String text) { + this.text = text; + } + + @Override + public String toString() { + return text; + } +} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafSecurityConfig.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafSecurityConfig.java deleted file mode 100644 index 787d786..0000000 --- a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafSecurityConfig.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright © 2019 AT&T Intellectual Property. - * - * 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. - * - * - * Unless otherwise specified, all documentation contained herein is licensed under the Creative - * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except - * in compliance with the License. You may obtain a copy of the License at - * - * https://creativecommons.org/licenses/by/4.0/ - * - * Unless required by applicable law or agreed to in writing, documentation distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onap.optf.cmso.aaf; - -import org.onap.optf.cmso.topology.SpringProfiles; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; - -@Configuration -@EnableWebSecurity -@ComponentScan("org.onap.optf") -@Profile(SpringProfiles.AAF_AUTHENTICATION) -public class AafSecurityConfig extends WebSecurityConfigurerAdapter { - - - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - - http.csrf().disable(); - - } -} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafUserRole.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafUserRole.java old mode 100644 new mode 100755 index 17e3c22..7c5b6e2 --- a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafUserRole.java +++ b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafUserRole.java @@ -1,176 +1,199 @@ -/* - * Copyright © 2019 AT&T Intellectual Property. - * - * 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. - * - * - * Unless otherwise specified, all documentation contained herein is licensed under the Creative - * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except - * in compliance with the License. You may obtain a copy of the License at - * - * https://creativecommons.org/licenses/by/4.0/ - * - * Unless required by applicable law or agreed to in writing, documentation distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package org.onap.optf.cmso.aaf; - -import java.util.ArrayList; -import java.util.List; - -/** - * The Class AafUserRole. - */ -public class AafUserRole { - private String url = ""; - private String[] pathParts = {}; - private String perm = ""; - private String method = ""; - private List aafPerms = new ArrayList<>(); - - /** - * Instantiates a new aaf user role. - * - * @param url the url - * @param perm the perm - */ - public AafUserRole(String url, String perm) { - this.setUrl(url); - this.setPerm(perm); - pathParts = url.split("\\/"); - - String[] perms = perm.split(","); - for (String p : perms) { - String[] parts = p.split(" "); - if (parts.length == 2) { - method = parts[1]; - } else { - method = "ALL"; - } - - String[] list = parts[0].split("\\|"); - if (list.length == 3) { - AafPerm aafPerm = new AafPerm(); - aafPerm.setAction(list[2]); - aafPerm.setInstance(list[1]); - aafPerm.setType(list[0]); - aafPerms.add(aafPerm); - } - } - } - - /** - * Gets the url. - * - * @return the url - */ - public String getUrl() { - return url; - } - - /** - * Sets the url. - * - * @param url the new url - */ - public void setUrl(String url) { - this.url = url; - } - - /** - * Gets the perm. - * - * @return the perm - */ - public String getPerm() { - return perm; - } - - /** - * Sets the perm. - * - * @param perm the new perm - */ - public void setPerm(String perm) { - this.perm = perm; - } - - /** - * Gets the aaf perms. - * - * @return the aaf perms - */ - public List getAafPerms() { - return aafPerms; - } - - /** - * Sets the aaf perms. - * - * @param aafPerms the new aaf perms - */ - public void setAafPerms(List aafPerms) { - this.aafPerms = aafPerms; - } - - /** - * Matches. - * - * @param path the path - * @param matchMethod the match method - * @return true, if successful - */ - public boolean matches(String path, String matchMethod) { - if (!this.method.equalsIgnoreCase("ALL") && !this.method.equals("*") && !this.method.equals(matchMethod)) { - return false; - } - List inNodes = new ArrayList<>(); - List matchNodes = new ArrayList<>(); - String[] pathList = path.split("\\/"); - for (String n : pathList) { - inNodes.add(n); - } - for (String n : pathParts) { - matchNodes.add(n); - } - - while (!inNodes.isEmpty() && !matchNodes.isEmpty()) { - String inNode = inNodes.remove(0); - String matchNode = matchNodes.get(0); - if (matchNode.equals(inNode) || matchNode.equals("*")) { - matchNodes.remove(0); - } else { - if (!matchNode.equals("**")) { - return false; - } - } - } - - // - if (inNodes.isEmpty() && matchNodes.isEmpty()) { - return true; - } - - // We have incoming nodes remaining, see if we can wildcard them - if (matchNodes.size() == 1) { - if (matchNodes.get(0).equals("**")) { - return true; - } - if (inNodes.size() == 1 && matchNodes.get(0).equals("*")) { - return true; - } - } - return false; - } -} +/* + * Copyright (c) 2019 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * 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. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.aaf; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.ArrayList; +import java.util.List; +import org.onap.observations.Observation; +import org.onap.optf.cmso.topology.common.LogMessages; + +/** + * The Class AafUserRole. + */ +public class AafUserRole { + private String url = ""; + private String[] pathParts = {}; + private String perm = ""; + private String method = ""; + private List aafPerms = new ArrayList<>(); + + /** + * Instantiates a new aaf user role. + * + * @param url the url + * @param perm the perm + */ + public AafUserRole(String url, String perm) { + this.setUrl(url); + this.setPerm(perm); + pathParts = url.split("\\/"); + + String[] perms = perm.split(","); + for (String p : perms) { + String[] parts = p.split(" "); + if (parts.length == 2) { + method = parts[1]; + } + else { + method = "ALL"; + } + + String[] list = parts[0].split("\\|"); + if (list.length == 3) { + AafPerm aafPerm = new AafPerm(); + aafPerm.setAction(list[2]); + aafPerm.setInstance(list[1]); + aafPerm.setType(list[0]); + aafPerms.add(aafPerm); + } + } + } + + /** + * Gets the url. + * + * @return the url + */ + public String getUrl() { + return url; + } + + /** + * Sets the url. + * + * @param url the new url + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * Gets the perm. + * + * @return the perm + */ + public String getPerm() { + return perm; + } + + /** + * Sets the perm. + * + * @param perm the new perm + */ + public void setPerm(String perm) { + this.perm = perm; + } + + /** + * Gets the aaf perms. + * + * @return the aaf perms + */ + public List getAafPerms() { + return aafPerms; + } + + /** + * Sets the aaf perms. + * + * @param aafPerms the new aaf perms + */ + public void setAafPerms(List aafPerms) { + this.aafPerms = aafPerms; + } + + /** + * Matches. + * + * @param path the path + * @param matchMethod the match method + * @return true, if successful + */ + public boolean matches(String path, String matchMethod) { + if (!this.method.equals("ALL") && !this.method.equals(matchMethod)) { + return false; + } + List inNodes = new ArrayList<>(); + List matchNodes = new ArrayList<>(); + String[] pathList = path.split("\\/"); + for (String n : pathList) { + inNodes.add(n); + } + for (String n : pathParts) { + matchNodes.add(n); + } + + while (!inNodes.isEmpty() && !matchNodes.isEmpty()) { + String inNode = inNodes.remove(0); + String matchNode = matchNodes.get(0); + if (matchNode.equals(inNode) || matchNode.equals("*")) { + matchNodes.remove(0); + } else { + if (!matchNode.equals("**")) { + return false; + } + } + } + + // + if (inNodes.isEmpty() && matchNodes.isEmpty()) { + return true; + } + + // We have incoming nodes remaining, see if we can wildcard them + if (matchNodes.size() == 1) { + if (matchNodes.get(0).equals("**")) { + return true; + } + if (inNodes.size() == 1 && matchNodes.get(0).equals("*")) { + return true; + } + } + return false; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + try { + return new ObjectMapper().writeValueAsString(this); + } catch (JsonProcessingException e) { + Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.toString()); + } + return this.url; + } +} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafUserRoleProperties.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafUserRoleProperties.java old mode 100644 new mode 100755 index 7c39fc9..882c222 --- a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafUserRoleProperties.java +++ b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/AafUserRoleProperties.java @@ -1,133 +1,105 @@ -/* - * Copyright © 2019 AT&T Intellectual Property. - * - * 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. - * - * - * Unless otherwise specified, all documentation contained herein is licensed under the Creative - * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except - * in compliance with the License. You may obtain a copy of the License at - * - * https://creativecommons.org/licenses/by/4.0/ - * - * Unless required by applicable law or agreed to in writing, documentation distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package org.onap.optf.cmso.aaf; - -import java.io.File; -import java.io.FileInputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import javax.annotation.PostConstruct; -import javax.servlet.http.HttpServletRequest; -import org.onap.aaf.cadi.Permission; -import org.onap.aaf.cadi.aaf.AAFPermission; -import org.onap.observations.Observation; -import org.onap.optf.cmso.topology.SpringProfiles; -import org.onap.optf.cmso.topology.common.LogMessages; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Profile; -import org.springframework.core.env.Environment; -import org.springframework.stereotype.Component; - -/** - * This class uses a properties file to map URL patterns/method to AAF Permissions (AafPerm). - * - * @author jf9860 - * - */ -@Component -@Profile(SpringProfiles.AAF_AUTHENTICATION) -public class AafUserRoleProperties { - @Autowired - Environment env; - - private List list = new ArrayList<>(); - - /** - * Initialize permissions. - */ - @PostConstruct - public void initializePermissions() { - String userRolePropertiesName = - env.getProperty("aaf.user.roles", "src/main/resources/aaf/AAFUserRoles.properties"); - Properties props = new Properties(); - try { - props.load(new FileInputStream(new File(userRolePropertiesName))); - } catch (Exception e) { - Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage()); - } - for (Object url : props.keySet()) { - Object value = props.get(url); - list.add(new AafUserRole((String) url, (String) value)); - } - } - - /** - * Gets the for url method. - * - * @param url the url - * @param method the method - * @return the for url method - */ - public List getForUrlMethod(String url, String method) { - List userRoleList = new ArrayList<>(); - for (AafUserRole aur : list) { - if (aur.matches(url, method)) { - userRoleList.add(aur); - } - } - return userRoleList; - } - - /** - * Process permissions. - * - * @param request the request - * @param userPerms the user perms - * @return true, if successful - */ - public boolean processPermissions(HttpServletRequest request, List userPerms) { - try { - // Get list of perms that match incoming URL. May be more than 1... - // Users perms must match all that match URL - List perms = getForUrlMethod(request.getRequestURI(), request.getMethod()); - int tested = 0; - int passed = 0; - for (AafUserRole perm : perms) { - for (AafPerm test : perm.getAafPerms()) { - tested++; - for (Permission userPerm : userPerms) { - - if (test.matches((AAFPermission) userPerm)) { - passed++; - break; - } - } - } - } - // All permissions must be OK - if (tested > 0 && tested == passed) { - return true; - } else { - return false; - } - } catch (Exception e) { - Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage()); - } - return false; - } -} +/* + * Copyright (c) 2019 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * 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. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.aaf; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.PostConstruct; +import org.onap.observations.Observation; +import org.onap.optf.cmso.topology.SpringProfiles; +import org.onap.optf.cmso.topology.common.LogMessages; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +/** + * The Class AafUserRoleProperties. + */ +@Component +@Profile(SpringProfiles.AAF_AUTHENTICATION) +public class AafUserRoleProperties { + private static EELFLogger debug = EELFManager.getInstance().getDebugLogger(); + + /** The env. */ + @Autowired + Environment env; + + private List list = new ArrayList<>(); + + /** + * Initialize permissions. + */ + @PostConstruct + public void initializePermissions() { + String userRolePropertiesName = env.getProperty(AafProperties.aafUserRoleProperties.toString(), + "opt/att/ajsc/config/AAFUserRoles.properties"); + try { + List lines = Files.readAllLines(Paths.get(userRolePropertiesName)); + for (String line : lines) { + line = line.trim(); + if (!line.startsWith("#")) { + String[] parts = line.split("="); + if (parts.length == 2) { + list.add(new AafUserRole(parts[0], env.resolvePlaceholders(parts[1]))); + } else { + Observation.report(LogMessages.INVALID_ATTRIBUTE, line, userRolePropertiesName); + } + } + } + } catch (Exception e) { + Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage()); + } + debug.debug("AafUserRole.properties: " + list); + } + + /** + * Gets the for url method. + * + * @param url the url + * @param method the method + * @return the for url method + */ + public List getForUrlMethod(String url, String method) { + List userRoleList = new ArrayList<>(); + for (AafUserRole aur : list) { + if (aur.matches(url, method)) { + userRoleList.add(aur); + } + } + return userRoleList; + } +} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/BaseEndpoints.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/BaseEndpoints.java new file mode 100755 index 0000000..1027ade --- /dev/null +++ b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/BaseEndpoints.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2019 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * 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. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.aaf; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +/** + * Intent is to use AAF vanity URL however, this allows us to support a list of URLs. + */ +@Component +public class BaseEndpoints { + + @Autowired + Environment env; + + private Map> endpointMap = new HashMap<>(); + private Map endpointMapOk = new HashMap<>(); + + /** + * Gets the endpoint. + * + * @param ep the ep + * @param endpoints the endpoints + * @return the endpoint + */ + public String getEndpoint(EndpointInterface ep, List endpoints) { + loadUrls(ep); + endpoints.clear(); + endpoints.addAll(endpointMap.get(ep)); + String endpoint = null; + if (endpoints.size() > 0) { + // Make an attempt to return the most recent "working" endpoint. + // + synchronized (endpointMapOk) { + endpoint = endpointMapOk.get(ep); + if (endpoint == null) { + endpoint = endpoints.get(0); + endpointMapOk.put(ep, endpoint); + } + } + endpoints.remove(endpoint); + } + return endpoint; + } + + // Call this if the previous enpoint failed to connect. + /** + * Gets the next endpoint. + * + * @param ep the ep + * @param endpoints the endpoints + * @return the next endpoint + */ + // An attempt to track the most recent "working" endpoint. + public String getNextEndpoint(EndpointInterface ep, List endpoints) { + String endpoint = null; + if (endpoints.size() > 0) { + endpoint = endpoints.remove(0); + synchronized (endpointMapOk) { + // Let's hope this one works. + endpointMapOk.put(ep, endpoint); + } + } + return endpoint; + } + + private synchronized void loadUrls(EndpointInterface endpoint) { + endpointMap = new HashMap<>(); + String urls = env.getProperty(AafProperties.aafUrls.toString()); + String[] list = urls.split("\\|"); + for (String url : list) { + for (EndpointInterface ep : endpoint.getValues()) { + addToEndpointMap(ep, url); + } + } + } + + + private void addToEndpointMap(EndpointInterface ep, String endpoint) { + List list = endpointMap.get(ep); + if (list == null) { + list = new ArrayList<>(); + endpointMap.put(ep, list); + } + String path = env.getProperty(ep.getPathName().toString(), ep.defaultPath()); + list.add(endpoint + path); + } +} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/EndpointInterface.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/EndpointInterface.java new file mode 100755 index 0000000..af0039d --- /dev/null +++ b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/EndpointInterface.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * 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. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.aaf; + +public interface EndpointInterface { + public AafProperties getPathName(); + + public String defaultPath(); + + public EndpointInterface[] getValues(); + +} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/FilterPriority.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/FilterPriority.java deleted file mode 100644 index 2521ef7..0000000 --- a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/FilterPriority.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright © 2019 AT&T Intellectual Property. - * - * 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. - * - * - * Unless otherwise specified, all documentation contained herein is licensed under the Creative - * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except - * in compliance with the License. You may obtain a copy of the License at - * - * https://creativecommons.org/licenses/by/4.0/ - * - * Unless required by applicable law or agreed to in writing, documentation distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package org.onap.optf.cmso.aaf; - -import org.springframework.core.Ordered; - -public enum FilterPriority { - AAF_AUTHENTICATION(Ordered.HIGHEST_PRECEDENCE), AAF_AUTHORIZATION(Ordered.HIGHEST_PRECEDENCE + 1); - private final int priority; - - FilterPriority(final int ppri) { - priority = ppri; - } - - public int getPriority() { - return priority; - } -} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/ResponseFormatter.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/ResponseFormatter.java deleted file mode 100644 index b1a01bc..0000000 --- a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/ResponseFormatter.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright © 2019 AT&T Intellectual Property. - * - * 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. - * - * - * Unless otherwise specified, all documentation contained herein is licensed under the Creative - * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except - * in compliance with the License. You may obtain a copy of the License at - * - * https://creativecommons.org/licenses/by/4.0/ - * - * Unless required by applicable law or agreed to in writing, documentation distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -package org.onap.optf.cmso.aaf; - -import java.io.IOException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.onap.optf.cmso.common.exceptions.CmsoException; - -class ResponseFormatter { - - - static void errorResponse(HttpServletRequest request, HttpServletResponse response, CmsoException error) - throws IOException { - response.setStatus(error.getStatus().getStatusCode()); - response.getWriter().write(error.getRequestError().toString()); - response.getWriter().flush(); - response.getWriter().close(); - } - -} diff --git a/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/SecurityConfig.java b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/SecurityConfig.java new file mode 100755 index 0000000..ba2d928 --- /dev/null +++ b/cmso-topology/src/main/java/org/onap/optf/cmso/aaf/SecurityConfig.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019 AT&T Intellectual Property. + * Modifications Copyright © 2018 IBM. + * + * 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. + * + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package org.onap.optf.cmso.aaf; + +import org.onap.optf.cmso.topology.SpringProfiles; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +@EnableWebSecurity +@ComponentScan("org.onap") +@Profile(SpringProfiles.AAF_AUTHENTICATION) +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private AafAuthProvider authProvider; + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.authenticationProvider(authProvider); + + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + + http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().httpBasic().realmName("Realm"); + + } +} diff --git a/cmso-topology/src/main/resources/META-INF/resources/swagger/swagger.json b/cmso-topology/src/main/resources/META-INF/resources/swagger/swagger.json new file mode 100644 index 0000000..5d41ba3 --- /dev/null +++ b/cmso-topology/src/main/resources/META-INF/resources/swagger/swagger.json @@ -0,0 +1,516 @@ +{ + "swagger" : "2.0", + "info" : { + "version" : "2.1.1-SNAPSHOT", + "title" : "cmso-topology" + }, + "basePath" : "/topology", + "tags" : [ { + "name" : "Administration" + }, { + "name" : "Topology Interface" + } ], + "paths" : { + "/{apiVersion}/admin/{id}" : { + "get" : { + "tags" : [ "Administration" ], + "summary" : "", + "description" : "Returns encrypted value of id.", + "operationId" : "exec", + "produces" : [ "text/plain" ], + "parameters" : [ { + "name" : "apiVersion", + "in" : "path", + "description" : "v1|v2", + "required" : true, + "type" : "string", + "default" : "v1" + }, { + "name" : "id", + "in" : "path", + "description" : "Identifier", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "OK", + "schema" : { + "type" : "string" + } + }, + "400" : { + "description" : "Request failed" + } + } + } + }, + "/{apiVersion}/current" : { + "post" : { + "tags" : [ "Topology Interface" ], + "summary" : "Request Topology", + "description" : "API to retrieve toplogy for scheduling 'conflict free' mainentance. Retrieves the element information related to the list of elements targeted for mainenance activity. Scope of related elements to be returned are defined in the passed ToplogogyRequest. Elements returned must include in the elementData, the identifier that the element is known as in the ticket management system.\nThe Topology Service may implement asynchronous requests by returning IN_PROGRESS status. If IN_PROGRESS, the optimizer will begin polling until COMPLETED is returned with the response. ", + "operationId" : "retrieveCurrentTopology", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "apiVersion", + "in" : "path", + "description" : "v1", + "required" : true, + "type" : "string", + "default" : "v1" + }, { + "in" : "body", + "name" : "body", + "description" : "Topology criteria.", + "required" : false, + "schema" : { + "$ref" : "#/definitions/Topology Request" + } + } ], + "responses" : { + "200" : { + "description" : "OK", + "schema" : { + "$ref" : "#/definitions/Topology Response" + } + }, + "400" : { + "description" : "Bad request", + "schema" : { + "$ref" : "#/definitions/CmsoRequestError" + } + }, + "500" : { + "description" : "Unexpected Runtime error" + } + } + } + }, + "/{apiVersion}/current/request/{id}" : { + "get" : { + "tags" : [ "Topology Interface" ], + "summary" : "Poll Asynchronous Topology Request", + "description" : "If a topology request results in asynchronous request (IN_PROGRESS) this GET is used to retrieve status until COMPLETED. At which time, the optimizer will issue a DELETE to acknowledge receipt.\nThe Topology Service implementation may delete the cache when returning completed. The optimizer will treat subsequent not found on delete as normal.", + "operationId" : "getTopologyRequest", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "apiVersion", + "in" : "path", + "description" : "v1", + "required" : true, + "type" : "string", + "default" : "v1" + }, { + "name" : "id", + "in" : "path", + "description" : "Request Id", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "OK", + "schema" : { + "$ref" : "#/definitions/Topology Response" + } + }, + "404" : { + "description" : "Not Found", + "schema" : { + "$ref" : "#/definitions/CmsoRequestError" + } + }, + "500" : { + "description" : "Unexpected Runtime error" + } + } + }, + "delete" : { + "tags" : [ "Topology Interface" ], + "summary" : "Acknowledge Topology Response", + "description" : "API to acknowledge COMPLETED toplogy request.", + "operationId" : "deleteTopologyRequest", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "apiVersion", + "in" : "path", + "description" : "v1", + "required" : true, + "type" : "string", + "default" : "v1" + }, { + "name" : "id", + "in" : "path", + "description" : "Request Id", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "OK", + "schema" : { + "$ref" : "#/definitions/Topology Response" + } + }, + "404" : { + "description" : "Not Found", + "schema" : { + "$ref" : "#/definitions/CmsoRequestError" + } + }, + "500" : { + "description" : "Unexpected Runtime error" + } + } + } + }, + "/{apiVersion}/health" : { + "get" : { + "tags" : [ "Administration" ], + "summary" : "", + "description" : "Returns health status of server.", + "operationId" : "healthCheck", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "apiVersion", + "in" : "path", + "description" : "v1", + "required" : true, + "type" : "string", + "default" : "v1" + }, { + "name" : "checkInterfaces", + "in" : "query", + "description" : "Check Interfaces", + "required" : false, + "type" : "boolean", + "default" : true + } ], + "responses" : { + "200" : { + "description" : "OK", + "schema" : { + "$ref" : "#/definitions/HealthCheckMessage" + } + }, + "400" : { + "description" : "Not healthy", + "schema" : { + "$ref" : "#/definitions/HealthCheckMessage" + } + } + } + } + } + }, + "definitions" : { + "CmsoRequestError" : { + "type" : "object", + "properties" : { + "requestError" : { + "$ref" : "#/definitions/RequestError" + } + } + }, + "Element Critera" : { + "type" : "object", + "properties" : { + "elementId" : { + "type" : "string", + "description" : "Element id unique to the request." + }, + "elementData" : { + "type" : "array", + "description" : "Implementation specific element data.", + "items" : { + "$ref" : "#/definitions/Name Value Data" + } + } + }, + "description" : "Element criteria for retrieving topology." + }, + "Element Location" : { + "type" : "object", + "properties" : { + "lat" : { + "type" : "number", + "format" : "float", + "description" : "Geographic latitude of element." + }, + "lon" : { + "type" : "number", + "format" : "float", + "description" : "Geographic longitude of element." + }, + "timezone" : { + "type" : "string", + "description" : "Timezone." + } + }, + "description" : "Location information necessary to determine timezone. lat/lon and/or timezone must be provided" + }, + "HealthCheckComponent" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "url" : { + "type" : "string" + }, + "status" : { + "type" : "string" + }, + "healthy" : { + "type" : "boolean" + } + } + }, + "HealthCheckMessage" : { + "type" : "object", + "properties" : { + "healthy" : { + "type" : "boolean" + }, + "buildInfo" : { + "type" : "string" + }, + "currentTime" : { + "type" : "string" + }, + "hostname" : { + "type" : "string" + }, + "components" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/HealthCheckComponent" + } + } + } + }, + "Name Value Data" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string", + "description" : "Name." + }, + "value" : { + "type" : "object", + "description" : "Value." + } + }, + "description" : "Instance of a name/value" + }, + "RequestError" : { + "type" : "object", + "properties" : { + "messageId" : { + "type" : "string" + }, + "text" : { + "type" : "string" + }, + "variables" : { + "type" : "array", + "items" : { + "type" : "string" + } + } + } + }, + "Supported Policy Information" : { + "type" : "object", + "properties" : { + "policyName" : { + "type" : "string", + "description" : "Policy name" + }, + "policyDescription" : { + "type" : "string", + "description" : "Policy description" + }, + "policyModifiers" : { + "type" : "array", + "description" : "Named values to modify/override policy attributes.", + "items" : { + "$ref" : "#/definitions/Name Value Data" + } + } + }, + "description" : "Policy Information returned from get policies API." + }, + "Topology Constraint ELements" : { + "type" : "object", + "properties" : { + "elementId" : { + "type" : "string", + "description" : "Element identifier" + }, + "constraintType" : { + "type" : "string", + "description" : "Type of constraint." + }, + "constraintTypeMinimum" : { + "type" : "integer", + "format" : "int32", + "description" : "If more than one instance of constraintType, minimum number of available instances required. Useful for identifying availableBackup elements, service paths." + }, + "optimizerAvailabilityMatrixName" : { + "type" : "string", + "description" : "Availability matrix name. Availability matrix will not be passed to optimizer engine. Generally useful for global concurrency type constraints." + }, + "availabilityMatrixScope" : { + "type" : "string", + "description" : "Availability matrix scope global or scoped per elementId.", + "enum" : [ "NONE", "GLOBAL", "ELEMENT" ] + }, + "elementAvailabilityAggreagation" : { + "type" : "boolean", + "description" : "Availability matrix is aggregated into element availability marrix." + }, + "elements" : { + "type" : "array", + "description" : "Elements ", + "items" : { + "type" : "string" + } + } + }, + "description" : "Constraining Element Information returned from TopologyRequuest." + }, + "Topology Element" : { + "type" : "object", + "properties" : { + "elementId" : { + "type" : "string", + "description" : "Element identifier" + }, + "elementLocation" : { + "description" : "Location information for the element.", + "$ref" : "#/definitions/Element Location" + }, + "requiredElements" : { + "type" : "array", + "description" : "List of related elements required to be available to execute the chenge.", + "items" : { + "type" : "string" + } + }, + "constraintElements" : { + "type" : "array", + "description" : "Lists of related elements that must be available to avoid network outage while executing the change. Each set constraint elements", + "items" : { + "$ref" : "#/definitions/Topology Constraint ELements" + } + }, + "elementData" : { + "type" : "array", + "description" : "Implementation specific element data.", + "items" : { + "$ref" : "#/definitions/Name Value Data" + } + } + }, + "description" : "Element Information returned from TopologyRequuest." + }, + "Topology Related Element" : { + "type" : "object", + "properties" : { + "elementId" : { + "type" : "string", + "description" : "Element identifier" + }, + "elementLocation" : { + "description" : "Location information for the element.", + "$ref" : "#/definitions/Element Location" + }, + "elementData" : { + "type" : "array", + "description" : "Implementation specific element data.", + "items" : { + "$ref" : "#/definitions/Name Value Data" + } + }, + "relatedElements" : { + "type" : "array", + "items" : { + "type" : "string" + } + } + }, + "description" : "Element Information returned from TopologyRequuest." + }, + "Topology Request" : { + "type" : "object", + "properties" : { + "requestId" : { + "type" : "string", + "description" : "Unique Id of the request" + }, + "commonData" : { + "type" : "array", + "description" : "Implementation specific name value pairs.", + "items" : { + "$ref" : "#/definitions/Name Value Data" + } + }, + "elements" : { + "type" : "array", + "description" : "List of the elements for which topology information is requested.", + "items" : { + "$ref" : "#/definitions/Element Critera" + } + }, + "policies" : { + "type" : "array", + "description" : "List of the policies to control topology retrieve.", + "items" : { + "$ref" : "#/definitions/Supported Policy Information" + } + } + }, + "description" : "Request to retrieve topology information for the provided elements." + }, + "Topology Response" : { + "type" : "object", + "properties" : { + "requestId" : { + "type" : "string", + "description" : "Unique Id of the request" + }, + "elements" : { + "type" : "array", + "description" : "List of elements for for which topology has been requested.", + "items" : { + "$ref" : "#/definitions/Topology Element" + } + }, + "referencedElements" : { + "type" : "array", + "description" : "List of referenced elements representing the topology that has been requested.", + "items" : { + "$ref" : "#/definitions/Topology Related Element" + } + }, + "status" : { + "type" : "string", + "description" : "Status of asynchronous request. COMPLETED is returned on initial synchonous request. If IN_PROGRESS is returned, the optimizer will enter asynchronous polling mode.", + "enum" : [ "IN_PROGRESS", "COMPLETED", "FAILED" ] + }, + "errorMessage" : { + "type" : "string", + "description" : "FAILED request error message." + }, + "pollingSeconds" : { + "type" : "integer", + "format" : "int32", + "description" : "If request is asynchronous (IN_PROGRESS), suggested interval to the next poll." + } + }, + "description" : "Response to topology query for the requested elements." + } + } +} \ No newline at end of file diff --git a/cmso-topology/src/main/resources/application.properties b/cmso-topology/src/main/resources/application.properties index 9fa9e07..232484d 100644 --- a/cmso-topology/src/main/resources/application.properties +++ b/cmso-topology/src/main/resources/application.properties @@ -58,4 +58,4 @@ com.att.eelf.logging.file=logback.xml com.att.eelf.logging.path= logging.config= -spring.profiles.active=proprietary-auth \ No newline at end of file +spring.profiles.active=aaf-auth \ No newline at end of file -- cgit 1.2.3-korg