// Path: src/main/java/net/unicon/cas/addons/authentication/AuthenticationSupport.java
// public interface AuthenticationSupport {
// 
//     /**
//      * Retrieve a valid Authentication object identified by the provided TGT SSO token
//      * @param ticketGrantingTicketId an SSO token identifying the requested Authentication
//      * @return valid Authentication OR <b>NULL</b> if there is no valid SSO session present identified by the provided TGT id SSO token
//      * @throws RuntimeException
//      */
//     Authentication getAuthenticationFrom(String ticketGrantingTicketId) throws RuntimeException;
// 
//     /**
//      * Retrieve a valid Principal object identified by the provided TGT SSO token
//      * @param ticketGrantingTicketId an SSO token identifying the requested authenticated Principal
//      * @return valid Principal OR <b>NULL</b> if there is no valid SSO session present identified by the provided TGT id SSO token
//      * @throws RuntimeException
//      */
//     Principal getAuthenticatedPrincipalFrom(String ticketGrantingTicketId) throws RuntimeException;
// 
//     /**
//      * Retrieve a valid Principal's map of attributes identified by the provided TGT SSO token
//      * @param ticketGrantingTicketId an SSO token identifying the requested authenticated Principal's attributes
//      * @return valid Principal's attributes OR <b>NULL</b> if there is no valid SSO session present identified by the provided TGT id SSO token
//      * @throws RuntimeException
//      */
//     Map<String, Object> getPrincipalAttributesFrom(String ticketGrantingTicketId) throws RuntimeException;
// }
// 
// Path: src/main/java/net/unicon/cas/addons/authentication/internal/DefaultAuthenticationSupport.java
// public class DefaultAuthenticationSupport implements AuthenticationSupport {
// 
//     private TicketRegistry ticketRegistry;
// 
//     public DefaultAuthenticationSupport(TicketRegistry ticketRegistry) {
//         this.ticketRegistry = ticketRegistry;
//     }
// 
//     @Override
//     /** {@inheritDoc} */
//     public Authentication getAuthenticationFrom(String ticketGrantingTicketId) throws RuntimeException {
//         TicketGrantingTicket tgt = (TicketGrantingTicket) this.ticketRegistry.getTicket(ticketGrantingTicketId, TicketGrantingTicket.class);
//         return tgt == null ? null : tgt.getAuthentication();
//     }
// 
//     @Override
//     /** {@inheritDoc} */
//     public Principal getAuthenticatedPrincipalFrom(String ticketGrantingTicketId) throws RuntimeException {
//         Authentication auth = getAuthenticationFrom(ticketGrantingTicketId);
//         return auth == null ? null : auth.getPrincipal();
//     }
// 
//     @Override
//     /** {@inheritDoc} */
//     public Map<String, Object> getPrincipalAttributesFrom(String ticketGrantingTicketId) throws RuntimeException {
//         Principal principal = getAuthenticatedPrincipalFrom(ticketGrantingTicketId);
//         return principal == null ? null : principal.getAttributes();
//     }
// }
// 
// Path: src/main/java/net/unicon/cas/addons/serviceregistry/RegisteredServiceWithAttributes.java
// public interface RegisteredServiceWithAttributes extends RegisteredService {
// 
//     Map<String, Object> getExtraAttributes();
// 
// }


import net.unicon.cas.addons.authentication.AuthenticationSupport;
import net.unicon.cas.addons.authentication.internal.DefaultAuthenticationSupport;
import net.unicon.cas.addons.serviceregistry.RegisteredServiceWithAttributes;
import org.jasig.cas.authentication.principal.Principal;
import org.jasig.cas.authentication.principal.Service;
import org.jasig.cas.services.RegisteredService;
import org.jasig.cas.services.ServicesManager;
import org.jasig.cas.ticket.registry.TicketRegistry;
import org.jasig.cas.web.support.WebUtils;
import org.jasig.cas.services.UnauthorizedServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.webflow.action.AbstractAction;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
        this.servicesManager = servicesManager;
        this.authorizer = registeredServiceAuthorizer;
        this.authenticationSupport = new DefaultAuthenticationSupport(ticketRegistry);
    }

    @Override
    protected Event doExecute(final RequestContext requestContext) throws Exception {
        final Principal principal = this.authenticationSupport.getAuthenticatedPrincipalFrom(WebUtils.getTicketGrantingTicketId(requestContext));
        //Guard against expired SSO sessions. 'error' event should trigger the transition to the 'generateLoginTicket' state
        if (principal == null) {
            logger.warn("The SSO session is no longer valid. Restarting the login process...");
            return error();
        }
        final Object principalAttributes = principal.getAttributes();
        final String principalId = principal.getId();
        final Service service = WebUtils.getService(requestContext);
        final String serviceId = service.getId();

        //Find this service in the service registry
        final RegisteredService registeredService = this.servicesManager.findServiceBy(service);

        if (registeredService == null) {
            logger.warn("Unauthorized Service Access for Service: [ {} ] - service is not defined in the service registry.", serviceId);
            throw new UnauthorizedServiceException();
        }
        else if (!registeredService.isEnabled()) {
            logger.warn("Unauthorized Service Access for Service: [ {} ] - service is not enabled in the service registry.", serviceId);
            throw new UnauthorizedServiceException();
        }

// Path: src/main/java/net/unicon/cas/addons/authentication/AuthenticationSupport.java
// public interface AuthenticationSupport {
// 
//     /**
//      * Retrieve a valid Authentication object identified by the provided TGT SSO token
//      * @param ticketGrantingTicketId an SSO token identifying the requested Authentication
//      * @return valid Authentication OR <b>NULL</b> if there is no valid SSO session present identified by the provided TGT id SSO token
//      * @throws RuntimeException
//      */
//     Authentication getAuthenticationFrom(String ticketGrantingTicketId) throws RuntimeException;
// 
//     /**
//      * Retrieve a valid Principal object identified by the provided TGT SSO token
//      * @param ticketGrantingTicketId an SSO token identifying the requested authenticated Principal
//      * @return valid Principal OR <b>NULL</b> if there is no valid SSO session present identified by the provided TGT id SSO token
//      * @throws RuntimeException
//      */
//     Principal getAuthenticatedPrincipalFrom(String ticketGrantingTicketId) throws RuntimeException;
// 
//     /**
//      * Retrieve a valid Principal's map of attributes identified by the provided TGT SSO token
//      * @param ticketGrantingTicketId an SSO token identifying the requested authenticated Principal's attributes
//      * @return valid Principal's attributes OR <b>NULL</b> if there is no valid SSO session present identified by the provided TGT id SSO token
//      * @throws RuntimeException
//      */
//     Map<String, Object> getPrincipalAttributesFrom(String ticketGrantingTicketId) throws RuntimeException;
// }
// 
// Path: src/main/java/net/unicon/cas/addons/authentication/internal/DefaultAuthenticationSupport.java
// public class DefaultAuthenticationSupport implements AuthenticationSupport {
// 
//     private TicketRegistry ticketRegistry;
// 
//     public DefaultAuthenticationSupport(TicketRegistry ticketRegistry) {
//         this.ticketRegistry = ticketRegistry;
//     }
// 
//     @Override
//     /** {@inheritDoc} */
//     public Authentication getAuthenticationFrom(String ticketGrantingTicketId) throws RuntimeException {
//         TicketGrantingTicket tgt = (TicketGrantingTicket) this.ticketRegistry.getTicket(ticketGrantingTicketId, TicketGrantingTicket.class);
//         return tgt == null ? null : tgt.getAuthentication();
//     }
// 
//     @Override
//     /** {@inheritDoc} */
//     public Principal getAuthenticatedPrincipalFrom(String ticketGrantingTicketId) throws RuntimeException {
//         Authentication auth = getAuthenticationFrom(ticketGrantingTicketId);
//         return auth == null ? null : auth.getPrincipal();
//     }
// 
//     @Override
//     /** {@inheritDoc} */
//     public Map<String, Object> getPrincipalAttributesFrom(String ticketGrantingTicketId) throws RuntimeException {
//         Principal principal = getAuthenticatedPrincipalFrom(ticketGrantingTicketId);
//         return principal == null ? null : principal.getAttributes();
//     }
// }
// 
// Path: src/main/java/net/unicon/cas/addons/serviceregistry/RegisteredServiceWithAttributes.java
// public interface RegisteredServiceWithAttributes extends RegisteredService {
// 
//     Map<String, Object> getExtraAttributes();
// 
// }


// Path: src/main/java/net/unicon/cas/addons/serviceregistry/services/authorization/ServiceAuthorizationAction.java
import net.unicon.cas.addons.authentication.AuthenticationSupport;
import net.unicon.cas.addons.authentication.internal.DefaultAuthenticationSupport;
import net.unicon.cas.addons.serviceregistry.RegisteredServiceWithAttributes;
import org.jasig.cas.authentication.principal.Principal;
import org.jasig.cas.authentication.principal.Service;
import org.jasig.cas.services.RegisteredService;
import org.jasig.cas.services.ServicesManager;
import org.jasig.cas.ticket.registry.TicketRegistry;
import org.jasig.cas.web.support.WebUtils;
import org.jasig.cas.services.UnauthorizedServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.webflow.action.AbstractAction;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;

        this.servicesManager = servicesManager;
        this.authorizer = registeredServiceAuthorizer;
        this.authenticationSupport = new DefaultAuthenticationSupport(ticketRegistry);
    }

    @Override
    protected Event doExecute(final RequestContext requestContext) throws Exception {
        final Principal principal = this.authenticationSupport.getAuthenticatedPrincipalFrom(WebUtils.getTicketGrantingTicketId(requestContext));
        //Guard against expired SSO sessions. 'error' event should trigger the transition to the 'generateLoginTicket' state
        if (principal == null) {
            logger.warn("The SSO session is no longer valid. Restarting the login process...");
            return error();
        }
        final Object principalAttributes = principal.getAttributes();
        final String principalId = principal.getId();
        final Service service = WebUtils.getService(requestContext);
        final String serviceId = service.getId();

        //Find this service in the service registry
        final RegisteredService registeredService = this.servicesManager.findServiceBy(service);

        if (registeredService == null) {
            logger.warn("Unauthorized Service Access for Service: [ {} ] - service is not defined in the service registry.", serviceId);
            throw new UnauthorizedServiceException();
        }
        else if (!registeredService.isEnabled()) {
            logger.warn("Unauthorized Service Access for Service: [ {} ] - service is not enabled in the service registry.", serviceId);
            throw new UnauthorizedServiceException();
        }

        if (!(registeredService instanceof RegisteredServiceWithAttributes)) {