/*
* Copyright 2021 EMBL - European Bioinformatics Institute
* 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.
*/
package uk.ac.ebi.biosamples.service.security;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import org.springframework.stereotype.Service;
import uk.ac.ebi.biosamples.exception.AccessControlException;
import uk.ac.ebi.biosamples.model.AuthToken;
import uk.ac.ebi.biosamples.model.auth.LoginWays;

@Service
public class AccessControlService {
  private final ObjectMapper objectMapper;

  public AccessControlService(ObjectMapper objectMapper) {
    this.objectMapper = objectMapper;
  }

  public AuthToken extractToken(String token) {
    token = token.startsWith("Bearer ") ? token.split("Bearer ")[1] : token;

    String[] chunks = token.split("\\.");
    Base64.Decoder decoder = Base64.getDecoder();
    String header = new String(decoder.decode(chunks[0]));
    String payload = new String(decoder.decode(chunks[1]));

    if (!verifySignature(token)) {
      throw new AccessControlException("Failed to verify the integrity of the token");
    }

    AuthToken authToken;
    try {
      String algorithm = objectMapper.readTree(header).get("alg").asText();
      LoginWays authority;
      String user;
      List<String> roles;

      JsonNode node = objectMapper.readTree(payload);
      if (node.get("iss") != null
          && "https://explore.aai.ebi.ac.uk/sp".equals(node.get("iss").asText())) {
        authority = LoginWays.AAP;
        user = node.get("sub").asText();
        roles =
            objectMapper.convertValue(node.get("domains"), new TypeReference<List<String>>() {});
      } else {
        authority = LoginWays.WEBIN;
        user = node.get("principle").asText();
        roles = objectMapper.convertValue(node.get("role"), new TypeReference<List<String>>() {});
      }

      authToken = new AuthToken(algorithm, authority, user, roles);
    } catch (IOException e) {
      throw new AccessControlException("Could not decode token. ", e);
    }

    return authToken;
  }

  public boolean verifySignature(String token) {
    // todo without verifying with the authority we cant make any claims about the validity of the
    // token
    return true;
  }

  public List<String> getUserRoles(AuthToken token) {
    return token.getAuthority() == LoginWays.AAP
        ? token.getRoles()
        : Collections.singletonList(token.getUser());
  }
}

@@ -896,16 +896,74 @@
 il.List;
+%0A%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0Aimport 
@@ -1205,16 +1205,76 @@
 rvice %7B%0A
+  private Logger log = LoggerFactory.getLogger(getClass());%0A
   privat
@@ -2167,74 +2167,18 @@
  && 
-%22https://explore.aai.ebi.ac.uk/sp%22.equals(node.get(%22iss%22).asText()
+isIss(node
 )) %7B
@@ -2747,24 +2747,24 @@
  e);%0A    %7D%0A%0A
-
     return a
@@ -2774,24 +2774,252 @@
 Token;%0A  %7D%0A%0A
+  private boolean isIss(JsonNode node) %7B%0A    final String iss = node.get(%22iss%22).asText();%0A    log.info(%22ISS is %22 + iss);%0A%0A    return %22https://explore.aai.ebi.ac.uk/sp%22.equals(iss) %7C%7C %22https://aai.ebi.ac.uk/sp%22.equals(iss);%0A  %7D%0A%0A
   public boo

Fix access control service /security/AccessControlService.java