From 56fdc166c91e3bcf5f9eba86436b176952322bbd Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 16 Oct 2016 21:37:27 +0100 Subject: [PATCH] All aboard the refactor tractor --- blocks/ORB/Login.pm | 380 +++++++++++-------- templates/default/api/docs.tem | 102 +++++ templates/default/api/html_error.tem | 1 + templates/default/api/html_wrapper.tem | 7 + templates/default/css/foundation.mods.css | 23 ++ templates/default/css/login.css | 4 + templates/default/error/error_box.tem | 6 + templates/default/error/error_item.tem | 1 + templates/default/error/error_list.tem | 2 + templates/default/images/error.png | Bin 0 -> 3259 bytes templates/default/images/important.png | Bin 0 -> 3078 bytes templates/default/login/extrahead.tem | 1 + templates/default/login/extrajs.tem | 12 + templates/default/login/form.tem | 34 ++ templates/default/login/persist_disabled.tem | 1 + templates/default/login/persist_enabled.tem | 4 + templates/default/messagebox.tem | 15 + templates/default/messagebox_button.tem | 1 + templates/default/messagebox_buttonbar.tem | 1 + templates/default/page.tem | 30 ++ templates/default/userbar/userbar.tem | 9 + templates/default/validator_harness.tem | 10 + 22 files changed, 480 insertions(+), 164 deletions(-) create mode 100755 templates/default/api/docs.tem create mode 100755 templates/default/api/html_error.tem create mode 100755 templates/default/api/html_wrapper.tem create mode 100755 templates/default/css/foundation.mods.css create mode 100755 templates/default/css/login.css create mode 100755 templates/default/error/error_box.tem create mode 100755 templates/default/error/error_item.tem create mode 100755 templates/default/error/error_list.tem create mode 100755 templates/default/images/error.png create mode 100755 templates/default/images/important.png create mode 100755 templates/default/login/extrahead.tem create mode 100755 templates/default/login/extrajs.tem create mode 100755 templates/default/login/form.tem create mode 100755 templates/default/login/persist_disabled.tem create mode 100755 templates/default/login/persist_enabled.tem create mode 100755 templates/default/messagebox.tem create mode 100755 templates/default/messagebox_button.tem create mode 100755 templates/default/messagebox_buttonbar.tem create mode 100755 templates/default/page.tem create mode 100755 templates/default/userbar/userbar.tem create mode 100755 templates/default/validator_harness.tem diff --git a/blocks/ORB/Login.pm b/blocks/ORB/Login.pm index 0e7f938..43ebbcd 100755 --- a/blocks/ORB/Login.pm +++ b/blocks/ORB/Login.pm @@ -1,5 +1,5 @@ ## @file -# This file contains the implementation of the login/logout facility. +# This file contains the implementation of the login/signout facility. # # @author Chris Page <chris@starforge.co.uk> # @@ -26,7 +26,7 @@ use strict; use parent qw(ORB); # This class extends the ORB block class use experimental qw(smartmatch); use Webperl::Utils qw(path_join is_defined_numeric); -use v5.12; +use v5.14; # ============================================================================ # Emailer functions @@ -226,7 +226,7 @@ sub validate_login { "formattest" => '^[-\w]+$', "formatdesc" => $self -> {"template"} -> replace_langvar("LOGIN_ERR_BADUSERCHAR")}); # Bomb out at this point if the username is not valid. - return ($self -> {"template"} -> load_template("login/error.tem", {"***reason***" => $error}), $args) + return ($self -> {"template"} -> load_template("login/error.tem", {"%(reason)s" => $error}), $args) if($error); # Do the same with the password... @@ -234,7 +234,7 @@ sub validate_login { "nicename" => $self -> {"template"} -> replace_langvar("LOGIN_PASSWORD"), "minlen" => 2, "maxlen" => 255}); - return ($self -> {"template"} -> load_template("login/error.tem", {"***reason***" => $error}), $args) + return ($self -> {"template"} -> load_template("login/error.tem", {"%(reason)s" => $error}), $args) if($error); # Username and password appear to be present and contain sane characters. Try to log the user in... @@ -250,8 +250,8 @@ sub validate_login { } else { # Otherwise, send back the 'account needs activating' error return ($self -> {"template"} -> load_template("login/error.tem", - {"***reason***" => $self -> {"template"} -> replace_langvar("LOGIN_ERR_INACTIVE", - { "***url-resend***" => $self -> build_url("block" => "login", "pathinfo" => [ "resend" ]) }) + {"%(reason)s" => $self -> {"template"} -> replace_langvar("LOGIN_ERR_INACTIVE", + { "***url-resend***" => $self -> build_url("block" => "login", "pathinfo" => [ "resend" ]) }) }), $args); } } @@ -297,10 +297,7 @@ sub validate_login { } # limiting not supported, or username is bunk - return the failure message as-is - return ($self -> {"template"} -> load_template("login/error.tem", - { - "***reason***" => $failmsg - }), $args); + return ($self -> {"template"} -> load_template("login/error.tem", { "%(reason)" => $failmsg }), $args); } @@ -705,28 +702,21 @@ sub generate_login_form { my $args = shift; # Wrap the error message in a message box if we have one. - $error = $self -> {"template"} -> load_template("login/error_box.tem", {"***message***" => $error}) + $error = $self -> {"template"} -> load_template("login/error_box.tem", {"%(message)s" => $error}) if($error); - # Persist length is always in seconds, so convert it to something more readable - my $persist_length = $self -> {"template"} -> humanise_seconds($self -> {"session"} -> {"auth"} -> get_config("max_autologin_time")); - - # if self-registration is enabled, turn on the option - my $self_register = $self -> {"settings"} -> {"config"} -> {"Login:allow_self_register"} ? - $self -> {"template"} -> load_template("login/selfreg.tem") : - $self -> {"template"} -> load_template("login/no_selfreg.tem"); + my $persist = $self -> {"settings"} -> {"config"} -> {"Auth:allow_autologin"} ? + $self -> {"template"} -> load_template("login/persist_enabled.tem") : + $self -> {"template"} -> load_template("login/persist_disabled.tem"); return ($self -> {"template"} -> replace_langvar("LOGIN_TITLE"), - $self -> {"template"} -> load_template("login/form.tem", {"***error***" => $error, - "***persistlen***" => $persist_length, - "***selfreg***" => $self_register, - "***url-actform***" => $self -> build_url("block" => "login", "pathinfo" => [ "activate" ]), - "***url-recform***" => $self -> build_url("block" => "login", "pathinfo" => [ "recover" ]), - "***target***" => $self -> build_url("block" => "login"), - "***question***" => $self -> {"settings"} -> {"config"} -> {"Login:self_register_question"}, - "***username***" => $args -> {"username"}, - "***regname***" => $args -> {"regname"}, - "***email***" => $args -> {"email"}})); + $self -> {"template"} -> load_template("login/form.tem", {"%(error)s" => $error, + "%(persist)s" => $persist, + "%(url-forgot)s" => $self -> build_url("block" => "login", "pathinfo" => [ "recover" ]), + "%(target)s" => $self -> build_url("block" => "login"), + "%(username)s" => $args -> {"username"}}), + $self -> {"template"} -> load_template("login/extrahead.tem"), + $self -> {"template"} -> load_template("login/extrajs.tem")); } @@ -846,22 +836,27 @@ sub generate_loggedin { # If any warnings were encountered, send back a different logged-in page to avoid # confusing users. if(!$warning) { - # Note that, while it would be nice to immediately redirect users at this point, - $content = $self -> {"template"} -> message_box($self -> {"template"} -> replace_langvar("LOGIN_DONETITLE"), - "security", - $self -> {"template"} -> replace_langvar("LOGIN_SUMMARY"), - $self -> {"template"} -> replace_langvar("LOGIN_LONGDESC", {"***url***" => $url}), - undef, - "logincore", - [ {"message" => $self -> {"template"} -> replace_langvar("SITE_CONTINUE"), - "colour" => "blue", - "action" => "location.href='$url'"} ]); - $extrahead = $self -> {"template"} -> load_template("refreshmeta.tem", {"***url***" => $url}); + # Do a redirect to the return URL. This bypasses problems with double-post, and + # avoids the need for an interstitial. There is ambiguity about whether 302/303 + # responses should contain cookies, but all major browsers support doing this + # (see, eg http://blog.dubbelboer.com/2012/11/25/302-cookie.html ) + print $self -> {"cgi"} -> redirect( -url => $url, + -charset => 'utf-8', + -cookie => $self -> {"session"} -> session_cookies()); + # Prevent circular references from messing up shutdown + $self -> {"template"} -> set_module_obj(undef); + $self -> {"messages"} -> set_module_obj(undef); + $self -> {"system"} -> clear() if($self -> {"system"}); + $self -> {"appuser"} -> set_system(undef) if($self -> {"appuser"}); + + $self -> {"dbh"} -> disconnect(); + $self -> {"logger"} -> end_log(); + exit; # Users who have encountered warnings during login always get a login confirmation page, as it has # to show them the warning message box. } else { - my $message = $self -> {"template"} -> message_box($self -> {"template"} -> replace_langvar("LOGIN_DONETITLE"), + my $message = $self -> message_box($self -> {"template"} -> replace_langvar("LOGIN_DONETITLE"), "security", $self -> {"template"} -> replace_langvar("LOGIN_SUMMARY"), $self -> {"template"} -> replace_langvar("LOGIN_NOREDIRECT", {"***url***" => $url, @@ -882,12 +877,12 @@ sub generate_loggedin { } -## @method private @ generate_loggedout() +## @method private @ generate_signedout() # Generate the contents of a page telling the user that they have successfully logged out. # # @return An array of three values: the page title string, the 'logged out' message, and # a meta element to insert into the head element to redirect the user. -sub generate_loggedout { +sub generate_signedout { my $self = shift; # NOTE: This is called **after** the session is deleted, so savestate will be undef. This @@ -896,7 +891,7 @@ sub generate_loggedout { # return the title, content, and extraheader return ($self -> {"template"} -> replace_langvar("LOGOUT_TITLE"), - $self -> {"template"} -> message_box($self -> {"template"} -> replace_langvar("LOGOUT_TITLE"), + $self -> message_box($self -> {"template"} -> replace_langvar("LOGOUT_TITLE"), "security", $self -> {"template"} -> replace_langvar("LOGOUT_SUMMARY"), $self -> {"template"} -> replace_langvar("LOGOUT_LONGDESC", {"***url***" => $url}), @@ -921,7 +916,7 @@ sub generate_activated { pathinfo => []); return ($self -> {"template"} -> replace_langvar("LOGIN_ACT_DONETITLE"), - $self -> {"template"} -> message_box($self -> {"template"} -> replace_langvar("LOGIN_ACT_DONETITLE"), + $self -> message_box($self -> {"template"} -> replace_langvar("LOGIN_ACT_DONETITLE"), "security", $self -> {"template"} -> replace_langvar("LOGIN_ACT_SUMMARY"), $self -> {"template"} -> replace_langvar("LOGIN_ACT_LONGDESC", @@ -946,7 +941,7 @@ sub generate_registered { pathinfo => [ "activate" ]); return ($self -> {"template"} -> replace_langvar("LOGIN_REG_DONETITLE"), - $self -> {"template"} -> message_box($self -> {"template"} -> replace_langvar("LOGIN_REG_DONETITLE"), + $self -> message_box($self -> {"template"} -> replace_langvar("LOGIN_REG_DONETITLE"), "security", $self -> {"template"} -> replace_langvar("LOGIN_REG_SUMMARY"), $self -> {"template"} -> replace_langvar("LOGIN_REG_LONGDESC"), @@ -969,7 +964,7 @@ sub generate_resent { my $url = $self -> build_url("block" => "login", "pathinfo" => [ "activate" ]); return ($self -> {"template"} -> replace_langvar("LOGIN_RESEND_DONETITLE"), - $self -> {"template"} -> message_box($self -> {"template"} -> replace_langvar("LOGIN_RESEND_DONETITLE"), + $self -> message_box($self -> {"template"} -> replace_langvar("LOGIN_RESEND_DONETITLE"), "security", $self -> {"template"} -> replace_langvar("LOGIN_RESEND_SUMMARY"), $self -> {"template"} -> replace_langvar("LOGIN_RESEND_LONGDESC"), @@ -992,7 +987,7 @@ sub generate_recover { my $url = $self -> build_url("block" => "login", "pathinfo" => []); return ($self -> {"template"} -> replace_langvar("LOGIN_RECOVER_DONETITLE"), - $self -> {"template"} -> message_box($self -> {"template"} -> replace_langvar("LOGIN_RECOVER_DONETITLE"), + $self -> message_box($self -> {"template"} -> replace_langvar("LOGIN_RECOVER_DONETITLE"), "security", $self -> {"template"} -> replace_langvar("LOGIN_RECOVER_SUMMARY"), $self -> {"template"} -> replace_langvar("LOGIN_RECOVER_LONGDESC"), @@ -1018,7 +1013,7 @@ sub generate_reset { if(!$error) { return ($self -> {"template"} -> replace_langvar("LOGIN_RESET_DONETITLE"), - $self -> {"template"} -> message_box($self -> {"template"} -> replace_langvar("LOGIN_RESET_DONETITLE"), + $self -> message_box($self -> {"template"} -> replace_langvar("LOGIN_RESET_DONETITLE"), "security", $self -> {"template"} -> replace_langvar("LOGIN_RESET_SUMMARY"), $self -> {"template"} -> replace_langvar("LOGIN_RESET_LONGDESC"), @@ -1029,7 +1024,7 @@ sub generate_reset { "action" => "location.href='$url'"} ])); } else { return ($self -> {"template"} -> replace_langvar("LOGIN_RESET_ERRTITLE"), - $self -> {"template"} -> message_box($self -> {"template"} -> replace_langvar("LOGIN_RESET_ERRTITLE"), + $self -> message_box($self -> {"template"} -> replace_langvar("LOGIN_RESET_ERRTITLE"), "error", $self -> {"template"} -> replace_langvar("LOGIN_RESET_ERRSUMMARY"), $self -> {"template"} -> replace_langvar("LOGIN_RESET_ERRDESC", {"***reason***" => $error}), @@ -1092,61 +1087,156 @@ sub _build_login_response { # ============================================================================ # Interface functions -## @method $ page_display() -# Generate the page content for this module. -sub page_display { +sub _handle_signout { my $self = shift; - # Is this an API call, or a normal page operation? - my $apiop = $self -> is_api_operation(); - if(defined($apiop)) { - # API call - dispatch to appropriate handler. - given($apiop) { - when("check") { return $self -> api_response ($self -> _build_login_check_response()); } - when("loginform") { return $self -> api_html_response($self -> _build_loginform_response()); } - when("login") { return $self -> api_response ($self -> _build_login_response()); } + # User must be logged in to log out + return $self -> _generate_not_loggedin() + if($self -> {"session"} -> anonymous_session()); - default { - return $self -> api_response($self -> api_errorhash('bad_op', - $self -> {"template"} -> replace_langvar("API_BAD_OP"))) - } - } + # User is logged in, do the signout + $self -> log("signout", $self -> {"session"} -> get_session_userid()); + if($self -> {"session"} -> delete_session()) { + return $self -> _generate_signedout(); } else { - # We need to determine what the page title should be, and the content to shove in it... - my ($title, $body, $extrahead) = ("", "", ""); - my @pathinfo = $self -> {"cgi"} -> multi_param("pathinfo"); + return $self -> _generate_fatal($SessionHandler::errstr); + } +} + + +sub _handle_activate { + my $self = shift; + + # Does the get/post data include an activation code? If so, check it + if(defined($self -> {"cgi"} -> param("actcode"))) { + my ($user, $args) = $self -> _validate_actcode(); + if(!ref($user)) { + $self -> log("activation error", $user); + return $self -> _generate_actcode_form($user); + } else { + $self -> log("activation success", $user -> {"username"}); + return $self -> _generate_activated($user); + } + } + + # Otherwise, just return the activation form + return $self -> _generate_actcode_form(); +} + + +sub _handle_recover { + my $self = shift; + + if(defined($self -> {"cgi"} -> param("dorecover"))) { + my ($user, $args) = $self -> _validate_recover(); + if(!ref($user)) { + $self -> log("Reset error", $user); + return $self -> _generate_recover_form($user); + } else { + $self -> log("Reset success", $user -> {"username"}); + return $self -> _generate_recover($user); + } + } + + return $self -> _generate_recover_form(); +} + + +sub _handle_resend { + my $self = shift; + + if(defined($self -> {"cgi"} -> param("doresend"))) { + my ($user, $args) = $self -> _validate_resend(); + if(!ref($user)) { + $self -> log("Resend error", $user); + return $self -> _generate_resend_form($user); + } else { + $self -> log("Resend success", $user -> {"username"}); + return $self -> _generate_resent($user); + } + } + + return $self -> _generate_resend_form(); +} + + +sub _handle_signup { + my $self = shift; + + if(defined($self -> {"cgi"} -> param("signup"))) { + # Validate/perform the registration + my ($user, $args) = $self -> _validate_signup(); + + # Do we have any errors? If so, send back the login form with them + if(!ref($user)) { + $self -> log("registration error", $user); + return $self -> _generate_signup_form($user, $args); + + # No errors, user is registered + } else { + # Do not create a new session - the user needs to confirm the account. + $self -> log("registered inactive", $user -> {"username"}); + return $self -> _generate_signedup(); + } + } + + return $self -> _generate_signup_form(); +} + + +sub _handle_changepass { + my $self = shift; + + if(defined($self -> {"cgi"} -> param("changepass"))) { + # Check the password is valid + my ($user, $args) = $self -> validate_passchange(); + + # Change failed, send back the change form + if(!ref($user)) { + $self -> log("passchange error", $user); + return $self -> _generate_passchange_form($user); + + # Change done, send back the loggedin page + } else { + $self -> log("password updated", $user); + return $self -> _generate_loggedin(); + } + } + + return $self -> _generate_passchange_form(); +} + + +sub _dispatch_ui { + my $self = shift; + + # We need to determine what the page title should be, and the content to shove in it... + my ($title, $body, $extrahead, $extrajs) = ("", "", "", ""); + my @pathinfo = $self -> {"cgi"} -> multi_param("pathinfo"); + + given($pathinfo[0]) { + when("signup") { ($title, $body, $extrahead, $extrajs) = $self -> _handle_signup(); } + when("signout") { ($title, $body, $extrahead, $extrajs) = $self -> _handle_signout(); } + when("activate") { ($title, $body, $extrahead, $extrajs) = $self -> _handle_activate(); } + when("recover") { ($title, $body, $extrahead, $extrajs) = $self -> _handle_recover(); } + when("resend") { ($title, $body, $extrahead, $extrajs) = $self -> _handle_resend(); } + when("passchange") { ($title, $body, $extrahead, $extrajs) = $self -> _handle_passchange(); } + + default { + ($title, $body, $extrahead, $extrajs) = $self -> generate_login_form(); + } + } + + # Done generating the page content, return the filled in page template + return $self -> generate_orb_page($title, $body, $extrahead, $extrajs, 'login'); +} + # User is attempting to do a password change - if(defined($self -> {"cgi"} -> param("changepass"))) { - - # Check the password is valid - my ($user, $args) = $self -> validate_passchange(); - - # Change failed, send back the change form - if(!ref($user)) { - $self -> log("passchange error", $user); - ($title, $body) = $self -> generate_passchange_form($user); - - # Change done, send back the loggedin page - } else { - $self -> log("password updated", $user); - ($title, $body, $extrahead) = $self -> generate_loggedin(); - } # If the user is not anonymous, they have logged in already. - } elsif(!$self -> {"session"} -> anonymous_session()) { + } elsif(!) { - # Is the user requesting a logout? If so, doo eet. - if(defined($self -> {"cgi"} -> param("logout")) || ($pathinfo[0] && $pathinfo[0] eq "logout")) { - $self -> log("logout", $self -> {"session"} -> get_session_userid()); - if($self -> {"session"} -> delete_session()) { - ($title, $body, $extrahead) = $self -> generate_loggedout(); - } else { - return $self -> generate_fatal($SessionHandler::errstr); - } - - # Already logged in, check password and either force a change or tell the user they logged in. - } else { my $user = $self -> {"session"} -> get_user_byid(); if($user) { @@ -1159,7 +1249,7 @@ sub page_display { ($title, $body, $extrahead) = $self -> generate_loggedin(); } else { $self -> {"session"} -> set_variable("passchange_reason", $passchange); - ($title, $body) = $self -> generate_passchange_form(); + ($title, $body, $extrahead, $extrajs) = $self -> generate_passchange_form(); } } else { $self -> {"logger"} -> die_log($self -> {"cgi"} -> remote_host(), "Logged in session with no user record. This Should Not Happen."); @@ -1167,7 +1257,7 @@ sub page_display { } # User is anonymous - do we have a login? - } elsif(defined($self -> {"cgi"} -> param("login"))) { + } elsif(defined($self -> {"cgi"} -> param("signin"))) { # Validate the other fields... my ($user, $args) = $self -> validate_login(); @@ -1175,7 +1265,7 @@ sub page_display { # Do we have any errors? If so, send back the login form with them if(!ref($user)) { $self -> log("login error", $user); - ($title, $body) = $self -> generate_login_form($user, $args); + ($title, $body, $extrahead, $extrajs) = $self -> generate_login_form($user, $args); # No errors, user is valid... } else { @@ -1202,87 +1292,49 @@ sub page_display { ($title, $body, $extrahead) = $self -> generate_loggedin(); } else { $self -> {"session"} -> set_variable("passchange_reason", $passchange); - ($title, $body) = $self -> generate_passchange_form(); + ($title, $body, $extrahead, $extrajs) = $self -> generate_passchange_form(); } } # Has a registration attempt been made? - } elsif(defined($self -> {"cgi"} -> param("register"))) { - - # Validate/perform the registration - my ($user, $args) = $self -> validate_register(); - - # Do we have any errors? If so, send back the login form with them - if(!ref($user)) { - $self -> log("registration error", $user); - ($title, $body) = $self -> generate_login_form($user, $args); - - # No errors, user is registered - } else { - # Do not create a new session - the user needs to confirm the account. - $self -> log("registered inactive", $user -> {"username"}); - ($title, $body) = $self -> generate_registered(); - } - - # Is the user attempting activation? - } elsif(defined($self -> {"cgi"} -> param("actcode"))) { - - my ($user, $args) = $self -> validate_actcode(); - if(!ref($user)) { - $self -> log("activation error", $user); - ($title, $body) = $self -> generate_actcode_form($user); - } else { - $self -> log("activation success", $user -> {"username"}); - ($title, $body) = $self -> generate_activated($user); - } - - # Password reset requested? - } elsif(defined($self -> {"cgi"} -> param("dorecover"))) { - - my ($user, $args) = $self -> validate_recover(); - if(!ref($user)) { - $self -> log("Reset error", $user); - ($title, $body) = $self -> generate_recover_form($user); - } else { - $self -> log("Reset success", $user -> {"username"}); - ($title, $body) = $self -> generate_recover($user); - } + } els } elsif(defined($self -> {"cgi"} -> param("resetcode"))) { my ($user, $args) = $self -> validate_reset(); - ($title, $body) = $self -> generate_reset(!ref($user) ? $user : undef); + ($title, $body, $extrahead, $extrajs) = $self -> generate_reset(!ref($user) ? $user : undef); # User wants a resend? - } elsif(defined($self -> {"cgi"} -> param("doresend"))) { - - my ($user, $args) = $self -> validate_resend(); - if(!ref($user)) { - $self -> log("Resend error", $user); - ($title, $body) = $self -> generate_resend_form($user); - } else { - $self -> log("Resend success", $user -> {"username"}); - ($title, $body) = $self -> generate_resent($user); - } + } els - } elsif(defined($self -> {"cgi"} -> param("activate")) || ($pathinfo[0] && $pathinfo[0] eq "activate")) { - ($title, $body) = $self -> generate_actcode_form(); - - } elsif(defined($self -> {"cgi"} -> param("recover")) || ($pathinfo[0] && $pathinfo[0] eq "recover")) { - ($title, $body) = $self -> generate_recover_form(); - - } elsif(defined($self -> {"cgi"} -> param("resend")) || ($pathinfo[0] && $pathinfo[0] eq "resend")) { - ($title, $body) = $self -> generate_resend_form(); # No session, no submission? Send back the login form... - } else { - ($title, $body) = $self -> generate_login_form(); } - # Done generating the page content, return the filled in page template - return $self -> {"template"} -> load_template("login/page.tem", {"***title***" => $title, - "***extrahead***" => $extrahead, - "***content***" => $body,}); +} + + +## @method $ page_display() +# Generate the page content for this module. +sub page_display { + my $self = shift; + + # Is this an API call, or a normal page operation? + my $apiop = $self -> is_api_operation(); + if(defined($apiop)) { + # API call - dispatch to appropriate handler. + given($apiop) { + when("check") { return $self -> api_response ($self -> _build_login_check_response()); } + when("loginform") { return $self -> api_html_response($self -> _build_loginform_response()); } + when("login") { return $self -> api_response ($self -> _build_login_response()); } + + default { + return $self -> api_response($self -> api_errorhash('bad_op', + $self -> {"template"} -> replace_langvar("API_BAD_OP"))) + } + } + } else { + return $self -> _dispatch_ui(); } } diff --git a/templates/default/api/docs.tem b/templates/default/api/docs.tem new file mode 100755 index 0000000..b4cf14b --- /dev/null +++ b/templates/default/api/docs.tem @@ -0,0 +1,102 @@ + + + + + User Data Tools API Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+
+ + diff --git a/templates/default/api/html_error.tem b/templates/default/api/html_error.tem new file mode 100755 index 0000000..62afcda --- /dev/null +++ b/templates/default/api/html_error.tem @@ -0,0 +1 @@ +
%(info)s
diff --git a/templates/default/api/html_wrapper.tem b/templates/default/api/html_wrapper.tem new file mode 100755 index 0000000..f861c44 --- /dev/null +++ b/templates/default/api/html_wrapper.tem @@ -0,0 +1,7 @@ + + + +API Response + +%(data)s + diff --git a/templates/default/css/foundation.mods.css b/templates/default/css/foundation.mods.css new file mode 100755 index 0000000..acff32b --- /dev/null +++ b/templates/default/css/foundation.mods.css @@ -0,0 +1,23 @@ +/* Remove margins from selected elements */ +.nomargin { + margin: 0 0; +} + +/* Label to the right of switches */ +.switch-label { + color: #0a0a0a; + font-weight: normal; + padding-left: 0.5rem; + vertical-align: 50%; +} + +/* Space out buttons in the title bar */ +div.top-bar-right ul.menu li { + padding-left: 0.25rem; +} + +/* Centre text in title part of bar */ +div.top-bar-title { + padding-top: 0.5rem; + font-weight: bold; +} \ No newline at end of file diff --git a/templates/default/css/login.css b/templates/default/css/login.css new file mode 100755 index 0000000..cd25a4a --- /dev/null +++ b/templates/default/css/login.css @@ -0,0 +1,4 @@ +@charset "utf-8"; +div.contextlink { + font-size: 12px; +} diff --git a/templates/default/error/error_box.tem b/templates/default/error/error_box.tem new file mode 100755 index 0000000..8d84027 --- /dev/null +++ b/templates/default/error/error_box.tem @@ -0,0 +1,6 @@ + + + + + +
error%(message)s
\ No newline at end of file diff --git a/templates/default/error/error_item.tem b/templates/default/error/error_item.tem new file mode 100755 index 0000000..020c35c --- /dev/null +++ b/templates/default/error/error_item.tem @@ -0,0 +1 @@ +
  • %(error)s
  • diff --git a/templates/default/error/error_list.tem b/templates/default/error/error_list.tem new file mode 100755 index 0000000..f3d14e0 --- /dev/null +++ b/templates/default/error/error_list.tem @@ -0,0 +1,2 @@ +
    %(message)s
    + diff --git a/templates/default/images/error.png b/templates/default/images/error.png new file mode 100755 index 0000000000000000000000000000000000000000..b11a7b6a4f1825e1e2a22a7719165872d4f7cf48 GIT binary patch literal 3259 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 U+#`I}b^rhX07*qoM6N<$f>uAi761SM literal 0 HcmV?d00001 diff --git a/templates/default/login/extrahead.tem b/templates/default/login/extrahead.tem new file mode 100755 index 0000000..30413b0 --- /dev/null +++ b/templates/default/login/extrahead.tem @@ -0,0 +1 @@ + diff --git a/templates/default/login/extrajs.tem b/templates/default/login/extrajs.tem new file mode 100755 index 0000000..bb3a9c4 --- /dev/null +++ b/templates/default/login/extrajs.tem @@ -0,0 +1,12 @@ + $(function() { + // Toggle the persist warning box, if it exists + if($('#persist').length) { + $('#persist').change(function() { + if($('#persist').is(':checked')) { + $('#persist-warn').fadeIn(); + } else { + $('#persist-warn').fadeOut(); + } + }); + } + }); diff --git a/templates/default/login/form.tem b/templates/default/login/form.tem new file mode 100755 index 0000000..55429ac --- /dev/null +++ b/templates/default/login/form.tem @@ -0,0 +1,34 @@ +
    +%(error)s + +
    +
    {L_LOGIN_INTRO}
    +
    +
    + +
    +
    + +
    +
    +%(persist)s + +
    +
    + +
    +
    +
    + + + + + + + + +
    \ No newline at end of file diff --git a/templates/default/login/persist_disabled.tem b/templates/default/login/persist_disabled.tem new file mode 100755 index 0000000..7f3680e --- /dev/null +++ b/templates/default/login/persist_disabled.tem @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/default/login/persist_enabled.tem b/templates/default/login/persist_enabled.tem new file mode 100755 index 0000000..021938e --- /dev/null +++ b/templates/default/login/persist_enabled.tem @@ -0,0 +1,4 @@ +
    + + Keep me logged in +
    diff --git a/templates/default/messagebox.tem b/templates/default/messagebox.tem new file mode 100755 index 0000000..9a7b7d3 --- /dev/null +++ b/templates/default/messagebox.tem @@ -0,0 +1,15 @@ +
    + +
    +

    %(title)s

    +
    +
    +
    %(summary)s
    +
    %(longdesc)s
    +
    +%(additional)s +%(buttons)s +
    +
    + +
    diff --git a/templates/default/messagebox_button.tem b/templates/default/messagebox_button.tem new file mode 100755 index 0000000..7410480 --- /dev/null +++ b/templates/default/messagebox_button.tem @@ -0,0 +1 @@ +