From 5e0e2ad1e8e616969374f1e9c238f7db7c38dc91 Mon Sep 17 00:00:00 2001 From: Jerry Flood Date: Sat, 28 Sep 2019 07:01:17 -0400 Subject: Replace CADI for access to AAF Issue-ID: OPTFRA-593 Change-Id: I56ee7ea9bebce402541b1acefb5e1049b50ad886 Signed-off-by: Jerry Flood --- cmso-service/etc/config/cmso.properties | 5 + .../org/onap/optf/cmso/aaf/AafAuthProvider.java | 82 ++ .../onap/optf/cmso/aaf/AafAuthorizationFilter.java | 93 -- .../java/org/onap/optf/cmso/aaf/AafClient.java | 184 +++ .../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 | 86 -- .../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 | 60 - .../java/org/onap/optf/cmso/aaf/AafUserRole.java | 376 +++--- .../onap/optf/cmso/aaf/AafUserRoleProperties.java | 244 ++-- .../java/org/onap/optf/cmso/aaf/BaseEndpoints.java | 123 ++ .../org/onap/optf/cmso/aaf/EndpointInterface.java | 41 + .../org/onap/optf/cmso/aaf/FilterPriority.java | 46 - .../org/onap/optf/cmso/aaf/ResponseFormatter.java | 49 - .../org/onap/optf/cmso/aaf/SecurityConfig.java | 65 ++ .../META-INF/resources/swagger/swagger.json | 1234 ++++++++++++++++++++ .../src/main/resources/application.properties | 2 +- 21 files changed, 2661 insertions(+), 788 deletions(-) create mode 100755 cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafAuthProvider.java delete mode 100644 cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafAuthorizationFilter.java create mode 100755 cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClient.java create mode 100755 cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java create mode 100755 cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java create mode 100755 cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafEndpoints.java delete mode 100644 cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafFilter.java mode change 100644 => 100755 cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafPerm.java create mode 100755 cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafPermResponse.java create mode 100755 cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafProperties.java delete mode 100644 cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafSecurityConfig.java mode change 100644 => 100755 cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafUserRole.java mode change 100644 => 100755 cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafUserRoleProperties.java create mode 100755 cmso-service/src/main/java/org/onap/optf/cmso/aaf/BaseEndpoints.java create mode 100755 cmso-service/src/main/java/org/onap/optf/cmso/aaf/EndpointInterface.java delete mode 100644 cmso-service/src/main/java/org/onap/optf/cmso/aaf/FilterPriority.java delete mode 100644 cmso-service/src/main/java/org/onap/optf/cmso/aaf/ResponseFormatter.java create mode 100755 cmso-service/src/main/java/org/onap/optf/cmso/aaf/SecurityConfig.java create mode 100644 cmso-service/src/main/resources/META-INF/resources/swagger/swagger.json (limited to 'cmso-service') diff --git a/cmso-service/etc/config/cmso.properties b/cmso-service/etc/config/cmso.properties index ed06d92..6ae215d 100644 --- a/cmso-service/etc/config/cmso.properties +++ b/cmso-service/etc/config/cmso.properties @@ -100,3 +100,8 @@ mechid.user=oof@oof.onap.org mechid.pass=enc:vfxQdJ1mgdcI7S6SPrzNaw== cmso.dispatch.url=http://localhost:8089 + +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-service/src/main/java/org/onap/optf/cmso/aaf/AafAuthProvider.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafAuthProvider.java new file mode 100755 index 0000000..c34e4b0 --- /dev/null +++ b/cmso-service/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.SpringProfiles; +import org.onap.optf.cmso.aaf.AafClientCache.AuthorizationResult; +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-service/src/main/java/org/onap/optf/cmso/aaf/AafAuthorizationFilter.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafAuthorizationFilter.java deleted file mode 100644 index c38a53d..0000000 --- a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafAuthorizationFilter.java +++ /dev/null @@ -1,93 +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.SpringProfiles; -import org.onap.optf.cmso.common.LogMessages; -import org.onap.optf.cmso.common.exceptions.CmsoException; -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-service/src/main/java/org/onap/optf/cmso/aaf/AafClient.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClient.java new file mode 100755 index 0000000..e52d295 --- /dev/null +++ b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClient.java @@ -0,0 +1,184 @@ +/* + * 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.SpringProfiles; +import org.onap.optf.cmso.common.BasicAuthenticatorFilter; +import org.onap.optf.cmso.common.LogMessages; +import org.onap.optf.cmso.common.PropertiesManagement; +import org.onap.optf.cmso.common.exceptions.CmsoException; +import org.onap.optf.cmso.filters.CmsoClientFilters; +import org.onap.optf.cmso.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(AafEndpoints.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(AafEndpoints.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-service/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java new file mode 100755 index 0000000..c76463d --- /dev/null +++ b/cmso-service/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.SpringProfiles; +import org.onap.optf.cmso.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-service/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java new file mode 100755 index 0000000..a8d860d --- /dev/null +++ b/cmso-service/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.SpringProfiles; +import org.onap.optf.cmso.aaf.AafClientCache.AuthorizationResult; +import org.onap.optf.cmso.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-service/src/main/java/org/onap/optf/cmso/aaf/AafEndpoints.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafEndpoints.java new file mode 100755 index 0000000..e9c9181 --- /dev/null +++ b/cmso-service/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-service/src/main/java/org/onap/optf/cmso/aaf/AafFilter.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafFilter.java deleted file mode 100644 index 661510d..0000000 --- a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafFilter.java +++ /dev/null @@ -1,86 +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.Application; -import org.onap.optf.cmso.SpringProfiles; -import org.onap.optf.cmso.common.LogMessages; -import org.onap.optf.cmso.common.exceptions.CmsoException; -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-service/src/main/java/org/onap/optf/cmso/aaf/AafPerm.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafPerm.java old mode 100644 new mode 100755 index 278f3ab..d324f18 --- a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafPerm.java +++ b/cmso-service/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-service/src/main/java/org/onap/optf/cmso/aaf/AafPermResponse.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafPermResponse.java new file mode 100755 index 0000000..caf2b62 --- /dev/null +++ b/cmso-service/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-service/src/main/java/org/onap/optf/cmso/aaf/AafProperties.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafProperties.java new file mode 100755 index 0000000..00758e5 --- /dev/null +++ b/cmso-service/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-service/src/main/java/org/onap/optf/cmso/aaf/AafSecurityConfig.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafSecurityConfig.java deleted file mode 100644 index 068e6c3..0000000 --- a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafSecurityConfig.java +++ /dev/null @@ -1,60 +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.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(); - - } -} \ No newline at end of file diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafUserRole.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafUserRole.java old mode 100644 new mode 100755 index 87938d7..806a7b1 --- a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafUserRole.java +++ b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafUserRole.java @@ -1,177 +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.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-service/src/main/java/org/onap/optf/cmso/aaf/AafUserRoleProperties.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafUserRoleProperties.java old mode 100644 new mode 100755 index 624171d..26bb436 --- a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafUserRoleProperties.java +++ b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafUserRoleProperties.java @@ -1,139 +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 com.fasterxml.jackson.databind.ObjectMapper; -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.SpringProfiles; -import org.onap.optf.cmso.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.SpringProfiles; +import org.onap.optf.cmso.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-service/src/main/java/org/onap/optf/cmso/aaf/BaseEndpoints.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/BaseEndpoints.java new file mode 100755 index 0000000..1027ade --- /dev/null +++ b/cmso-service/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-service/src/main/java/org/onap/optf/cmso/aaf/EndpointInterface.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/EndpointInterface.java new file mode 100755 index 0000000..af0039d --- /dev/null +++ b/cmso-service/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-service/src/main/java/org/onap/optf/cmso/aaf/FilterPriority.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/FilterPriority.java deleted file mode 100644 index e861f71..0000000 --- a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/FilterPriority.java +++ /dev/null @@ -1,46 +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-service/src/main/java/org/onap/optf/cmso/aaf/ResponseFormatter.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/ResponseFormatter.java deleted file mode 100644 index 8ed6df3..0000000 --- a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/ResponseFormatter.java +++ /dev/null @@ -1,49 +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-service/src/main/java/org/onap/optf/cmso/aaf/SecurityConfig.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/SecurityConfig.java new file mode 100755 index 0000000..80eea75 --- /dev/null +++ b/cmso-service/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.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-service/src/main/resources/META-INF/resources/swagger/swagger.json b/cmso-service/src/main/resources/META-INF/resources/swagger/swagger.json new file mode 100644 index 0000000..f987661 --- /dev/null +++ b/cmso-service/src/main/resources/META-INF/resources/swagger/swagger.json @@ -0,0 +1,1234 @@ +{ + "swagger" : "2.0", + "info" : { + "version" : "2.1.1-SNAPSHOT", + "title" : "cmso-service" + }, + "basePath" : "/cmso", + "tags" : [ { + "name" : "CMSO Administration" + }, { + "name" : "CMSO Optimized Schedule API" + }, { + "name" : "CMSO Schedule API" + } ], + "paths" : { + "/{apiVersion}/admin/{id}" : { + "get" : { + "tags" : [ "CMSO 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" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "csv" + } ], + "responses" : { + "200" : { + "description" : "OK", + "schema" : { + "type" : "string" + } + }, + "400" : { + "description" : "Request failed" + } + } + } + }, + "/{apiVersion}/health" : { + "get" : { + "tags" : [ "CMSO 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" : "array", + "items" : { + "type" : "boolean", + "default" : true + }, + "collectionFormat" : "multi" + } ], + "responses" : { + "200" : { + "description" : "OK", + "schema" : { + "$ref" : "#/definitions/HealthCheckMessage" + } + }, + "400" : { + "description" : "Not healthy", + "schema" : { + "$ref" : "#/definitions/HealthCheckMessage" + } + } + } + } + }, + "/{apiVersion}/schedules" : { + "get" : { + "tags" : [ "CMSO Schedule API" ], + "summary" : "", + "description" : "Returns a list of Scheduler Requests based upon the filter criteria.", + "operationId" : "searchScheduleRequests", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "apiVersion", + "in" : "path", + "description" : "v1", + "required" : true, + "type" : "string", + "default" : "v1" + }, { + "name" : "includeDetails", + "in" : "query", + "description" : "Include details", + "required" : false, + "type" : "boolean", + "default" : false + }, { + "name" : "scheduleId", + "in" : "query", + "description" : "Schedule identifier", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "scheduleName", + "in" : "query", + "description" : "Schedule name", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "userId", + "in" : "query", + "description" : "SCheduler creator User id of ", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "status", + "in" : "query", + "description" : "Schedule status", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "createDateTime", + "in" : "query", + "description" : "Creation date and time ([,])", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "optimizerStatus", + "in" : "query", + "description" : "Optimizer status", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "WorkflowName", + "in" : "query", + "description" : "Workflow", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + } ], + "responses" : { + "200" : { + "description" : "OK", + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/Schedule" + } + } + }, + "404" : { + "description" : "No records found", + "schema" : { + "$ref" : "#/definitions/CmsoRequestError" + } + }, + "500" : { + "description" : "Unexpected Runtime error" + } + } + } + }, + "/{apiVersion}/schedules/optimized/{scheduleId}" : { + "post" : { + "tags" : [ "CMSO Optimized Schedule API" ], + "summary" : "", + "description" : "Creates a request for an optimized schedule", + "operationId" : "createScheduleRequest", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "apiVersion", + "in" : "path", + "description" : "v1", + "required" : true, + "type" : "string", + "default" : "v1" + }, { + "name" : "scheduleId", + "in" : "path", + "description" : "Schedule id to uniquely identify the schedule request being created.", + "required" : true, + "type" : "string" + }, { + "in" : "body", + "name" : "body", + "description" : "Data for creating a schedule request for the given schedule id", + "required" : false, + "schema" : { + "$ref" : "#/definitions/Optimized Schedule Request" + } + } ], + "responses" : { + "202" : { + "description" : "Schedule request accepted for optimization." + }, + "409" : { + "description" : "Schedule request already exists for this schedule id.", + "schema" : { + "$ref" : "#/definitions/CmsoRequestError" + } + }, + "500" : { + "description" : "Unexpected Runtime error" + } + } + } + }, + "/{apiVersion}/schedules/scheduleDetails" : { + "get" : { + "tags" : [ "CMSO Schedule API" ], + "summary" : "", + "description" : "Returns a list of Schedule request details based upon the filter criteria.", + "operationId" : "searchScheduleRequestDetails", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "apiVersion", + "in" : "path", + "description" : "v1", + "required" : true, + "type" : "string", + "default" : "v1" + }, { + "name" : "request.scheduleId", + "in" : "query", + "description" : "Schedule identifier", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "request.scheduleName", + "in" : "query", + "description" : "Schedule name", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "request.userId", + "in" : "query", + "description" : "Scheduler creator User id of ", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "request.status", + "in" : "query", + "description" : "Schedule status", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "request.createDateTime", + "in" : "query", + "description" : "Creation date and time ([,])", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "request.optimizerStatus", + "in" : "query", + "description" : "Optimizer status", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "request.approvalUserId", + "in" : "query", + "description" : "Request Approval user id", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "request.approvalStatus", + "in" : "query", + "description" : "Request Approval status", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "request.approvalType", + "in" : "query", + "description" : "Request Approval type", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "WorkflowName", + "in" : "query", + "description" : "Workflow", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "vnfName", + "in" : "query", + "description" : "VNF Name", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "vnfId", + "in" : "query", + "description" : "VNF Id", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "vnfStatus", + "in" : "query", + "description" : "VNF Status", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "startTime", + "in" : "query", + "description" : "Start time ,", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "finishTime", + "in" : "query", + "description" : "Finish time ,", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "lastInstanceTime", + "in" : "query", + "description" : "Last instance start time ,", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "tmChangeId", + "in" : "query", + "description" : "TM Change Ticket Change Id", + "required" : false, + "type" : "array", + "items" : { + "type" : "string" + }, + "collectionFormat" : "multi" + }, { + "name" : "maxSchedules", + "in" : "query", + "description" : "Maximum number of schedules to return", + "required" : false, + "type" : "integer", + "format" : "int32" + }, { + "name" : "lastScheduleId", + "in" : "query", + "description" : "Return schedules > lastScheduleId", + "required" : false, + "type" : "string" + }, { + "name" : "request.concurrencyLimit", + "in" : "query", + "description" : "Return concurrencyLimit", + "required" : false, + "type" : "integer", + "format" : "int32" + } ], + "responses" : { + "200" : { + "description" : "OK", + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/CmDetailsMessage" + } + } + }, + "404" : { + "description" : "No records found", + "schema" : { + "$ref" : "#/definitions/CmsoRequestError" + } + }, + "500" : { + "description" : "Unexpected Runtime error" + } + } + } + }, + "/{apiVersion}/schedules/{scheduleId}" : { + "get" : { + "tags" : [ "CMSO Schedule API" ], + "summary" : "", + "description" : "Retrieve the schedule request for scheduleId", + "operationId" : "getScheduleRequestInfo", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "apiVersion", + "in" : "path", + "description" : "v1", + "required" : true, + "type" : "string", + "default" : "v1" + }, { + "name" : "scheduleId", + "in" : "path", + "description" : "Schedule id to uniquely identify the schedule info being retrieved.", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "OK", + "schema" : { + "$ref" : "#/definitions/Schedule" + } + }, + "404" : { + "description" : "No record found" + }, + "500" : { + "description" : "Unexpected Runtime error" + } + } + }, + "post" : { + "tags" : [ "CMSO Schedule API" ], + "summary" : "", + "description" : "Creates a schedule request for scheduleId", + "operationId" : "createScheduleRequest", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "apiVersion", + "in" : "path", + "description" : "v1", + "required" : true, + "type" : "string", + "default" : "v1" + }, { + "name" : "scheduleId", + "in" : "path", + "description" : "Schedule id to uniquely identify the schedule request being created.", + "required" : true, + "type" : "string" + }, { + "in" : "body", + "name" : "body", + "description" : "Data for creating a schedule request for the given schedule id", + "required" : false, + "schema" : { + "$ref" : "#/definitions/CmsoMessage" + } + } ], + "responses" : { + "202" : { + "description" : "Schedule request accepted for optimization." + }, + "409" : { + "description" : "Schedule request already exists for this schedule id.", + "schema" : { + "$ref" : "#/definitions/CmsoRequestError" + } + }, + "500" : { + "description" : "Unexpected Runtime error" + } + } + }, + "delete" : { + "tags" : [ "CMSO Schedule API" ], + "summary" : "", + "description" : "Cancels the schedule request for scheduleId", + "operationId" : "deleteScheduleRequest", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "apiVersion", + "in" : "path", + "description" : "v1", + "required" : true, + "type" : "string", + "default" : "v1" + }, { + "name" : "scheduleId", + "in" : "path", + "description" : "Schedule id to uniquely identify the schedule request being deleted.", + "required" : true, + "type" : "string" + } ], + "responses" : { + "204" : { + "description" : "Delete successful" + }, + "404" : { + "description" : "No record found", + "schema" : { + "$ref" : "#/definitions/CmsoRequestError" + } + }, + "500" : { + "description" : "Unexpected Runtime error" + } + } + } + }, + "/{apiVersion}/schedules/{scheduleId}/approvals" : { + "post" : { + "tags" : [ "CMSO Schedule API" ], + "summary" : "", + "description" : "Adds an accept/reject approval status to the schedule request identified by scheduleId", + "operationId" : "approveScheduleRequest", + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "apiVersion", + "in" : "path", + "description" : "v1", + "required" : true, + "type" : "string", + "default" : "v1" + }, { + "name" : "scheduleId", + "in" : "path", + "description" : "Schedule id to uniquely identify the schedule request being accepted or rejected.", + "required" : true, + "type" : "string" + }, { + "in" : "body", + "name" : "body", + "description" : "Accept or reject approval message", + "required" : false, + "schema" : { + "$ref" : "#/definitions/Schedule Approval Request" + } + } ], + "responses" : { + "200" : { + "description" : "OK" + }, + "404" : { + "description" : "No record found" + }, + "500" : { + "description" : "Unexpected Runtime error" + } + } + } + } + }, + "definitions" : { + "Change Management Group" : { + "type" : "object", + "properties" : { + "finishTime" : { + "type" : "string", + "description" : "Date/time by which all of the workflows should be completed." + }, + "groupId" : { + "type" : "string", + "description" : "Name of the group of VNFs to be scheduled" + }, + "lastInstanceStartTime" : { + "type" : "string", + "description" : "The latest date/time by which a workflow is to be started." + }, + "startTime" : { + "type" : "string", + "description" : "The date/time when workflows are to be started." + }, + "additionalDurationInSecs" : { + "type" : "integer", + "format" : "int32", + "description" : "Time added to the workflow interval to allow for rollback in case of failure." + }, + "concurrencyLimit" : { + "type" : "integer", + "format" : "int32", + "description" : "The maximum number of workflows that should be started simultaneiously." + }, + "normalDurationInSecs" : { + "type" : "integer", + "format" : "int32", + "description" : "Expected duration of a successful workflow execution." + }, + "policyId" : { + "type" : "string", + "description" : "The name of the schedule optimization policy used by the change management schedule optimizer." + }, + "changeManagementSchedules" : { + "type" : "array", + "description" : "The list of VNF workflows scheduled.", + "items" : { + "$ref" : "#/definitions/Change Management Schedule" + } + } + }, + "description" : "Scheduling critirea for a group of VNFs" + }, + "Change Management Schedule" : { + "type" : "object", + "properties" : { + "tmChangeId" : { + "type" : "string", + "description" : "TM Change Id" + }, + "tmStatus" : { + "type" : "string", + "description" : "TM ticket status", + "enum" : [ "", "Closed" ] + }, + "tmApprovalStatus" : { + "type" : "string", + "description" : "TM ticket approval status", + "enum" : [ "", "Approved" ] + }, + "finishTime" : { + "type" : "string", + "description" : "Anticipated time of completion based upon start time and duration" + }, + "startTime" : { + "type" : "string", + "description" : "Start time of this VNF workflow assigned by Scheduler based upon the group start time returned by the optimizer and concurrency." + }, + "status" : { + "type" : "string", + "description" : "Status of the VNF.", + "enum" : [ "See CMSStatusEnum" ] + }, + "vnfName" : { + "type" : "string", + "description" : "Name of the VNF." + }, + "dispatchTime" : { + "type" : "string", + "description" : "Actual time the VNF workflow was dispatched." + }, + "executionCompletedTime" : { + "type" : "string", + "description" : "Actual time the VNF workflow execution was completed as reported by MSO." + }, + "msoRequestId" : { + "type" : "string", + "description" : "MSO Request ID of the workflow returned at dispatch time." + }, + "msoStatus" : { + "type" : "string", + "description" : "Final MSO status.", + "enum" : [ "COMPLETED", "FAILED" ] + }, + "msoMessage" : { + "type" : "string", + "description" : "MSO final status message." + }, + "statusMessage" : { + "type" : "string", + "description" : "Scheduler status message." + }, + "msoTime" : { + "type" : "string", + "description" : "Time of last poll for MSO status." + }, + "request" : { + "type" : "string", + "description" : "Change equest." + } + }, + "description" : "VNF details for Change Management Schedule" + }, + "Change Management Scheduling Info" : { + "type" : "object", + "properties" : { + "normalDurationInSeconds" : { + "type" : "integer", + "format" : "int32", + "description" : "Expected duration (in seconds) of a successful execution of a single VNF change." + }, + "additionalDurationInSeconds" : { + "type" : "integer", + "format" : "int32", + "description" : "Additional duration (in seconds) to be added to support backout of an unsuccessful VNF change." + }, + "concurrencyLimit" : { + "type" : "integer", + "format" : "int32", + "description" : "Maximum number of VNF changes to schedule concurrently" + }, + "changeWindows" : { + "type" : "array", + "description" : "Lists of desired change windows to schedule the elements.", + "items" : { + "$ref" : "#/definitions/Change Window" + } + }, + "policies" : { + "type" : "array", + "description" : "List of the policies to control optimization.", + "items" : { + "$ref" : "#/definitions/Supported Policy Information" + } + }, + "elements" : { + "type" : "array", + "description" : "Lists of the VNFs to be changed and the desired change windows", + "items" : { + "$ref" : "#/definitions/Optimizer Element" + } + } + }, + "description" : "Details of schedule being requested" + }, + "Change Window" : { + "type" : "object", + "properties" : { + "startTime" : { + "type" : "string", + "format" : "date-time", + "description" : "Earliest time for which changes may begin." + }, + "endTime" : { + "type" : "string", + "format" : "date-time", + "description" : "Latest time by which all changes must be completed." + } + }, + "description" : "Time window for which tickets are to returned" + }, + "CmDetailsMessage" : { + "type" : "object", + "properties" : { + "vnfName" : { + "type" : "string", + "description" : "Name of the VNF." + }, + "status" : { + "type" : "string", + "description" : "Status of the VNF.", + "enum" : [ "See CMSStatusEnum" ] + }, + "tmChangeId" : { + "type" : "string", + "description" : "TM Change Id" + }, + "tmStatus" : { + "type" : "string", + "description" : "TM ticket status", + "enum" : [ "", "Closed" ] + }, + "tmApprovalStatus" : { + "type" : "string", + "description" : "TM ticket approval status", + "enum" : [ "", "Approved" ] + }, + "startTime" : { + "type" : "string", + "description" : "Start time of this VNF workflow assigned by Scheduler based upon the group start time returned by the optimizer and concurrency." + }, + "finishTime" : { + "type" : "string", + "description" : "Anticipated time of completion based upon start time and duration" + }, + "groupId" : { + "type" : "string", + "description" : "Name of the group of VNFs to be scheduled" + }, + "lastInstanceStartTime" : { + "type" : "string", + "description" : "The latest date/time by which a workflow is to be started." + }, + "policyId" : { + "type" : "string", + "description" : "Time of last poll for MSO status." + }, + "dispatchTime" : { + "type" : "string", + "description" : "Actual time the VNF workflow was dispatched." + }, + "executionCompletedTime" : { + "type" : "string", + "description" : "Actual time the VNF workflow execution was completed as reported by MSO." + }, + "msoRequestId" : { + "type" : "string", + "description" : "MSO Request ID of the workflow returned at dispatch time." + }, + "msoStatus" : { + "type" : "string", + "description" : "Final MSO status.", + "enum" : [ "COMPLETED", "FAILED" ] + }, + "msoMessage" : { + "type" : "string", + "description" : "MSO final status message." + }, + "statusMessage" : { + "type" : "string", + "description" : "Scheduler status message." + }, + "msoTime" : { + "type" : "string", + "description" : "Time of last poll for MSO status." + }, + "scheduleRequest" : { + "$ref" : "#/definitions/Schedule" + }, + "approvals" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/Schedule Approval Request" + } + } + } + }, + "CmsoMessage" : { + "type" : "object", + "properties" : { + "domain" : { + "type" : "string", + "description" : "Schedule domain : ChangeManagement" + }, + "scheduleId" : { + "type" : "string", + "description" : "Schedule id that must be unique within the domain. Use of UUID is highly recommended." + }, + "scheduleName" : { + "type" : "string", + "description" : "User provided name of the schedule (deaults to scheduleId" + }, + "userId" : { + "type" : "string", + "description" : "ATTUID of the user requesting the schedule." + }, + "domainData" : { + "type" : "array", + "description" : "Domain data as name value/pairs. (i.e. CallbackUrl, CallbackData, WorkflowName)", + "items" : { + "type" : "object", + "additionalProperties" : { + "type" : "string" + } + } + }, + "schedulingInfo" : { + "$ref" : "#/definitions/Change Management Scheduling Info" + } + } + }, + "CmsoRequestError" : { + "type" : "object", + "properties" : { + "requestError" : { + "$ref" : "#/definitions/RequestError" + } + } + }, + "Domain data" : { + "type" : "object", + "properties" : { + "name" : { + "type" : "string" + }, + "value" : { + "type" : "string" + } + }, + "description" : "Domain specific data represented as name/value pairs" + }, + "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" + }, + "Optimized Schedule Request" : { + "type" : "object", + "properties" : { + "domain" : { + "type" : "string", + "description" : "Schedule domain : ChangeManagement" + }, + "scheduleId" : { + "type" : "string", + "description" : "Schedule id that must be unique within the domain. Use of UUID is highly recommended." + }, + "scheduleName" : { + "type" : "string", + "description" : "User provided name of the schedule (deaults to scheduleId" + }, + "userId" : { + "type" : "string", + "description" : "ATTUID of the user requesting the schedule." + }, + "commonData" : { + "type" : "array", + "description" : "Implementation specific name value pairs.", + "items" : { + "$ref" : "#/definitions/Name Value Data" + } + }, + "schedulingData" : { + "description" : "Scheduling data.", + "$ref" : "#/definitions/Change Management Scheduling Info" + } + }, + "description" : "Request to schedule VNF change management workflow(s)." + }, + "Optimizer Element" : { + "type" : "object", + "properties" : { + "elementId" : { + "type" : "string", + "description" : "Element identifier" + }, + "elementData" : { + "type" : "array", + "description" : "Implementation specific element data.", + "items" : { + "$ref" : "#/definitions/Name Value Data" + } + }, + "request" : { + "type" : "object", + "description" : "Request for be scheduled." + }, + "groupId" : { + "type" : "string", + "description" : "VNF group identifier." + } + }, + "description" : "Element to be scheduled." + }, + "RequestError" : { + "type" : "object", + "properties" : { + "messageId" : { + "type" : "string" + }, + "text" : { + "type" : "string" + }, + "variables" : { + "type" : "array", + "items" : { + "type" : "string" + } + } + } + }, + "Schedule" : { + "type" : "object", + "properties" : { + "createDateTime" : { + "type" : "string", + "description" : "Date/time schedule was created." + }, + "optimizerDateTime" : { + "type" : "string" + }, + "optimizerMessage" : { + "type" : "string" + }, + "optimizerStatus" : { + "type" : "string" + }, + "optimizerReturnDateTime" : { + "type" : "string" + }, + "optimizerTransactionId" : { + "type" : "string" + }, + "schedule" : { + "type" : "string" + }, + "scheduleName" : { + "type" : "string" + }, + "scheduleInfo" : { + "type" : "string" + }, + "status" : { + "type" : "string" + }, + "userId" : { + "type" : "string" + }, + "domain" : { + "type" : "string" + }, + "deleteDateTime" : { + "type" : "string" + }, + "domainData" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/Domain data" + } + }, + "scheduleApprovals" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/Schedule Approval" + } + }, + "groups" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/Change Management Group" + } + } + } + }, + "Schedule Approval" : { + "type" : "object", + "properties" : { + "approvalDateTime" : { + "type" : "string", + "description" : "Date/time schedule time slot was accepted/rejected." + }, + "status" : { + "type" : "string", + "description" : "Approval status.", + "enum" : [ "Accepted", "Rejected" ] + }, + "userId" : { + "type" : "string", + "description" : "ATTUID of the user accepting/rejecting the time slot." + } + }, + "description" : "Details of a schedule approval/rejection." + }, + "Schedule Approval Request" : { + "type" : "object", + "properties" : { + "approvalUserId" : { + "type" : "string", + "description" : "ATTUID of the user accepting/rejecting the time slot." + }, + "approvalStatus" : { + "type" : "string", + "description" : "Approval status.", + "enum" : [ "Accepted", "Rejected" ] + }, + "approvalType" : { + "type" : "string", + "description" : "Type of approval.", + "enum" : [ "Tier 2" ] + }, + "approvalDateTime" : { + "type" : "string", + "format" : "date-time" + } + }, + "description" : "Request to accept or reject an optimized time slot." + }, + "Supported Policy Information" : { + "type" : "object", + "properties" : { + "policyName" : { + "type" : "string", + "description" : "Policy name" + }, + "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." + }, + "VNF Details" : { + "type" : "object", + "properties" : { + "groupId" : { + "type" : "string", + "description" : "Name of the list of VNFs to be changed as a group" + }, + "node" : { + "type" : "array", + "description" : "Lists of the VNF names to be changed", + "items" : { + "type" : "string" + } + }, + "changeWindow" : { + "type" : "array", + "description" : "Lists of desired change windows that the optimizer can select from. (Only 1 change window supported at this time)", + "items" : { + "$ref" : "#/definitions/Change Window" + } + } + }, + "description" : "Details and scheduling criteria for the VNFs to be changed." + } + } +} \ No newline at end of file diff --git a/cmso-service/src/main/resources/application.properties b/cmso-service/src/main/resources/application.properties index 0cdbf57..abc26be 100644 --- a/cmso-service/src/main/resources/application.properties +++ b/cmso-service/src/main/resources/application.properties @@ -60,4 +60,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=proprietary-auth -- cgit 1.2.3-korg