using System; using System.Threading.Tasks; using IdentityModel.Client; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using xIdentityHelper; using xCommons.Attributes; using xCommons.Extensions; using xExceptions.Constants; using xIdentityModels.Models; using xModels.Dtos; using static xIdentityHelper.XApiScopeHelper; namespace xApi.Controllers { public partial class AccountController { // #region Authentication Actions ... /// /// Retrieve OAuth Discovery Document /// /// an instance of DiscoveryDocumentResponse [AllowAnonymous] [RequireXPowered] [HttpGet ("DiscoveryDocument")] public async Task> GetDiscoveryDocument () { // try { // var result = await identityProvider .RequestDiscoveryDocument (); // // Ceck Response Result ... if (result.IsError) { XException.InvalidConfiguration.Throw (); } // return Ok (result .ToDynamicObject ()); } catch (Exception ex) { // var result = GetExceptionActionResult (ex); return result; } } /// /// Request AccessToken for Specific XApiScope /// /// a member of XApiScope /// an instance of XTokenResponse [AllowAnonymous] [RequireXPowered] [HttpPost ("RequestScopeAccessToken")] public async Task> RequestScopeAccessToken ( [FromHeader] XApiScope scope ) { // // Do Action ... try { // // Validate Args ... var scopeName = string.Empty; try { scopeName = scope.GetStringValue (); } catch { } ValidationProvider.NotEmpty (scopeName); // var result = await identityProvider .RequestScopeAccessToken (scopeName); // return Ok (result .ToDynamicObject ()); } catch (Exception ex) { // var result = GetExceptionActionResult (ex); return result; } } /// /// Authenticate User /// /// /// Sample request: /// /// { /// "password": "", /// "userSelectBy": "", /// } /// /// /// User Login Required Info, an instance of XLoginRequest /// an instance of XTokenResponse [AllowAnonymous] [RequireXPowered] [HttpPost ("Authenticate")] public async Task> Authenticate ( [FromBody] XLoginRequest model ) { try { // // Validate Args ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw (); } await ValidationProvider .GroupValidationBuilder () .AddNotNull (model) .AddNotEmpty ( model.UserSelectBy, model.Password ) .ValidateGroupAsync (); // var result = await identityProvider .Authenticate (model); // return Ok (result .ToDynamicObject ()); } catch (Exception ex) { // var result = GetExceptionActionResult (ex); return result; } } /// /// Authenticate User /// /// /// Sample request: /// /// { /// "language": "fa-IR" /// "password": "", /// "userSelectBy": "", /// "device": { /// "os":"Mac", /// "browser":"Chrome", /// "osVersion":"mac-os-x-15", /// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36", /// "deviceType":3, /// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]", /// "token":"96f400dd9aa5c57a8cec9d6f4775bad3" /// } /// } /// /// /// User Login Required Info, an instance of XLoginRequest /// an instance of XLoginResponse [AllowAnonymous] [RequireXPowered] [HttpPost ("Login")] public async Task> Login ( [FromBody] XLoginRequest model ) { try { // // Validate Args ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw (); } await ValidationProvider .GroupValidationBuilder () .AddNotNull ( model, model.Device) .AddNotEmpty ( model.Language, model.UserSelectBy, model.Password ) .ValidateGroupAsync (); // var result = await identityProvider .Login (model); // return Ok (result .ToDynamicObject ()); } catch (Exception ex) { // var result = GetExceptionActionResult (ex); return result; } } /// /// Logout User /// [RequireXPowered] [HttpPost ("Logout")] [Authorize (Policy = XPolicies.User)] public async Task Logout () { try { // var tokens = await RetrieveTokensAsXTokenResponse (); await identityProvider .Logout (tokens); // return Ok (); } catch (Exception ex) { // var result = GetExceptionActionResult (ex); return result; } } /// /// Refresh Expired Tokens /// /// /// in addition to AccessToken, you had to pass RefreshToken due to Headers /// /// an instance of XTokenResponse [AllowAnonymous] [RequireXPowered] [HttpPost ("RefreshTokens")] public async Task> RefreshTokens () { // try { // // Retrieve Toke Response ... var model = await RetrieveTokensAsXTokenResponse (); // // Validate Args ... ValidationProvider .GroupValidationBuilder () .AddNotNull (model) .AddNotEmpty ( model.AccessToken, model.RefreshToken) .ValidateGroup (); // var result = await identityProvider .RefreshTokens (model); // return Ok (result .ToDynamicObject ()); } catch (Exception ex) { // var result = GetExceptionActionResult (ex); return result; } } /// /// Validate a Revision Checksum /// /// /// [HttpPost ("Validate")] [Authorize (Policy = XPolicies.EnabledUser)] public async Task> Validate ( [FromBody] XValidateRevisionRequest model ) { // // Do Action ... try { // // Validate Args ... await ValidationProvider .GroupValidationBuilder () .AddNotNull (model) .AddNotEmpty (model.Revision) .ValidateGroupAsync (); // // Get Request ... var tokens = await RetrieveTokensAsXTokenResponse (); var result = tokens.ValidateRevisionChecksum ( model.Revision, identityProvider.RevisionSecretKey ); // // Return Result return Ok (result); } catch (Exception ex) { // var result = GetExceptionActionResult (ex); return result; } } #endregion // #region Password Actions ... /// /// Change a User's Password ... /// /// /// for this action you have to provide: /// - Lang: client device currently used locale, such as: en-US. /// - Password: user's current active password. /// - NewPassword: user's new password to change. /// - Device: user's client device which is an instance of XDevice. /// - ReturnUrl: client application Login URL. /// /// Sample request: /// /// { /// "lang": "fa-IR", /// "password": "" /// "newPassword": "", /// "returnUrl": "http://localhost/login", /// "device": { /// "os":"Mac", /// "browser":"Chrome", /// "osVersion":"mac-os-x-15", /// "userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36", /// "deviceType":3, /// "identifier":"[Mac]-[mac-os-x-15]-[3]-[Chrome]-[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) x-framework-test/0.0.0 Chrome/87.0.4280.141 Electron/11.2.0 Safari/537.36]", /// "token":"96f400dd9aa5c57a8cec9d6f4775bad3" /// } /// } /// /// /// an instance of XActionRequest class which provider requirement for action /// [RequireXPowered] [HttpPost ("ChangePassword")] [Authorize (Policy = XPolicies.User)] [Authorize (Policy = XPolicies.EnabledUser)] public async Task ChangePassword ( [FromBody] XActionRequest model ) { // // Do Action ... try { // // Validate Args ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw (); } await ValidationProvider .GroupValidationBuilder () .AddNotNull ( model, model.Device ) .AddNotEmpty ( model.Lang, model.Password, model.NewPassword, model.ReturnUrl ) .ValidateGroupAsync (); // // Get User Select By ... var userSelectByParam = GetUserSelectByParam ( model, forceNotNull : false ); if (userSelectByParam.IsNullOrEmpty ()) { userSelectByParam = User.Identity.Name; } ValidationProvider.NotEmpty (userSelectByParam); // // Get Request ... var tokens = await RetrieveTokensAsXTokenResponse (); await identityProvider .ChangePassword (tokens, model); // return Ok (); } catch (Exception ex) { // var exResult = GetExceptionActionResult (ex); return exResult; } } #endregion } }