package Plack::Middleware::CAS;

use strict;
use warnings;
use Plack::Request;
use AnyEvent::HTTP;
use URI::Escape;
use parent qw(Plack::Middleware);

sub call {
    my ($self, $env) = @_;

    my $req = Plack::Request->new($env);
    my $session = $env->{'psgix.session'};
    my $ticket = $req->parameters->{ticket};

    if ($ticket) {
        return sub {
            my $responder = shift;
            my $app = $self->app;
            http_get "https://sso.univ-pau.fr/cas/validate?ticket=$ticket&service=" . $self->service($req), sub {
                my ($status, $login) = split(/\n/, $_[0]);
                if ($status eq 'yes' && $login) {
                    $session->{'cas.username'} = $login;
                    my $uri = $req->base;
                    $uri->path($uri->path . $req->path_info);
                    $responder->([ 302, [ 'Location', $uri->as_string ], [ '' ] ]);
                } else {
                    $responder->([ 400, [ 'Content-type', 'text/plain' ], [ 'Unable de validate CAS' ] ]);
                }
            };
        }

    } elsif (!$session->{'cas.username'}) {
        return $self->redirect($req);
    }

    $env->{user} = $session->{'cas.username'};
    my $res = $self->app->($env);

    return $res;
}

sub redirect {
    my ($self, $req) = @_;

    return [
        302,
        [ 'Location' => 'https://sso.univ-pau.fr/cas/login?service=' . $self->service($req) ],
        ['']
    ];
}

sub service {
    my ($self, $req) = @_;

    my $uri = $req->base;
    $uri->path($uri->path . $req->path_info);

    return uri_escape($uri->as_string);
}

1;

