/*
Apache2 License Notice
Copyright 2018 Alex Barry
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 com.ao.adrestia.security;

import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

public class TokenAuthentication extends AbstractAuthenticationToken {

  private final DecodedJWT jwt;
  private boolean invalidated;

  public TokenAuthentication(DecodedJWT jwt) {
    super(readAuthorities(jwt));
    this.jwt = jwt;
  }

  private boolean hasExpired() {
    return jwt.getExpiresAt().before(new Date());
  }

  private static Collection<? extends GrantedAuthority> readAuthorities(DecodedJWT jwt) {
    Claim rolesClaim = jwt.getClaim("https://access.control/roles");
    if (rolesClaim.isNull()) {
      return Collections.emptyList();
    }
    List<GrantedAuthority> authorities = new ArrayList<>();
    String[] scopes = rolesClaim.asArray(String.class);
    for (String s : scopes) {
      SimpleGrantedAuthority a = new SimpleGrantedAuthority(s);
      if (!authorities.contains(a)) {
        authorities.add(a);
      }
    }
    return authorities;
  }


  @Override
  public String getCredentials() {
    return jwt.getToken();
  }

  @Override
  public Object getPrincipal() {
    return jwt.getSubject();
  }

  @Override
  public void setAuthenticated(boolean authenticated) {
    if (authenticated) {
      throw new IllegalArgumentException("Create a new Authentication object to authenticate");
    }
    invalidated = true;
  }

  @Override
  public boolean isAuthenticated() {
    return !invalidated && !hasExpired();
  }
}

@@ -820,16 +820,73 @@
 .List;%0A%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A
 import o
@@ -957,16 +957,16 @@
 nToken;%0A
-
 import o
@@ -1164,16 +1164,108 @@
 oken %7B%0A%0A
+  private static final Logger logger = LoggerFactory.getLogger(%22adrestia.AuthController%22);%0A%0A
   privat
@@ -1699,24 +1699,75 @@
 isNull()) %7B%0A
+      logger.warn(%22No Roles found for JWT Token%22);%0A
       return
@@ -1910,24 +1910,75 @@
 ing.class);%0A
+    logger.debug(%22Role Claim Scopes: %7B%7D%22, scopes);%0A
     for (Str
@@ -2093,24 +2093,86 @@
 tains(a)) %7B%0A
+        logger.debug(%22Granting Authority: %7B%7D%22, a.toString());%0A
         auth
@@ -2393,32 +2393,32 @@
  %7D%0A%0A  @Override%0A
-
   public void se
@@ -2453,24 +2453,78 @@
 nticated) %7B%0A
+    logger.info(%22Invalidating Authentication Token%22);%0A
     if (auth

add debug logs into token authentication methods