1 // This may look like C code, but it's really -*- C++ -*- 2 /* 3 * Copyright (C) 2011 Emweb bv, Herent, Belgium. 4 * 5 * See the LICENSE file for terms of use. 6 */ 7 #ifndef WT_AUTH_REGISTRATION_MODEL_H_ 8 #define WT_AUTH_REGISTRATION_MODEL_H_ 9 10 #include <Wt/Auth/Identity.h> 11 #include <Wt/Auth/FormBaseModel.h> 12 #include <Wt/Auth/User.h> 13 14 namespace Wt { 15 namespace Auth { 16 17 /*! \brief Enumeration for an email policy 18 */ 19 enum class EmailPolicy { 20 Disabled, //!< The email address is not asked for 21 Optional, //!< A user may optionally provide an email address 22 Mandatory //!< A user must provide an email address 23 }; 24 25 /*! \brief Method for confirming to be an existing user. 26 */ 27 enum class IdentityConfirmationMethod { 28 ConfirmWithPassword, //!< Confirm using a password prompt 29 ConfirmWithEmail, //!< Confirm by using an email procedure 30 ConfirmationNotPossible //!< Confirmation is not possible 31 }; 32 33 class Login; 34 35 /*! \class RegistrationModel Wt/Auth/RegistrationModel.h 36 * \brief Model for implementing a registration view. 37 * 38 * This model implements the logic for the registration of a new user. 39 * It can deal with traditional username/password registration, or 40 * registration of pre-identified users using federated login. 41 * 42 * The model exposes four fields: 43 * - LoginNameField: the login name (used as an identity for the 44 * Identity::LoginName provider) -- this can be an email if the 45 * AuthService is configured to use email addresses as identity 46 * - ChoosePasswordField: the password 47 * - RepeatPasswordField: the password (repeated) 48 * - EmailField: if an email address is to be asked (and is not used 49 * as identity). 50 * 51 * The largest complexity is in the handling of third party identity 52 * providers, which is initiated with a call to registerIdentified(). 53 * 54 * When a user is re-identified with the same identity, then the model 55 * may require that the (original) user confirms this new 56 * identity. The model indicates that this button should be made 57 * visible with isConfirmUserButtonVisible(), the action to take is 58 * determined by confirmIsExistingUser(), and existingUserConfirmed() 59 * ends this process by merging the new identity into the existing 60 * user. 61 * 62 * \sa RegistrationWidget 63 * 64 * \ingroup auth 65 */ 66 class WT_API RegistrationModel : public FormBaseModel 67 { 68 public: 69 //! \brief Choose Password field 70 static const Field ChoosePasswordField; 71 72 //! \brief Repeat password field 73 static const Field RepeatPasswordField; 74 75 //! \brief Email field (if login name is not email) 76 static const Field EmailField; 77 78 /*! \brief Constructor. 79 * 80 * Creates a new registration model, using a basic authentication 81 * service and user database. 82 * 83 * The \p login object is used to indicate that an existing user was 84 * re-identified, and thus the registration process may be aborted. 85 */ 86 RegistrationModel(const AuthService& baseAuth, AbstractUserDatabase& users, 87 Login& login); 88 89 /*! \brief Resets the model. 90 * 91 * This resets the model to initial values, clearing any entered information 92 * (login name, password, pre-identified identity). 93 */ 94 virtual void reset() override; 95 96 /*! \brief Returns the login object. 97 */ login()98 Login& login() { return login_; } 99 100 /*! \brief Configures a minimum length for a login name. 101 * 102 * The default value is 4. 103 */ setMinLoginNameLength(int chars)104 void setMinLoginNameLength(int chars) { minLoginNameLength_ = chars; } 105 106 /*! \brief Returns the minimum length for a login name. 107 * 108 * \sa setMinLoginNameLength() 109 */ minLoginNameLength()110 int minLoginNameLength() const { return minLoginNameLength_; } 111 112 /*! \brief Configures whether an email address needs to be entered. 113 * 114 * You may specify whether you want the user to enter an email 115 * address. 116 * 117 * This has no effect when the IdentityPolicy is 118 * IdentityPolicy::EmailAddress. 119 * 120 * The default policy is: 121 * - EmailOptional when email address verification is enabled 122 * - EmailDisabled otherwise 123 */ 124 void setEmailPolicy(EmailPolicy policy); 125 126 /*! \brief Returns the email policy. 127 * 128 * \sa setEmailPolicy() 129 */ emailPolicy()130 EmailPolicy emailPolicy() const { return emailPolicy_; } 131 132 /*! \brief Register a user authenticated by an identity provider. 133 * 134 * Using a 3rd party authentication service such as %OAuth, a user 135 * may be identified which is not yet registered with the web 136 * application. 137 * 138 * Then, you may still need to allow the user to complete 139 * registration, but because the user already is identified and 140 * authenticated, this simplifies the registration form, since 141 * fields related to authentication can be dropped. 142 * 143 * Returns \c true if the given identity was already registered, and 144 * has been logged in. 145 */ 146 virtual bool registerIdentified(const Identity& identity); 147 148 /*! \brief Returns the existing user that needs to be confirmed. 149 * 150 * When a user wishes to register with an identity that corresponds 151 * to an existing user, he may be allowd to confirm that he is in 152 * fact this existing user. 153 * 154 * \sa confirmIsExistingUser() 155 */ existingUser()156 User existingUser() const { return existingUser_; } 157 158 /*! \brief Returns the method to be used to confirm to be an existing user. 159 * 160 * When the ConfirmExisting field is visible, this returns an 161 * appropriate method to use to let the user confirm that he is 162 * indeed the identified existing user. 163 * 164 * The outcome of this method (if it is an online method, like a 165 * password prompt), if successful, should be indicated using 166 * existingUserConfirmed(). 167 * 168 * \sa existingUserConfirmed() 169 */ 170 virtual IdentityConfirmationMethod confirmIsExistingUser() const; 171 172 /*! \brief Confirms that the user is indeed an existing user. 173 * 174 * The new identity is added to this existing user (if applicable), 175 * and the user is logged in. 176 */ 177 virtual void existingUserConfirmed(); 178 179 /*! \brief Validates the login name. 180 * 181 * This verifies that the login name is adequate (see also 182 * setMinLoginNameLength()). 183 */ 184 virtual WString validateLoginName(const WT_USTRING& userName) const; 185 186 /*! \brief Verifies that a user with that name does not yet exist. 187 * 188 * If a user with that name already exists, it may in fact be the 189 * same user that is trying to register again (perhaps using a 190 * different identification method). If possible, we allow the user 191 * to confirm his identity. 192 */ 193 virtual void checkUserExists(const WT_USTRING& userName); 194 195 /*! \brief Performs the registration process. 196 */ 197 virtual User doRegister(); 198 199 virtual bool isVisible(Field field) const override; 200 virtual bool isReadOnly(Field field) const override; 201 virtual bool validateField(Field field) override; 202 203 /*! \brief Returns whether an existing user needs to be confirmed. 204 * 205 * This returns whether the user is being identified as an existing 206 * user and he can confirm that he is in fact the same user. 207 */ 208 virtual bool isConfirmUserButtonVisible() const; 209 210 /*! \brief Returns whether federated login options can be shown. 211 * 212 * This returns whether fields for federated login (such as OAuth) 213 * should be shown. These are typically buttons corresponding to 214 * identity providers. 215 * 216 * The result of a federated authentication procedure should be 217 * indicated to registerIdentified(). 218 */ 219 virtual bool isFederatedLoginVisible() const; 220 221 static void validatePasswordsMatchJS(WLineEdit *password, 222 WLineEdit *password2, 223 WText *info2); 224 225 private: 226 Login& login_; 227 int minLoginNameLength_; 228 EmailPolicy emailPolicy_; 229 230 Identity idpIdentity_; 231 User existingUser_; 232 }; 233 234 } 235 } 236 237 #endif // WT_AUTH_REGISTRATION_MODEL_H_ 238