001/*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 *     http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014package org.gbif.ws.remoteauth.app;
015
016import org.gbif.api.vocabulary.AppRole;
017import org.gbif.ws.remoteauth.AbstractRemoteAuthenticationProvider;
018import org.gbif.ws.remoteauth.LoggedUser;
019import org.gbif.ws.remoteauth.RemoteAuthClient;
020import org.gbif.ws.security.AppPrincipal;
021import org.gbif.ws.security.GbifAuthenticationToken;
022import org.gbif.ws.security.GbifUserPrincipal;
023import org.gbif.ws.util.SecurityConstants;
024
025import java.util.ArrayList;
026import java.util.Collection;
027
028import org.springframework.http.HttpHeaders;
029import org.springframework.http.ResponseEntity;
030import org.springframework.security.core.Authentication;
031import org.springframework.security.core.authority.SimpleGrantedAuthority;
032import org.springframework.security.core.userdetails.UserDetails;
033
034import lombok.extern.slf4j.Slf4j;
035
036import static org.gbif.ws.util.SecurityConstants.GBIF_SCHEME;
037
038/**
039 * GBIF APP authentication against the registry.
040 */
041@Slf4j
042public class GbifAppRemoteAuthenticationProvider
043    extends AbstractRemoteAuthenticationProvider<GbifAppAuthentication> {
044
045  private static final String AUTH_PATH = "/user/auth/app";
046
047  public GbifAppRemoteAuthenticationProvider(RemoteAuthClient remoteAuthClient) {
048    super(GbifAppAuthentication.class, AUTH_PATH, remoteAuthClient);
049  }
050
051  @Override
052  public HttpHeaders createHttpHeaders(Authentication authentication) {
053    HttpHeaders headers = new HttpHeaders();
054    GbifAppAuthentication gbifAppAuthentication = (GbifAppAuthentication) authentication;
055    headers.add(HttpHeaders.AUTHORIZATION, gbifAppAuthentication.getGbifScheme());
056
057    if (gbifAppAuthentication.getContentMd5() != null
058        && !gbifAppAuthentication.getContentMd5().isEmpty()) {
059      headers.add(SecurityConstants.HEADER_CONTENT_MD5, gbifAppAuthentication.getContentMd5());
060    }
061
062    if (gbifAppAuthentication.getContentType() != null
063        && !gbifAppAuthentication.getContentType().isEmpty()) {
064      headers.add(HttpHeaders.CONTENT_TYPE, gbifAppAuthentication.getContentType());
065    }
066
067    if (authentication.getPrincipal() != null) {
068      headers.add(SecurityConstants.HEADER_GBIF_USER, authentication.getPrincipal().toString());
069    }
070    if (gbifAppAuthentication.getOriginalRequestUrl() != null
071        && !gbifAppAuthentication.getOriginalRequestUrl().isEmpty()) {
072      headers.add(
073          SecurityConstants.HEADER_ORIGINAL_REQUEST_URL,
074          gbifAppAuthentication.getOriginalRequestUrl());
075    }
076    if (gbifAppAuthentication.getMethod() != null && !gbifAppAuthentication.getMethod().isEmpty()) {
077      headers.add(
078          SecurityConstants.HEADER_ORIGINAL_REQUEST_METHOD, gbifAppAuthentication.getMethod());
079    }
080
081    return headers;
082  }
083
084  @Override
085  protected Authentication createSuccessAuthentication(
086      ResponseEntity<String> response, Authentication authentication) {
087    LoggedUser loggedUser = readUserFromResponse(response);
088    Collection<SimpleGrantedAuthority> authorities = extractRoles(loggedUser);
089
090    UserDetails userDetails = null;
091    if (loggedUser.getRoles().contains(AppRole.APP.name())) {
092      userDetails =
093          new AppPrincipal(
094              ((GbifAppAuthentication) authentication).getAppKey(), new ArrayList<>(authorities));
095    } else {
096      userDetails = new GbifUserPrincipal(loggedUser.toGbifUser());
097    }
098
099    return new GbifAuthenticationToken(userDetails, GBIF_SCHEME, authorities);
100  }
101}