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
}
}