using System.Globalization; using System.Threading.Tasks; namespace zero.Core.Tokens { public abstract class ZeroTokenProvider { /// /// Creates bytes to use as a security token from the models internal data (preferable security stamp). /// /// The model. /// The security token bytes. protected abstract Task GetSecurityToken(T model); /// /// Returns a constant, provider and model unique modifier used for entropy in generated tokens from model information. /// /// The purpose the token will be generated for. /// The model a token should be generated for. /// /// The that represents the asynchronous operation, containing a constant modifier for the specified /// and . /// protected abstract Task GetModifier(string purpose, T model); /// public virtual async Task Generate(string purpose, T model) { var securityToken = await GetSecurityToken(model); var modifier = await GetModifier(purpose, model); return Rfc6238AuthenticationService.GenerateCode(securityToken, modifier).ToString("D6", CultureInfo.InvariantCulture); } /// public virtual async Task Validate(string purpose, string token, T model) { int code; if (!int.TryParse(token, out code)) { return false; } var securityToken = await GetSecurityToken(model); var modifier = await GetModifier(purpose, model); return securityToken != null && Rfc6238AuthenticationService.ValidateCode(securityToken, code, modifier); } } public interface IZeroTokenProvider { /// /// Generates a token for the specified and . /// /// The purpose the token will be used for. /// The model a token should be generated for. /// /// The that represents the asynchronous operation, containing the token for the specified /// and . /// /// /// The parameter allows a token generator to be used for multiple types of token whilst /// insuring a token for one purpose cannot be used for another. /// Task Generate(string purpose, T model); /// /// Returns a flag indicating whether the specified is valid for the given /// and . /// /// The purpose the token will be used for. /// The token to validate. /// The model a token should be validated for. /// /// The that represents the asynchronous operation, containing the a flag indicating the result /// of validating the for the specified and . /// The task will return true if the token is valid, otherwise false. /// Task Validate(string purpose, string token, T model); } }