Ed Tanous | f927347 | 2017-02-28 16:05:13 -0800 | [diff] [blame] | 1 | #include <unordered_map> |
| 2 | |
| 3 | #include <boost/algorithm/string/predicate.hpp> |
| 4 | |
| 5 | #include <token_authorization_middleware.hpp> |
| 6 | |
Ed Tanous | c4771fb | 2017-03-13 13:39:49 -0700 | [diff] [blame^] | 7 | #include <base64.hpp> |
Ed Tanous | f927347 | 2017-02-28 16:05:13 -0800 | [diff] [blame] | 8 | |
Ed Tanous | c4771fb | 2017-03-13 13:39:49 -0700 | [diff] [blame^] | 9 | namespace crow { |
| 10 | |
| 11 | using random_bytes_engine = std::independent_bits_engine<std::default_random_engine, CHAR_BIT, unsigned char>; |
| 12 | |
Ed Tanous | f927347 | 2017-02-28 16:05:13 -0800 | [diff] [blame] | 13 | |
Ed Tanous | 9992332 | 2017-03-03 14:21:24 -0800 | [diff] [blame] | 14 | void TokenAuthorizationMiddleware::before_handle(crow::request& req, response& res, context& ctx) { |
Ed Tanous | 9b65f1f | 2017-03-07 15:17:13 -0800 | [diff] [blame] | 15 | |
Ed Tanous | 9992332 | 2017-03-03 14:21:24 -0800 | [diff] [blame] | 16 | auto return_unauthorized = [&req, &res]() { |
| 17 | res.code = 401; |
| 18 | res.end(); |
| 19 | }; |
Ed Tanous | 9b65f1f | 2017-03-07 15:17:13 -0800 | [diff] [blame] | 20 | if (req.url == "/" || boost::starts_with(req.url, "/static/")){ |
| 21 | //TODO this is total hackery to allow the login page to work before the user |
Ed Tanous | c4771fb | 2017-03-13 13:39:49 -0700 | [diff] [blame^] | 22 | // is authenticated. Also, it will be quite slow for all pages instead of |
| 23 | // a one time hit for the whitelist entries. |
Ed Tanous | 9b65f1f | 2017-03-07 15:17:13 -0800 | [diff] [blame] | 24 | // Ideally, this should be done in the url router handler, with tagged routes |
| 25 | // for the whitelist entries. |
| 26 | return; |
| 27 | } |
| 28 | |
Ed Tanous | c4771fb | 2017-03-13 13:39:49 -0700 | [diff] [blame^] | 29 | |
Ed Tanous | 9992332 | 2017-03-03 14:21:24 -0800 | [diff] [blame] | 30 | if (req.url == "/login") { |
Ed Tanous | c4771fb | 2017-03-13 13:39:49 -0700 | [diff] [blame^] | 31 | if (req.method != HTTPMethod::POST){ |
| 32 | return_unauthorized(); |
| 33 | return; |
| 34 | } else { |
| 35 | auto login_credentials = crow::json::load(req.body); |
| 36 | if (!login_credentials){ |
| 37 | return_unauthorized(); |
| 38 | return; |
| 39 | } |
| 40 | auto username = login_credentials["username"].s(); |
| 41 | auto password = login_credentials["password"].s(); |
Ed Tanous | 38bdb98 | 2017-03-03 14:19:33 -0800 | [diff] [blame] | 42 | |
Ed Tanous | c4771fb | 2017-03-13 13:39:49 -0700 | [diff] [blame^] | 43 | if (username == "dude" && password == "dude"){ |
| 44 | std::random_device rand; |
| 45 | random_bytes_engine rbe; |
| 46 | std::string token('a', 20); |
| 47 | std::generate(begin(token), end(token), std::ref(rbe)); |
| 48 | std::string encoded_token; |
| 49 | base64::base64_encode(token, encoded_token); |
| 50 | ctx.auth_token = encoded_token; |
| 51 | this->auth_token2 = encoded_token; |
| 52 | |
| 53 | } else { |
| 54 | return_unauthorized(); |
| 55 | return; |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | } else if (req.url == "/logout") { |
| 60 | this->auth_token2 = ""; |
| 61 | } else { // Normal, non login, non static file request |
| 62 | // Check to make sure we're logged in |
| 63 | if (this->auth_token2.empty()){ |
| 64 | return_unauthorized(); |
| 65 | return; |
| 66 | } |
| 67 | // Check for an authorization header, reject if not present |
| 68 | if (req.headers.count("Authorization") != 1) { |
| 69 | return_unauthorized(); |
| 70 | return; |
| 71 | } |
| 72 | |
| 73 | std::string auth_header = req.get_header_value("Authorization"); |
| 74 | // If the user is attempting any kind of auth other than token, reject |
| 75 | if (!boost::starts_with(auth_header, "Token ")) { |
| 76 | return_unauthorized(); |
| 77 | return; |
| 78 | } |
| 79 | |
| 80 | //todo, use span here instead of constructing a new string |
| 81 | if (auth_header.substr(6) != this->auth_token2){ |
| 82 | return_unauthorized(); |
| 83 | return; |
| 84 | } |
Ed Tanous | 9992332 | 2017-03-03 14:21:24 -0800 | [diff] [blame] | 85 | } |
| 86 | } |
Ed Tanous | f927347 | 2017-02-28 16:05:13 -0800 | [diff] [blame] | 87 | |
Ed Tanous | 9992332 | 2017-03-03 14:21:24 -0800 | [diff] [blame] | 88 | void TokenAuthorizationMiddleware::after_handle(request& /*req*/, response& res, context& ctx) { |
Ed Tanous | c4771fb | 2017-03-13 13:39:49 -0700 | [diff] [blame^] | 89 | |
Ed Tanous | 9992332 | 2017-03-03 14:21:24 -0800 | [diff] [blame] | 90 | } |
Ed Tanous | c4771fb | 2017-03-13 13:39:49 -0700 | [diff] [blame^] | 91 | } |