// Path: distribution/src/main/java/nl/crowndov/displaydirect/distribution/authorization/AuthorizationWhitelist.java
// public class AuthorizationWhitelist extends AbstractService {
// 
//     private static final Logger LOGGER = LoggerFactory.getLogger(AuthorizationWhitelist.class);
// 
//     private static List<String> validKeys = new ArrayList<>();
//     private static Store.ValidationTokenStore validationTokens = new Store.ValidationTokenStore();
// 
//     private static Transport transport = TransportFactory.get();
// 
//     private static MessageDigest DIGEST = null;
// 
//     static {
//         try {
//             DIGEST = MessageDigest.getInstance("SHA-256");
//         } catch (NoSuchAlgorithmException e) {
//             LOGGER.error("Failed to initialize hash algorithm", e);
//         }
//     }
// 
//     public static void start() {
//         backup(() -> {
//             readFile("authorization_keys", Store.StringList.class).ifPresent(k -> validKeys = k);
//             readFile("authorization_tokens", Store.ValidationTokenStore.class).ifPresent(vt -> validationTokens = vt);
//         });
//     }
// 
//     public static void stop() {
//         writeFile("authorization_keys", validKeys);
//         writeFile("authorization_tokens", validationTokens);
//     }
// 
// 
//     public static boolean isValid(Subscription sub) {
//         return validKeys.contains(getKey(sub.getId(), sub.getEmail())) || Configuration.getAuthorizationWhitelist().contains(sub.getPrefix());
//     }
// 
//     private static String getKey(String systemId, String email) {
//         return systemId + "_" + email.toLowerCase();
//     }
// 
//     public static Optional<ValidationToken> addValidation(String systemId, Subscription subscribe) {
//         ZonedDateTime now = ZonedDateTime.now(Configuration.getZoneId());
//         // Check a validation token hasn't already been handed out for this system and it's still valid
//         if (validationTokens.values().stream().anyMatch(vt -> vt.getSystemId().contentEquals(systemId) && vt.getGenerated().plusHours(48).isAfter(now))) {
//             return Optional.empty();
//         }
//         ValidationToken v = new ValidationToken(newToken(), systemId, subscribe.getEmail(), ZonedDateTime.now(ZoneId.of("UTC")), subscribe);
//         validationTokens.put(v.getToken(), v);
// 
//         Map<String, Object> variables = new HashMap<>();
//         variables.put("id", systemId);
//         variables.put("description", subscribe.getDescription());
//         variables.put("url", Configuration.getBaseUrl() + "/admin/authorize?token=" + v.getToken());
//         EmailUtil.sendHtmlEmail(subscribe.getEmail(), "Rond aanmelding DisplayDirect af", "authenticate", variables);
// 
//         return Optional.ofNullable(v);
//     }
// 
//     private static String newToken() {
//         return getHash(UUID.randomUUID().toString());
//     }
// 
//     private static String getHash(String s) {
//         return DatatypeConverter.printHexBinary(DIGEST.digest(s.getBytes()));
//     }
// 
//     public static boolean validate(String token) {
//         if (validationTokens.containsKey(token) && validationTokens.get(token).isValid()) {
//             ValidationToken vt = validationTokens.get(token);
//             validKeys.add(getKey(vt.getSystemId(), vt.getEmail()));
//             validationTokens.remove(token);
//             // TODO: Might need to do this in a different thread, this will trigger 48 hours of messages
//             // Get the planning we need // TODO: Duplicated
//             List<RealtimeMessage> times = QuayDataProvider.getDataForQuay(vt.getSubscription().getSubscribedQuayCodes(), true);
//             sendStatus(vt.getSystemId(), true, DisplayDirectMessage.SubscriptionResponse.Status.AUTHORISATION_VALIDATED);
//             if (times.size() > 0) {
//                 LOGGER.debug("Got {} times to send", times.size());
//                 transport.sendMessage(TopicFactory.travelInformation(vt.getSystemId()), DisplayDirectMessageFactory.fromRealTime(times, vt.getSubscription()), QoS.AT_LEAST_ONCE);
//                 sendStatus(vt.getSystemId(), true, DisplayDirectMessage.SubscriptionResponse.Status.PLANNING_SENT);
//             } else {
//                 sendStatus(vt.getSystemId(), true, DisplayDirectMessage.SubscriptionResponse.Status.NO_PLANNING);
//             }
// 
//             SubscriptionStore.add(vt.getSubscription());
//             Log.send(LogCode.AUTHORISATION_VALIDATED, vt.getSystemId(), "Authorization processed");
//             Log.send(LogCode.SUBSCRIPTION_ADDED, vt.getSystemId(), "System subscribed succesfully, authorization processed");
//             return true;
//         }
//         return false;
//     }
// 
//     public static void remove(Subscription sub) {
//         // aah
//         validKeys.remove(getKey(sub.getId(), sub.getEmail()));
//     }
// 
//     public static List<ValidationToken> getTokens() {
//         return new ArrayList<>(validationTokens.values());
//     }
// 
//     public static List<String> getValid() {
//         return validKeys;
//     }
// 
//     // TODO: Duplicate method
//     private static boolean sendStatus(String id, boolean success, DisplayDirectMessage.SubscriptionResponse.Status s) {
//         return transport.sendMessage(TopicFactory.subscriptionResponse(id),  DisplayDirectMessageFactory.toSubscriptionStatus(success, s), QoS.EXACTLY_ONCE);
//     }
// }


import nl.crowndov.displaydirect.distribution.authorization.AuthorizationWhitelist;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
package nl.crowndov.displaydirect.distribution.resources;



/**
 * Copyright 2017 CROW-NDOV
 *
 * This file is subject to the terms and conditions defined in file 'LICENSE.txt', which is part of this source code package.
 */
@Path("/v1/authorization")
public class AuthorizationResource {

    @GET
    public Response get() {
// Path: distribution/src/main/java/nl/crowndov/displaydirect/distribution/authorization/AuthorizationWhitelist.java
// public class AuthorizationWhitelist extends AbstractService {
// 
//     private static final Logger LOGGER = LoggerFactory.getLogger(AuthorizationWhitelist.class);
// 
//     private static List<String> validKeys = new ArrayList<>();
//     private static Store.ValidationTokenStore validationTokens = new Store.ValidationTokenStore();
// 
//     private static Transport transport = TransportFactory.get();
// 
//     private static MessageDigest DIGEST = null;
// 
//     static {
//         try {
//             DIGEST = MessageDigest.getInstance("SHA-256");
//         } catch (NoSuchAlgorithmException e) {
//             LOGGER.error("Failed to initialize hash algorithm", e);
//         }
//     }
// 
//     public static void start() {
//         backup(() -> {
//             readFile("authorization_keys", Store.StringList.class).ifPresent(k -> validKeys = k);
//             readFile("authorization_tokens", Store.ValidationTokenStore.class).ifPresent(vt -> validationTokens = vt);
//         });
//     }
// 
//     public static void stop() {
//         writeFile("authorization_keys", validKeys);
//         writeFile("authorization_tokens", validationTokens);
//     }
// 
// 
//     public static boolean isValid(Subscription sub) {
//         return validKeys.contains(getKey(sub.getId(), sub.getEmail())) || Configuration.getAuthorizationWhitelist().contains(sub.getPrefix());
//     }
// 
//     private static String getKey(String systemId, String email) {
//         return systemId + "_" + email.toLowerCase();
//     }
// 
//     public static Optional<ValidationToken> addValidation(String systemId, Subscription subscribe) {
//         ZonedDateTime now = ZonedDateTime.now(Configuration.getZoneId());
//         // Check a validation token hasn't already been handed out for this system and it's still valid
//         if (validationTokens.values().stream().anyMatch(vt -> vt.getSystemId().contentEquals(systemId) && vt.getGenerated().plusHours(48).isAfter(now))) {
//             return Optional.empty();
//         }
//         ValidationToken v = new ValidationToken(newToken(), systemId, subscribe.getEmail(), ZonedDateTime.now(ZoneId.of("UTC")), subscribe);
//         validationTokens.put(v.getToken(), v);
// 
//         Map<String, Object> variables = new HashMap<>();
//         variables.put("id", systemId);
//         variables.put("description", subscribe.getDescription());
//         variables.put("url", Configuration.getBaseUrl() + "/admin/authorize?token=" + v.getToken());
//         EmailUtil.sendHtmlEmail(subscribe.getEmail(), "Rond aanmelding DisplayDirect af", "authenticate", variables);
// 
//         return Optional.ofNullable(v);
//     }
// 
//     private static String newToken() {
//         return getHash(UUID.randomUUID().toString());
//     }
// 
//     private static String getHash(String s) {
//         return DatatypeConverter.printHexBinary(DIGEST.digest(s.getBytes()));
//     }
// 
//     public static boolean validate(String token) {
//         if (validationTokens.containsKey(token) && validationTokens.get(token).isValid()) {
//             ValidationToken vt = validationTokens.get(token);
//             validKeys.add(getKey(vt.getSystemId(), vt.getEmail()));
//             validationTokens.remove(token);
//             // TODO: Might need to do this in a different thread, this will trigger 48 hours of messages
//             // Get the planning we need // TODO: Duplicated
//             List<RealtimeMessage> times = QuayDataProvider.getDataForQuay(vt.getSubscription().getSubscribedQuayCodes(), true);
//             sendStatus(vt.getSystemId(), true, DisplayDirectMessage.SubscriptionResponse.Status.AUTHORISATION_VALIDATED);
//             if (times.size() > 0) {
//                 LOGGER.debug("Got {} times to send", times.size());
//                 transport.sendMessage(TopicFactory.travelInformation(vt.getSystemId()), DisplayDirectMessageFactory.fromRealTime(times, vt.getSubscription()), QoS.AT_LEAST_ONCE);
//                 sendStatus(vt.getSystemId(), true, DisplayDirectMessage.SubscriptionResponse.Status.PLANNING_SENT);
//             } else {
//                 sendStatus(vt.getSystemId(), true, DisplayDirectMessage.SubscriptionResponse.Status.NO_PLANNING);
//             }
// 
//             SubscriptionStore.add(vt.getSubscription());
//             Log.send(LogCode.AUTHORISATION_VALIDATED, vt.getSystemId(), "Authorization processed");
//             Log.send(LogCode.SUBSCRIPTION_ADDED, vt.getSystemId(), "System subscribed succesfully, authorization processed");
//             return true;
//         }
//         return false;
//     }
// 
//     public static void remove(Subscription sub) {
//         // aah
//         validKeys.remove(getKey(sub.getId(), sub.getEmail()));
//     }
// 
//     public static List<ValidationToken> getTokens() {
//         return new ArrayList<>(validationTokens.values());
//     }
// 
//     public static List<String> getValid() {
//         return validKeys;
//     }
// 
//     // TODO: Duplicate method
//     private static boolean sendStatus(String id, boolean success, DisplayDirectMessage.SubscriptionResponse.Status s) {
//         return transport.sendMessage(TopicFactory.subscriptionResponse(id),  DisplayDirectMessageFactory.toSubscriptionStatus(success, s), QoS.EXACTLY_ONCE);
//     }
// }


// Path: distribution/src/main/java/nl/crowndov/displaydirect/distribution/resources/AuthorizationResource.java
import nl.crowndov.displaydirect.distribution.authorization.AuthorizationWhitelist;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;

package nl.crowndov.displaydirect.distribution.resources;



/**
 * Copyright 2017 CROW-NDOV
 *
 * This file is subject to the terms and conditions defined in file 'LICENSE.txt', which is part of this source code package.
 */
@Path("/v1/authorization")
public class AuthorizationResource {

    @GET
    public Response get() {
        return Response.ok(AuthorizationWhitelist.getValid()).build();