Initial ...
This commit is contained in:
@@ -0,0 +1,392 @@
|
||||
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 ...
|
||||
/// <summary>
|
||||
/// Retrieve OAuth Discovery Document
|
||||
/// </summary>
|
||||
/// <returns>an instance of <see>DiscoveryDocumentResponse</see></returns>
|
||||
[AllowAnonymous]
|
||||
[RequireXPowered]
|
||||
[HttpGet("DiscoveryDocument")]
|
||||
public async Task<ActionResult<DiscoveryDocumentResponse>> 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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request AccessToken for Specific XApiScope
|
||||
/// </summary>
|
||||
/// <param name="scope">a member of <see>XApiScope</see></param>
|
||||
/// <returns>an instance of <see>XTokenResponse</see></returns>
|
||||
[AllowAnonymous]
|
||||
[RequireXPowered]
|
||||
[HttpPost("RequestScopeAccessToken")]
|
||||
public async Task<ActionResult<XTokenResponse>> 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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Authenticate User
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Sample request:
|
||||
///
|
||||
/// {
|
||||
/// "password": "",
|
||||
/// "userSelectBy": "",
|
||||
/// }
|
||||
///
|
||||
/// </remarks>
|
||||
/// <param name="model">an instance of <see>XLoginRequest</see> class which represent Authentication requirements</param>
|
||||
/// <returns>an instance of <see>XTokenResponse</see></returns>
|
||||
[AllowAnonymous]
|
||||
[RequireXPowered]
|
||||
[HttpPost("Authenticate")]
|
||||
public async Task<ActionResult<XTokenResponse>> 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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Authenticate User
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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"
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// </remarks>
|
||||
/// <param name="model">an instance of <see>XLoginRequest</see> class which represent Authentication requirements</param>
|
||||
/// <returns>an instance of <see>XLoginResponse</see></returns>
|
||||
[AllowAnonymous]
|
||||
[RequireXPowered]
|
||||
[HttpPost("Login")]
|
||||
public async Task<ActionResult<XLoginResponse>> 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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh Expired Tokens
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// in addition to AccessToken, you had to pass RefreshToken due to Headers
|
||||
/// </remarks>
|
||||
/// <returns>an instance of <see>XTokenResponse</see></returns>
|
||||
[AllowAnonymous]
|
||||
[RequireXPowered]
|
||||
[HttpPost("RefreshTokens")]
|
||||
public async Task<ActionResult<XTokenResponse>> 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 ...
|
||||
/// <summary>
|
||||
/// Change a User's Password ...
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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"
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// </remarks>
|
||||
/// <param name="model">an instance of <see>XActionRequest</see> class which provider requirement for action</param>
|
||||
/// <returns></returns>
|
||||
[RequireXPowered]
|
||||
[HttpPost("ChangePassword")]
|
||||
[Authorize(Policy = XPolicies.User)]
|
||||
[Authorize(Policy = XPolicies.EnabledUser)]
|
||||
[Authorize(Policy = LocalApi.PolicyName)]
|
||||
public async Task<ActionResult> 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user