Modularize Display/login (#1652)
parent
5a1c090a18
commit
8c562c7817
@ -0,0 +1,171 @@ |
||||
# IO::Handle filter. Used to transform HTML::Template on the fly. |
||||
package Lemonldap::NG::Common::IO::Filter; |
||||
use strict; |
||||
use IO::File; |
||||
use Symbol; |
||||
|
||||
#our @ISA = ('IO::File'); |
||||
|
||||
sub new { |
||||
my ( $class, $file, $opt ) = @_; |
||||
$opt->{_i} = ( ref $file ? $file : IO::File->new($file) ) |
||||
or die("Unable to build IO::File object $!"); |
||||
my $self = ref $class ? $class : bless gensym, $class; |
||||
tie( *$self, $class, $opt ); |
||||
return $self; |
||||
} |
||||
|
||||
sub TIEHANDLE { |
||||
my ( $class, $data ) = @_; |
||||
return bless( $data, $class ); |
||||
} |
||||
|
||||
sub READLINE { |
||||
my ($self) = shift; |
||||
my $res = $self->{_i}->getline; |
||||
foreach my $key ( keys %$self ) { |
||||
next if ( $key eq '_i' ); |
||||
if ( ref( $self->{$key} ) eq 'CODE' ) { |
||||
$res =~ s/__LLNG_${key}__/$self->{$key}->()/gse; |
||||
} |
||||
elsif ( ref $self->{$key} eq 'ARRAY' ) { |
||||
next; |
||||
} |
||||
elsif ( ref $self->{$key} ) { |
||||
local $/ = undef; |
||||
$res =~ s/__LLNG_${key}__/$self->{$key}->getline/gse; |
||||
} |
||||
} |
||||
|
||||
# Parse strings after code/IO |
||||
foreach my $key ( keys %$self ) { |
||||
die "Undefined value for __LLNG_${key}__ substitution" unless $self->{$key}; |
||||
my $v = (ref $self->{$key} and ref $self->{$key} eq 'ARRAY') ?$self->{$key}:[$self->{$key}]; |
||||
$v = join "\n", map {ref $_ ? () : qq'<TMPL_INCLUDE NAME="$_.tpl">'} @$v; |
||||
$res =~ s/__LLNG_${key}__/$v/gs; |
||||
} |
||||
return $res; |
||||
} |
||||
|
||||
sub DESTROY { |
||||
my ($self) = @_; |
||||
$self->close() if ( ref($self) eq 'SCALAR' ); |
||||
} |
||||
|
||||
sub AUTOLOAD { |
||||
no strict; |
||||
my $self = shift; |
||||
$AUTOLOAD =~ s/^.*:://; |
||||
$AUTOLOAD = lc $AUTOLOAD; |
||||
return tied( ${$self} )->{_i}->$AUTOLOAD(@_); |
||||
} |
||||
|
||||
1; |
||||
__END__ |
||||
=head1 NAME |
||||
|
||||
Lemonldap::NG::Common::IO::Filter - IO::Handle filter |
||||
|
||||
=head1 SYNOPSIS |
||||
|
||||
use HTML::Template; |
||||
my $fh = Lemonldap::NG::Common::IO::Filter->new( |
||||
'template.tpl', |
||||
{ |
||||
# Replace all __LLNG_AUTH__ by: |
||||
# <TMPL_INCLUDE NAME="login.tpl"> |
||||
AUTH => 'login', |
||||
# Replace all __LLNG_CODE__ by the result of the given function |
||||
CODE => sub {return "INCLUDED STRING"} |
||||
} |
||||
); |
||||
my $h = HTML::Template->new( filehandle => $fh ); |
||||
print $h->output; |
||||
|
||||
Input: |
||||
|
||||
<html><body> |
||||
__LLNG_AUTH__ |
||||
<hr> |
||||
__LLNG_CODE__ |
||||
</body></html> |
||||
|
||||
Output: |
||||
|
||||
<html><body> |
||||
<TMPL_INCLUDE NAME="login.tpl"> |
||||
<hr> |
||||
INCLUDED STRING |
||||
</body></html> |
||||
|
||||
Same but with a L<IO::Handle> file: |
||||
|
||||
use HTML::Template; |
||||
my $file = IO::File->new('test.tpl'); |
||||
my $fh = Lemonldap::NG::Common::IO::Filter->new_from_io( |
||||
$file, |
||||
{ |
||||
# Replace all __LLNG_AUTH__ by: |
||||
# <TMPL_INCLUDE NAME="login.tpl"> |
||||
AUTH => 'login', |
||||
# Replace all __LLNG_CODE__ by the result of the given function |
||||
CODE => sub {return "INCLUDED STRING"} |
||||
} |
||||
); |
||||
my $h = HTML::Template->new( filehandle => $fh ); |
||||
print $h->output; |
||||
|
||||
Or with an array: |
||||
|
||||
use HTML::Template; |
||||
my $fh = Lemonldap::NG::Common::IO::Filter->new_from_io( |
||||
'template.tpl', |
||||
{ |
||||
# Replace all __LLNG_AUTH__ by: |
||||
# <TMPL_INCLUDE NAME="login.tpl"> <TMPL_INCLUDE NAME="login2.tpl"> |
||||
AUTH => [ 'login', 'login2' ], |
||||
} |
||||
); |
||||
my $h = HTML::Template->new( filehandle => $fh ); |
||||
print $h->output; |
||||
|
||||
=head1 DESCRIPTION |
||||
|
||||
IO::Handle filter used to transform HTML::Template files on the fly. |
||||
|
||||
=head1 AUTHORS |
||||
|
||||
=over |
||||
|
||||
=item LemonLDAP::NG team L<http://lemonldap-ng.org/team> |
||||
|
||||
=back |
||||
|
||||
=head1 BUG REPORT |
||||
|
||||
Use OW2 system to report bug or ask for features: |
||||
L<https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues> |
||||
|
||||
=head1 DOWNLOAD |
||||
|
||||
Lemonldap::NG is available at |
||||
L<http://forge.objectweb.org/project/showfiles.php?group_id=274> |
||||
|
||||
=head1 COPYRIGHT AND LICENSE |
||||
|
||||
See COPYING file for details. |
||||
|
||||
This library is free software; you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation; either version 2, or (at your option) |
||||
any later version. |
||||
|
||||
This program is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with this program. If not, see L<http://www.gnu.org/licenses/>. |
||||
|
||||
=cut |
@ -0,0 +1,45 @@ |
||||
use Test::More tests => 10; |
||||
use strict; |
||||
use HTML::Template; |
||||
use IO::String; |
||||
|
||||
use_ok('Lemonldap::NG::Common::IO::Filter'); |
||||
|
||||
my ( $b, $t ); |
||||
|
||||
# Template name |
||||
ok( |
||||
$b = Lemonldap::NG::Common::IO::Filter->new( |
||||
't/test.tpl', { FORM => 't/inc' } |
||||
), |
||||
'Build IO filter (file.tpl)' |
||||
); |
||||
ok( $t = HTML::Template->new( filehandle => $b ), |
||||
'Build HTML::Template object' ); |
||||
ok( $t->output =~ /XX\s+YY\s+ZZ/s, 'Substitution works' ); |
||||
|
||||
# Code ref |
||||
my $s = IO::String->new('XX __LLNG_AUTH__ ZZ'); |
||||
ok( |
||||
$b = Lemonldap::NG::Common::IO::Filter->new( |
||||
$s, |
||||
{ |
||||
AUTH => sub { 'YY' } |
||||
} |
||||
), |
||||
'Build IO filter (code ref)' |
||||
); |
||||
ok( $t = HTML::Template->new( filehandle => $b ), |
||||
'Build HTML::Template object' ); |
||||
ok( $t->output eq 'XX YY ZZ', 'Substitution works' ); |
||||
|
||||
# IO ref |
||||
ok( |
||||
$b = Lemonldap::NG::Common::IO::Filter->new( |
||||
't/test.tpl', { FORM => IO::File->new('t/inc.tpl'), AUTH => 't/inc' } |
||||
), |
||||
'Build IO filter (IO ref)' |
||||
); |
||||
ok( $t = HTML::Template->new( filehandle => $b ), |
||||
'Build HTML::Template object' ); |
||||
ok( $t->output =~ /XX\s+YY\s+ZZ/s, 'Substitution works' ); |
@ -0,0 +1,3 @@ |
||||
|
||||
YY |
||||
|
@ -0,0 +1 @@ |
||||
XX __LLNG_FORM__ ZZ |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,18 +1,24 @@ |
||||
# Launch Kerberos request |
||||
|
||||
_krbJsAlreadySent = false if _krbJsAlreadySent == null |
||||
$(document).ready -> |
||||
$.ajax portal + '?kerberos=1', |
||||
dataType: 'json' |
||||
# Called if browser can't find Kerberos ticket, will display |
||||
# PE_BADCREDENTIALS |
||||
statusCode: |
||||
401: () -> |
||||
unless _krbJsAlreadySent |
||||
_krbJsAlreadySent = 1 |
||||
console.log 'Send Kerberos Ajax request' |
||||
$.ajax portal + '?kerberos=1', |
||||
dataType: 'json' |
||||
# Called if browser can't find Kerberos ticket, will display |
||||
# PE_BADCREDENTIALS |
||||
statusCode: |
||||
401: () -> |
||||
$('#lformKerberos').submit() |
||||
# If request succeed cookie is set, posting form to get redirection |
||||
# or menu |
||||
success: (data) -> |
||||
$('#lformKerberos').submit() |
||||
# If request succeed cookie is set, posting form to get redirection |
||||
# or menu |
||||
success: (data) -> |
||||
$('#lformKerberos').submit() |
||||
# Case else, will display PE_BADCREDENTIALS or fallback to next auth |
||||
# backend |
||||
error: () -> |
||||
$('#lformKerberos').submit() |
||||
# Case else, will display PE_BADCREDENTIALS or fallback to next auth |
||||
# backend |
||||
error: () -> |
||||
$('#lformKerberos').submit() |
||||
else |
||||
console.log 'Kerberos Ajax request already sent' |
||||
|
@ -1,20 +1,32 @@ |
||||
// Generated by CoffeeScript 1.12.8
|
||||
(function() { |
||||
var _krbJsAlreadySent; |
||||
|
||||
if (_krbJsAlreadySent === null) { |
||||
_krbJsAlreadySent = false; |
||||
} |
||||
|
||||
$(document).ready(function() { |
||||
return $.ajax(portal + '?kerberos=1', { |
||||
dataType: 'json', |
||||
statusCode: { |
||||
401: function() { |
||||
if (!_krbJsAlreadySent) { |
||||
_krbJsAlreadySent = 1; |
||||
console.log('Send Kerberos Ajax request'); |
||||
return $.ajax(portal + '?kerberos=1', { |
||||
dataType: 'json', |
||||
statusCode: { |
||||
401: function() { |
||||
return $('#lformKerberos').submit(); |
||||
} |
||||
}, |
||||
success: function(data) { |
||||
return $('#lformKerberos').submit(); |
||||
}, |
||||
error: function() { |
||||
return $('#lformKerberos').submit(); |
||||
} |
||||
}, |
||||
success: function(data) { |
||||
return $('#lformKerberos').submit(); |
||||
}, |
||||
error: function() { |
||||
return $('#lformKerberos').submit(); |
||||
} |
||||
}); |
||||
}); |
||||
} else { |
||||
return console.log('Kerberos Ajax request already sent'); |
||||
} |
||||
}); |
||||
|
||||
}).call(this); |
||||
|
@ -1 +1 @@ |
||||
(function(){$(document).ready(function(){return $.ajax(portal+"?kerberos=1",{dataType:"json",statusCode:{401:function(){return $("#lformKerberos").submit()}},success:function(data){return $("#lformKerberos").submit()},error:function(){return $("#lformKerberos").submit()}})})}).call(this); |
||||
(function(){var _krbJsAlreadySent;if(_krbJsAlreadySent===null){_krbJsAlreadySent=false}$(document).ready(function(){if(!_krbJsAlreadySent){_krbJsAlreadySent=1;console.log("Send Kerberos Ajax request");return $.ajax(portal+"?kerberos=1",{dataType:"json",statusCode:{401:function(){return $("#lformKerberos").submit()}},success:function(data){return $("#lformKerberos").submit()},error:function(){return $("#lformKerberos").submit()}})}else{return console.log("Kerberos Ajax request already sent")}})}).call(this); |
||||
|
@ -0,0 +1,31 @@ |
||||
</form> |
||||
<div id="authMenu" class="card"> |
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light"> |
||||
<a class="navbar-brand" href="/"><i class="fa fa-user-circle"></i></a> |
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> |
||||
<span class="navbar-toggler-icon"></span> |
||||
</button> |
||||
|
||||
<!-- Choice tabs --> |
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent"> |
||||
<ul class="navbar-nav mr-auto"> |
||||
<TMPL_LOOP NAME="AUTH_LOOP"> |
||||
<li class="nav-item" title="<TMPL_VAR NAME="key">"><a class="nav-link" href="#<TMPL_VAR NAME="key">"><TMPL_VAR NAME="name"></a></li> |
||||
</TMPL_LOOP> |
||||
</ul> |
||||
</div> |
||||
</nav> |
||||
<div> |
||||
<TMPL_LOOP NAME="AUTH_LOOP"> |
||||
<div id="<TMPL_VAR NAME="key">"> |
||||
<form id="lform<TMPL_VAR NAME="module">" action="<TMPL_VAR NAME="url">" method="post" class="login <TMPL_VAR NAME="module">"> |
||||
<TMPL_VAR NAME="HIDDEN_INPUTS"> |
||||
<input type="hidden" name="url" value="<TMPL_VAR NAME="AUTH_URL">" /> |
||||
<input type="hidden" name="timezone" /> |
||||
<input type="hidden" name="<TMPL_VAR NAME="CHOICE_PARAM">" value="<TMPL_VAR NAME="key">" /> |
||||
<input type="hidden" name="skin" value="<TMPL_VAR NAME="SKIN">" /> |
||||
__LLNG_FORM__ |
||||
</form> |
||||
</div> |
||||
</TMPL_LOOP> |
||||
<form> |
@ -0,0 +1,27 @@ |
||||
<TMPL_IF NAME="CHOICE_PARAM"> |
||||
<!-- //if:jsminified |
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">common/js/kerberosChoice.min.js"></script> |
||||
//else --> |
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">common/js/kerberosChoice.js"></script> |
||||
<!-- //endif --> |
||||
<TMPL_ELSE> |
||||
<!-- //if:jsminified |
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">common/js/kerberos.min.js"></script> |
||||
//else --> |
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">common/js/kerberos.js"></script> |
||||
<!-- //endif --> |
||||
</TMPL_IF> |
||||
<div class="form"> |
||||
<input type="hidden" name="kerberos" value="0" /> |
||||
<div class="sslclick"> |
||||
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/modules/Kerberos.png" alt="<TMPL_VAR NAME="module">" class="img-thumbnail mb-3" /> |
||||
</div> |
||||
|
||||
<TMPL_INCLUDE NAME="impersonation.tpl"> |
||||
<TMPL_INCLUDE NAME="checklogins.tpl"> |
||||
|
||||
<button type="submit" class="btn btn-success sslclick" > |
||||
<span class="fa fa-sign-in"></span> |
||||
<span trspan="connect">Connect</span> |
||||
</button> |
||||
</div> |
@ -0,0 +1,14 @@ |
||||
<div class="card"> |
||||
<div class="form"> |
||||
<TMPL_IF NAME="CUSTOM_LOGO"> |
||||
<img src="<TMPL_VAR NAME="STATIC_PREFIX"><TMPL_VAR NAME="CUSTOM_LOGO">" class="img-thumbnail" /> |
||||
</TMPL_IF> |
||||
|
||||
<div class="buttons"> |
||||
<button type="submit" class="btn btn-success"> |
||||
<span class="fa fa-sign-in"></span> |
||||
<span trspan="connect">Connect</span> |
||||
</button> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -1,20 +0,0 @@ |
||||
<!-- //if:jsminified |
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">common/js/sslChoice.min.js"></script> |
||||
//else --> |
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">common/js/sslChoice.js"></script> |
||||
<!-- //endif --> |
||||
|
||||
<div class="form"> |
||||
<input type="hidden" name="nossl" value="1" /> |
||||
<div class="sslclick"> |
||||
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/modules/SSL.png" alt="<TMPL_VAR NAME="module">" class="img-thumbnail mb-3" /> |
||||
</div> |
||||
|
||||
<TMPL_INCLUDE NAME="impersonation.tpl"> |
||||
<TMPL_INCLUDE NAME="checklogins.tpl"> |
||||
|
||||
<button type="submit" class="btn btn-success sslclick" > |
||||
<span class="fa fa-sign-in"></span> |
||||
<span trspan="connect">Connect</span> |
||||
</button> |
||||
</div> |
Loading…
Reference in new issue