public async Task <UserRefToken> GetUserRefToken(IWebRequest req) { var authentication = req.GetAuthenticationHeaderValue(); UserRefToken userRefToken = await this.AuthenticateAsync(authentication?.Scheme, authentication?.Parameter) as UserRefToken; if (userRefToken == null) { throw new UnauthorizedException(); } return(userRefToken); }
/// <summary> /// Validates the auth token id returning an <see cref="AuthToken"/> instance /// </summary> /// <param name="authType"></param> /// <param name="authValue"></param> /// <returns>An <see cref="AuthToken"/> instance</returns> public async Task <AuthToken> AuthenticateAsync(string authType, string authValue) { List <string> fieldList = new List <string>(); if (!string.IsNullOrEmpty(this.authTokenIdFieldName)) { fieldList.Add($"at.{ this.authTokenIdFieldName}"); } if (!string.IsNullOrEmpty(this.authTokenTableUserIdFieldName)) { fieldList.Add($"at.{ this.authTokenTableUserIdFieldName}"); } if (!string.IsNullOrEmpty(this.userTableAccountIdFieldName)) { fieldList.Add($"u.{ this.userTableAccountIdFieldName}"); } if (!string.IsNullOrEmpty(this.userTableUsernameFieldName)) { fieldList.Add($"u.{ this.userTableUsernameFieldName}"); } if (!string.IsNullOrEmpty(this.userTableRoleFieldName)) { fieldList.Add($"u.{ this.userTableRoleFieldName}"); } if (!string.IsNullOrEmpty(this.authTokenTableExpiresAtFieldName)) { fieldList.Add($"at.{ this.authTokenTableExpiresAtFieldName}"); } Dict authTokenDict = await this.database.SelectRowAsync($"SELECT {string.Join(",", fieldList)} FROM {this.authTokenTableName} at INNER JOIN {this.userTableName} u ON at.user_id=u.id WHERE at.id=@authTokenId", new { authTokenId = authValue }); logger.Debug($"Authenticate():authTokenDict={authTokenDict}"); if (authTokenDict == null) { throw new UnauthorizedException(); } var authToken = UserRefToken.FromDict(authTokenDict, this.authTokenIdFieldName, this.authTokenTableUserIdFieldName, this.userTableUsernameFieldName, this.userTableRoleFieldName, this.userTableAccountIdFieldName, this.authTokenTableExpiresAtFieldName); logger.Debug($"Authenticate():authToken.expiresAt={authToken.expiresAt}"); if (authToken.expiresAt == DateTime.MinValue || authToken.expiresAt < DateTime.Now) { throw new UnauthorizedException(); } return(authToken); }
/// <summary> /// Registers a new user /// </summary> /// <param name="input"></param> /// <param name="notifyData"></param> /// <returns></returns> public async Task <UserRefToken> RegisterAsync(dynamic input, Dict notifyData = null) { Dict registration = this.ConvertInputToDict(input); // Handle registering an anonymous user string userId = registration.GetAs("user_id", (string)null); string accountId = null; logger.Trace($"RegisterAsync():userId={userId}"); if (!string.IsNullOrEmpty(userId)) { accountId = await this.database.SelectValueAsync <string>($"SELECT account_id FROM {this.userTableName}", userId); } if (string.IsNullOrEmpty(accountId)) { userId = null; } // Validate username string username = this.usernameFieldValidator.Validate(registration?.GetAs(this.userTableUsernameFieldName, (string)null)); logger.Trace($"RegisterAsync():username={username}"); Dict existingUserByUsername = await this.database.SelectRowAsync(this.userTableName, new Dict { { this.userTableUsernameFieldName, username } }); if (existingUserByUsername != null) { throw new Exception("Username '" + username + "' is unavailable"); } // Validate password string password = this.passwordFieldValidator.Validate(registration?.GetAs("password", (string)null)); // Validate email and phone string email = this.emailFieldValidator.Validate(registration?.GetAs(this.userTableEmailFieldName, (string)null)); string phone = this.phoneFieldValidator.Validate(registration?.GetAs(this.userTablePhoneFieldName, (string)null)); // Validate first and last name string firstName = this.nameFieldValidator.Validate(registration?.GetAs(this.userTableFirstNameFieldName, (string)null)); string lastName = this.nameFieldValidator.Validate(registration?.GetAs(this.userTableLastNameFieldName, (string)null)); string role = string.IsNullOrEmpty(this.userTableRoleFieldName) ? this.defaultRole : registration?.GetAs(this.userTableRoleFieldName, this.defaultRole); // Create salt and password hash string salt = Guid.NewGuid().ToString(); string passwordHash = $"{salt} {password}".Hash(); // Create account using (ITransaction transaction = await this.database.BeginTransactionAsync()) { if (string.IsNullOrEmpty(accountId)) { Dict extraAccountInfo = this.getExtraAccountInfo == null ? null : this.getExtraAccountInfo(registration); accountId = await transaction.InsertAsync <string>(this.accountTableName, extraAccountInfo); if (this.onRegisterAccount != null) { Dict registerAccount = new Dict(extraAccountInfo) { ["id"] = accountId }; transaction.OnCommit(async() => { try { await this.onRegisterAccount(registerAccount); } catch (Exception e) { logger.Debug(e); } }); } } // Create user record Dict user = new Dict { { this.userTableAccountIdFieldName, accountId }, { this.userTableUsernameFieldName, username }, { this.userTableSaltFieldName, salt }, { this.userTablePasswordHashFieldName, passwordHash }, { this.userTableEmailFieldName, email }, { this.userTablePhoneFieldName, phone }, { this.userTableFirstNameFieldName, firstName }, { this.userTableLastNameFieldName, lastName }, }; if (!string.IsNullOrEmpty(this.userTableRoleFieldName) && !string.IsNullOrEmpty(this.defaultRole)) { user[this.userTableRoleFieldName] = role; } Dict extraUserInfo = this.getExtraUserInfo == null ? null : this.getExtraUserInfo(registration); if (extraUserInfo != null) { user.UpdateFrom(extraUserInfo); } if (string.IsNullOrEmpty(userId)) { userId = await transaction.InsertAsync <string>(this.userTableName, user); } else { user[this.userTableIdFieldName] = userId; await transaction.UpdateAsync(this.userTableName, user); } if (this.onRegisterUser != null) { transaction.OnCommit(async() => { var registerUser = new Dict { { this.userTableAccountIdFieldName, accountId }, { this.userTableUsernameFieldName, username }, { this.userTableEmailFieldName, email }, { this.userTablePhoneFieldName, phone }, { this.userTableFirstNameFieldName, firstName }, { this.userTableLastNameFieldName, lastName }, }; try { if (notifyData != null) { registerUser.UpdateFrom(notifyData); } await this.onRegisterUser(registerUser); } catch (Exception e) { logger.Debug(e); } }); } UserRefToken userRefToken = await this.CreateUserRefTokenAsync(transaction, userId, username, role, accountId); await transaction.CommitAsync(); return(userRefToken); } }