| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | |
|---|
| 15 | |
|---|
| 16 | |
|---|
| 17 | |
|---|
| 18 | |
|---|
| 19 | |
|---|
| 20 | #include "authn.hh" |
|---|
| 21 | #include "error_resource.hh" |
|---|
| 22 | #include "redir_resource.hh" |
|---|
| 23 | #include "request.hh" |
|---|
| 24 | #include "resource.hh" |
|---|
| 25 | #include "session.hh" |
|---|
| 26 | |
|---|
| 27 | #include "../db/db.hh" |
|---|
| 28 | #include "../html/util.hh" |
|---|
| 29 | #include "../server.hh" |
|---|
| 30 | #include "../tlate/tlate.hh" |
|---|
| 31 | #include "../tlate/string_value.hh" |
|---|
| 32 | #include "../tlate/structured_value.hh" |
|---|
| 33 | #include "../tlate/user_value.hh" |
|---|
| 34 | #include "../util.hh" |
|---|
| 35 | |
|---|
| 36 | #include <boost/shared_ptr.hpp> |
|---|
| 37 | |
|---|
| 38 | namespace |
|---|
| 39 | { |
|---|
| 40 | class authn_value : public tlate::structured_value |
|---|
| 41 | { |
|---|
| 42 | db::user::const_ptr u; |
|---|
| 43 | std::string msg; |
|---|
| 44 | std::string ruri; |
|---|
| 45 | public: |
|---|
| 46 | authn_value(db::user::const_ptr u, |
|---|
| 47 | std::string msg, |
|---|
| 48 | std::string ruri) |
|---|
| 49 | : u(u) |
|---|
| 50 | , msg(msg) |
|---|
| 51 | , ruri(ruri) |
|---|
| 52 | {} |
|---|
| 53 | |
|---|
| 54 | value::const_ptr get(std::string) const; |
|---|
| 55 | }; |
|---|
| 56 | |
|---|
| 57 | tlate::value::const_ptr authn_value::get(std::string var) const |
|---|
| 58 | { |
|---|
| 59 | using tlate::value; |
|---|
| 60 | using tlate::user_value; |
|---|
| 61 | using tlate::string_value; |
|---|
| 62 | tlate::value::ptr rv; |
|---|
| 63 | if (var == "user" && u) |
|---|
| 64 | rv.reset(new user_value(u)); |
|---|
| 65 | else if (var == "message" && !msg.empty()) |
|---|
| 66 | rv.reset(new string_value(html::quote(msg, false))); |
|---|
| 67 | else if (var == "request-uri") |
|---|
| 68 | rv.reset(new string_value(html::quote(ruri, false))); |
|---|
| 69 | else if (var == "logout-action") |
|---|
| 70 | rv.reset(new string_value("/logout")); |
|---|
| 71 | else if (var == "logout-method") |
|---|
| 72 | rv.reset(new string_value("post")); |
|---|
| 73 | else if (var == "login-action") |
|---|
| 74 | rv.reset(new string_value("/login")); |
|---|
| 75 | else if (var == "login-method") |
|---|
| 76 | rv.reset(new string_value("post")); |
|---|
| 77 | else if (var == "enctype") |
|---|
| 78 | rv.reset(new string_value |
|---|
| 79 | ("application/x-www-form-urlencoded")); |
|---|
| 80 | else if (var == "accept-charlist") |
|---|
| 81 | rv.reset(new string_value("utf8")); |
|---|
| 82 | else if (var == "recovery") |
|---|
| 83 | rv.reset(new string_value("/recovery")); |
|---|
| 84 | else if (var == "register") |
|---|
| 85 | rv.reset(new string_value("/register")); |
|---|
| 86 | return rv; |
|---|
| 87 | } |
|---|
| 88 | } |
|---|
| 89 | |
|---|
| 90 | namespace http |
|---|
| 91 | { |
|---|
| 92 | tlate::value::const_ptr |
|---|
| 93 | authn::tlate_value(boost::shared_ptr<request> req) |
|---|
| 94 | { |
|---|
| 95 | std::string ruri = req->get_path(); |
|---|
| 96 | std::string query = req->get_form_as_query(); |
|---|
| 97 | if (!query.empty()) ruri += "?" + query; |
|---|
| 98 | tlate::value::ptr rv(new authn_value(req->get_user(), |
|---|
| 99 | req->get_form_field |
|---|
| 100 | ("user.authn.message"), |
|---|
| 101 | ruri)); |
|---|
| 102 | return rv; |
|---|
| 103 | } |
|---|
| 104 | |
|---|
| 105 | boost::shared_ptr<response> authn::operator() |
|---|
| 106 | (boost::shared_ptr<request> req, response::factory rf) |
|---|
| 107 | { |
|---|
| 108 | ::uri redir = req->get_form_field("redirect"); |
|---|
| 109 | |
|---|
| 110 | std::string msg_name = "user.authn.message"; |
|---|
| 111 | |
|---|
| 112 | if (req->get_path() == "/login" && req->has_form_field("login")) |
|---|
| 113 | { |
|---|
| 114 | std::string user = req->get_form_field("userid"); |
|---|
| 115 | std::string pass = req->get_form_field("passwd"); |
|---|
| 116 | boost::shared_ptr<session> sess(new session()); |
|---|
| 117 | sess->authenticate(cb.dbase().lookup_user(user), pass); |
|---|
| 118 | if (!sess->is_authenticated()) |
|---|
| 119 | redir.replace_query_param |
|---|
| 120 | (msg_name, |
|---|
| 121 | "User name or password incorrect."); |
|---|
| 122 | else |
|---|
| 123 | redir.remove_query_param(msg_name); |
|---|
| 124 | boost::shared_ptr<resource> rr |
|---|
| 125 | (new redir_resource(cb, |
|---|
| 126 | redir.to_string(), |
|---|
| 127 | "303 See other")); |
|---|
| 128 | boost::shared_ptr<response> resp = (*rr)(req, rf); |
|---|
| 129 | if (sess->is_authenticated()) |
|---|
| 130 | resp->set_session(req, sess); |
|---|
| 131 | return resp; |
|---|
| 132 | } |
|---|
| 133 | if (req->get_path() == "/logout") |
|---|
| 134 | { |
|---|
| 135 | req->get_session().reset(); |
|---|
| 136 | boost::shared_ptr<resource> rr |
|---|
| 137 | (new redir_resource(cb, redir.to_string(), |
|---|
| 138 | "303 See other")); |
|---|
| 139 | return (*rr)(req, rf); |
|---|
| 140 | } |
|---|
| 141 | else |
|---|
| 142 | { |
|---|
| 143 | boost::shared_ptr<resource> er |
|---|
| 144 | (new error_resource(cb, "404 Not found")); |
|---|
| 145 | return (*er)(req, rf); |
|---|
| 146 | } |
|---|
| 147 | } |
|---|
| 148 | |
|---|
| 149 | }; |
|---|
| 150 | |
|---|
| 151 | namespace |
|---|
| 152 | { |
|---|
| 153 | class factory : public server::http_resource_factory |
|---|
| 154 | { |
|---|
| 155 | public: |
|---|
| 156 | factory() { |
|---|
| 157 | server::register_http_resource("/login", this); |
|---|
| 158 | server::register_http_resource("/logout", this); |
|---|
| 159 | } |
|---|
| 160 | boost::shared_ptr<http::resource> operator() |
|---|
| 161 | (server::conn_cb cb, std::string) { |
|---|
| 162 | boost::shared_ptr<http::resource> rv |
|---|
| 163 | (new http::authn(cb)); |
|---|
| 164 | return rv; |
|---|
| 165 | } |
|---|
| 166 | }; |
|---|
| 167 | factory f; |
|---|
| 168 | } |
|---|