Mission Impossible / How to create datatypes which cannot contain invalid state

adrianimboden
4,729 views

Open Source Your Knowledge, Become a Contributor

Technology knowledge has to be shared and made accessible for free. Join the movement.

Create Content

In this program, the class AuthenticationProcedure implements the logic for the following passwordless login procedure:

  1. The user goes to the login form
  2. The user enters his email address
  3. The user gets an email with a randomly generated token
  4. The user enters the received token on the login form
  5. The user is logged in

Refactor the example with your newly aqcuired knowledge.

Authentication Procedure
// { autofold
#include <boost/assert.hpp>
#include <iostream>
#include <set>
#include <string>
// given
bool send_mail(std::string recipient, std::string token) {
return true;
}
// end given
struct AuthConfig {
std::set<std::string> users;
std::set<std::string> admins;
};
class AuthenticationProcedure {
public:
enum class LoginResult { success, failure };
enum class RequestTokenResult { mail_sent, mail_send_error, not_authorized };
explicit AuthenticationProcedure(AuthConfig config)
: config_{config} {
}
RequestTokenResult request_token(const std::string& email) {
if ((std::find(config_.admins.begin(), config_.admins.end(), email) == config_.admins.end())
and (std::find(config_.users.begin(), config_.users.end(), email) == config_.users.end())) {
return RequestTokenResult::not_authorized;
}
const auto token = "random-token";
const auto send_successful = send_mail(email, token);
if (not send_successful) {
return RequestTokenResult::mail_send_error;
}
token_ = token;
email_ = email;
return RequestTokenResult::mail_sent;
}
LoginResult verify_token(const std::string& token) {
if (token_.empty()) {
return LoginResult::failure;
}
if (token_ != token) {
return LoginResult::failure;
}
is_logged_in_ = true;
if (std::find(config_.admins.begin(), config_.admins.end(), email_) != config_.admins.end()) {
is_admin_ = true;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Open Source Your Knowledge: become a Contributor and help others learn. Create New Content