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.Extensions; using xIdentityModels.Models; using static IdentityServer4.IdentityServerConstants; using static xIdentityHelper.XApiScopeHelper; using Microsoft.Extensions.Logging; namespace xIds.Controllers { public partial class AccountController { // #region Authentication Actions ... /// /// Retrieve OAuth Discovery Document /// /// an instance of DiscoveryDocumentResponse [AllowAnonymous] [RequireXPowered] [HttpGet("DiscoveryDocument")] public async Task> GetDiscoveryDocument() { // // Do Action ... try { // var result = await IdentityManager .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 IdentityManager .RequestScopeAccessToken(scopeName); // // Ceck Response Result ... if (result.IsError) { XException.InvalidConfiguration.Throw(); } // return Ok(result .CreateXTokenResponse() .ToDynamicObject()); } catch (Exception ex) { // var result = GetExceptionActionResult(ex); return result; } } /// /// Authenticate User /// /// /// Sample request: /// /// { /// "password": "", /// "userSelectBy": "", /// } /// /// /// an instance of XLoginRequest class which represent Authentication requirements /// an instance of XTokenResponse [AllowAnonymous] [RequireXPowered] [HttpPost("Authenticate")] public async Task> Authenticate( [FromBody] XLoginRequest model ) { // // Do Action ... try { // // Validate Args ... if (!ModelState.IsValid) { XException.InvalidArgs.Throw(); } await ValidationProvider .GroupValidationBuilder() .AddNotNull(model) .AddNotEmpty( model.UserSelectBy, model.Password ) .ValidateGroupAsync(); // var result = await IdentityManager .Authenticate(model); // // Check Result ... if (result.IsError) { throw result.GetException(); } // // Return Result ... return Ok(result .CreateXTokenResponse() .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" /// } /// } /// /// /// an instance of XLoginRequest class which represent Authentication requirements /// an instance of XLoginResponse [AllowAnonymous] [RequireXPowered] [HttpPost("Login")] public async Task> Login( [FromBody] XLoginRequest model ) { // // Do Action ... 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 IdentityManager .Login(model); // return Ok(result .ToDynamicObject()); } 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() { // // Do Action ... try { // // Retrieve Toke Response ... var model = await RetrieveTokensAsXTokenResponse(); // // Validate Args ... ValidationProvider .GroupValidationBuilder() .AddNotNull(model) .AddNotEmpty( model.AccessToken, model.RefreshToken) .ValidateGroup(); // var result = await IdentityManager .RefreshTokens(model); // return Ok(result .ToDynamicObject()); } 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)] [Authorize(Policy = LocalApi.PolicyName)] 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 ... await IdentityManager .ChangePassword( model.Lang, model.Device, userSelectByParam, model.Password, model.NewPassword, model.ReturnUrl ); // return Ok(); } catch (Exception ex) { // var exResult = GetExceptionActionResult(ex); return exResult; } } #endregion } }