-
-
Notifications
You must be signed in to change notification settings - Fork 9
Use the manager
Olivier Lefebvre edited this page Dec 20, 2018
·
6 revisions
The PersistentDynamicManager<SchemeDefinition> is responsible to add, update, delete and list schemes dynamically managed.
And persist changes to the underlying database.
Here a sample of how to use it in a controller:
public class AuthenticationViewModel
{
[Required]
public string Scheme { get; set; }
[Required]
public string DisplayName { get; set; }
[Required]
public string ClientId { get; set; }
[Required]
public string ClientSecret { get; set; }
public string HandlerType { get; set; }
public PathString CallbackPath { get; internal set; }
}
public class HomeController : Controller
{
private readonly PersistentDynamicManager<SchemeDefinition> _manager;
private readonly SignInManager<IdentityUser> _signInManager;
public HomeController(PersistentDynamicManager<SchemeDefinition> manager, SignInManager<IdentityUser> signInManager)
{
_manager = manager ?? throw new ArgumentNullException(nameof(manager));
_signInManager = signInManager;
}
// Returns an empty details view to create a scheme for a type of handler
[Route("Create/{type}")]
public IActionResult Create(string type)
{
return View(new AuthenticationViewModel
{
HandlerType = type
});
}
// Creates a new scheme
[HttpPost]
[Route("Create/{type}")]
public async Task<IActionResult> Create(AuthenticationViewModel model)
{
if (ModelState.IsValid)
{
OAuthOptions oAuthOptions;
if (HandlerHelper.GetProviderName(model.HandlerType) == "Google")
{
oAuthOptions = new GoogleOptions();
}
else
{
oAuthOptions = new OAuthOptions();
}
oAuthOptions.ClientId = model.ClientId;
oAuthOptions.ClientSecret = model.ClientSecret;
oAuthOptions.CallbackPath = "/signin-" + model.Scheme;
await _manager.AddAsync(new SchemeDefinition
{
Scheme = model.Scheme,
DisplayName = model.DisplayName,
HandlerType = _manager.ManagedHandlerType.First(t => t.Name == model.HandlerType),
Options = oAuthOptions
});
return RedirectToAction("List");
}
return View(model);
}
// Returns a scheme details view to update id
[Route("Update/{scheme}")]
public async Task<IActionResult> Update(string scheme)
{
AuthenticationViewModel model;
var definition = await _manager.FindBySchemeAsync(scheme);
if (definition == null)
{
return NotFound();
}
else
{
model = new AuthenticationViewModel
{
Scheme = definition.Scheme,
DisplayName = definition.DisplayName,
HandlerType = definition.HandlerType.Name
};
var oAuthOptions = definition.Options as OAuthOptions; // GoogleOptions is OAuthOptions
model.ClientId = oAuthOptions.ClientId;
model.ClientSecret = oAuthOptions.ClientSecret;
}
return View(model);
}
// Updates a scheme
[HttpPost]
[Route("Update/{scheme}")]
public async Task<IActionResult> Update(AuthenticationViewModel model)
{
if (ModelState.IsValid)
{
var definition = await _manager.FindBySchemeAsync(model.Scheme);
if (definition == null)
{
return NotFound();
}
if (definition.Options is OAuthOptions oAuthOptions) // GoogleOptions is OAuthOptions
{
oAuthOptions.ClientId = model.ClientId;
oAuthOptions.ClientSecret = model.ClientSecret;
}
definition.DisplayName = model.DisplayName;
await _manager.UpdateAsync(definition);
}
return View(model);
}
// Deletes a scheme
[Route("Delete/{scheme}")]
public async Task<IActionResult> Delete(string scheme)
{
var definition = await _manager.FindBySchemeAsync(scheme);
if (definition == null)
{
return NotFound();
}
await _manager.RemoveAsync(scheme);
return RedirectToAction("List");
}
// Lists all schemes we can manage
[Route("List")]
public async Task<IActionResult> List()
{
var schemes = await _signInManager.GetExternalAuthenticationSchemesAsync();
var managedSchemes = schemes.Where(s => _manager.ManagedHandlerType.Any(h => s.HandlerType == h))
.Select(s => s.Name);
var definitions = managedSchemes.Select(name => _manager.FindBySchemeAsync(name).GetAwaiter().GetResult());
return View(definitions.Select(definition => new AuthenticationViewModel
{
Scheme = definition.Scheme,
DisplayName = definition.DisplayName,
CallbackPath = definition.Options is RemoteAuthenticationOptions remote ? remote.CallbackPath : null
}));
}
}