public async Task CreateMasterFoxIDsControlApiResourceDocumentAsync(string tenantName, bool includeMasterTenantScope = false) { var mControlApiResourceDownParty = new OAuthDownParty { Name = Constants.ControlApi.ResourceName }; await mControlApiResourceDownParty.SetIdAsync(new Party.IdKey { TenantName = tenantName?.ToLower(), TrackName = Constants.Routes.MasterTrackName, PartyName = Constants.ControlApi.ResourceName }); var scopes = new List <string> { Constants.ControlApi.Scope.Tenant }; if (includeMasterTenantScope) { scopes.Add(Constants.ControlApi.Scope.Master); } mControlApiResourceDownParty.Resource = new OAuthDownResource() { Scopes = scopes }; await tenantRepository.CreateAsync(mControlApiResourceDownParty); }
private async Task CreateSeedClientDocmentAsync() { Console.WriteLine("Creating seed client"); var seedClientDownParty = new OAuthDownParty(); await seedClientDownParty.SetIdAsync(new Party.IdKey { TenantName = settings.MasterTenant, TrackName = settings.MasterTrack, PartyName = settings.ClientId }); seedClientDownParty.Client = new OAuthDownClient { RedirectUris = new[] { settings.RedirectUri }.ToList(), ResourceScopes = new List <OAuthDownResourceScope> { new OAuthDownResourceScope { Resource = apiResourceName, Scopes = new[] { "foxids_master" }.ToList() } }, ResponseTypes = new[] { "token" }.ToList(), AccessTokenLifetime = 1800 // 30 minutes }; (var secret, var oauthClientSecret) = await CreateSecretAsync(); seedClientDownParty.Client.Secrets = new List <OAuthClientSecret> { oauthClientSecret }; seedClientDownParty.SetPartitionId(); await simpleTenantRepository.SaveAsync(seedClientDownParty); Console.WriteLine("Seed client document created and saved in Cosmos DB"); Console.WriteLine($"Seed client secret is: {secret}"); }
private async Task CreateFoxIDsApiResourceDocumentAsync() { Console.WriteLine("Creating FoxIDs api resource"); var apiResourceDownParty = new OAuthDownParty(); await apiResourceDownParty.SetIdAsync(new Party.IdKey { TenantName = settings.MasterTenant, TrackName = settings.MasterTrack, PartyName = apiResourceName }); apiResourceDownParty.Resource = new OAuthDownResource { Scopes = apiResourceScopes.ToList() }; apiResourceDownParty.SetPartitionId(); await simpleTenantRepository.SaveAsync(apiResourceDownParty); Console.WriteLine($"FoxIDs api resource document created and saved in Cosmos DB"); }
private async Task CreateNetCoreClientGrantConsoleSampleDownPartyAsync() { Func <string, Task> getAction = async(name) => { _ = await foxIDsApiClient.GetOAuthDownPartyAsync(name); }; Func <string, Task> postAction = async(name) => { var oauthDownParty = new OAuthDownParty { Name = name, Client = new OAuthDownClient { ResourceScopes = new[] { // Scope to API1. new OAuthDownResourceScope { Resource = "aspnetcore_api1_sample", Scopes = new [] { "admin", "some_access" } } }, ResponseTypes = new[] { "token" }, RedirectUris = new[] { $"uri:{netCoreClientGrantConsoleSampleDownPartyName}:client" }, AccessTokenLifetime = 600 // 10 minutes } }; await foxIDsApiClient.PostOAuthDownPartyAsync(oauthDownParty); var secret = "MXtV-UmVJqygGUthkG5Q_6SCpmyBpsksvA1kvbE735k"; await foxIDsApiClient.PostOAuthClientSecretDownPartyAsync(new OAuthClientSecretRequest { PartyName = oauthDownParty.Name, Secrets = new string[] { secret }, }); Console.WriteLine($"\t'{name}' client secret is: {secret}"); }; await CreateIfNotExistsAsync(netCoreClientGrantConsoleSampleDownPartyName, getAction, postAction); }
private async Task CreateAspNetCoreApi1SampleDownPartyAsync() { Func <string, Task> getAction = async(name) => { _ = await foxIDsApiClient.GetOAuthDownPartyAsync(name); }; Func <string, Task> postAction = async(name) => { var oauthDownParty = new OAuthDownParty { Name = name, Resource = new OAuthDownResource { Scopes = new[] { "admin", "some_access" } } }; await foxIDsApiClient.PostOAuthDownPartyAsync(oauthDownParty); }; await CreateIfNotExistsAsync(aspNetCoreApi1SampleDownPartyName, getAction, postAction); }
public async Task UpdateOAuthDownPartyAsync(OAuthDownParty party) => await PutAsync(oauthApiUri, party);
public async Task CreateOAuthDownPartyAsync(OAuthDownParty party) => await PostAsync(oauthApiUri, party);
public async Task <bool> ValidateModelAsync <TClient, TScope, TClaim>(ModelStateDictionary modelState, OAuthDownParty <TClient, TScope, TClaim> oauthDownParty) where TClient : OAuthDownClient <TScope, TClaim> where TScope : OAuthDownScope <TClaim> where TClaim : OAuthDownClaim { return(await ValidateClientResourceScopesAsync(modelState, oauthDownParty) && ValidateClientScopes(modelState, oauthDownParty) && ValidateResourceScopes(modelState, oauthDownParty)); }
private bool ValidateResourceScopes <TClient, TScope, TClaim>(ModelStateDictionary modelState, OAuthDownParty <TClient, TScope, TClaim> oauthDownParty) where TClient : OAuthDownClient <TScope, TClaim> where TScope : OAuthDownScope <TClaim> where TClaim : OAuthDownClaim { var isValid = true; if (oauthDownParty.Resource?.Scopes?.Count() > 0) { try { var duplicatedScope = oauthDownParty.Resource.Scopes.GroupBy(s => s).Where(g => g.Count() > 1).FirstOrDefault(); if (duplicatedScope != null) { throw new ValidationException($"Duplicated scope in resource, scope '{duplicatedScope.Key}'."); } } catch (ValidationException vex) { isValid = false; logger.Warning(vex); modelState.TryAddModelError($"{nameof(oauthDownParty.Resource)}.{nameof(oauthDownParty.Resource.Scopes)}".ToCamelCase(), vex.Message); } } return(isValid); }
private async Task <bool> ValidateClientResourceScopesAsync <TClient, TScope, TClaim>(ModelStateDictionary modelState, OAuthDownParty <TClient, TScope, TClaim> oauthDownParty) where TClient : OAuthDownClient <TScope, TClaim> where TScope : OAuthDownScope <TClaim> where TClaim : OAuthDownClaim { var isValid = true; if (oauthDownParty.Client?.ResourceScopes?.Count() > 0) { try { var duplicatedResourceScope = oauthDownParty.Client.ResourceScopes.GroupBy(r => r.Resource).Where(g => g.Count() > 1).FirstOrDefault(); if (duplicatedResourceScope != null) { throw new ValidationException($"Duplicated resource scope, resource '{duplicatedResourceScope.Key}'."); } foreach (var resourceScope in oauthDownParty.Client.ResourceScopes.Where(rs => !rs.Resource.Equals(oauthDownParty.Name, System.StringComparison.Ordinal))) { var duplicatedScope = resourceScope.Scopes?.GroupBy(s => s).Where(g => g.Count() > 1).FirstOrDefault(); if (duplicatedScope != null) { throw new ValidationException($"Duplicated scope in resource scope, resource '{resourceScope.Resource} scope '{duplicatedScope.Key}'."); } try { // Test if Down-party exists. var resourceDownParty = await tenantService.GetAsync <OAuthDownParty>(await DownParty.IdFormatAsync(RouteBinding, resourceScope.Resource)); if (resourceScope.Scopes?.Count > 0) { foreach (var scope in resourceScope.Scopes) { if (!(resourceDownParty.Resource?.Scopes?.Where(s => s.Equals(scope, System.StringComparison.Ordinal)).Count() > 0)) { throw new ValidationException($"Resource '{resourceScope.Resource}' scope '{scope}' not found."); } } } } catch (CosmosDataException ex) { if (ex.StatusCode == HttpStatusCode.NotFound) { isValid = false; var errorMessage = $"Resource scope down-party resource '{resourceScope.Resource}' not found."; logger.Warning(ex, errorMessage); modelState.TryAddModelError($"{nameof(oauthDownParty.Client)}.{nameof(oauthDownParty.Client.ResourceScopes)}".ToCamelCase(), errorMessage); } else { throw; } } } var appResourceScope = oauthDownParty.Client.ResourceScopes.Where(rs => rs.Resource.Equals(oauthDownParty.Name, System.StringComparison.Ordinal)).SingleOrDefault(); if (appResourceScope != null && appResourceScope.Scopes?.Count() > 0) { foreach (var scope in appResourceScope.Scopes) { if (!(oauthDownParty.Resource?.Scopes?.Where(s => s.Equals(scope, StringComparison.Ordinal)).Count() > 0)) { if (oauthDownParty.Resource == null) { oauthDownParty.Resource = new OAuthDownResource { Scopes = new List <string>() }; } oauthDownParty.Resource.Scopes.Add(scope); } } } } catch (ValidationException vex) { isValid = false; logger.Warning(vex); modelState.TryAddModelError($"{nameof(oauthDownParty.Client)}.{nameof(oauthDownParty.Client.ResourceScopes)}.{nameof(OAuthDownResourceScope.Scopes)}".ToCamelCase(), vex.Message); } } return(isValid); }
public async Task <bool> ValidateResourceScopesAsync <TClient, TScope, TClaim>(ModelStateDictionary modelState, OAuthDownParty <TClient, TScope, TClaim> oauthDownParty) where TClient : OAuthDownClient <TScope, TClaim> where TScope : OAuthDownScope <TClaim> where TClaim : OAuthDownClaim { var isValid = true; if (oauthDownParty.Client?.ResourceScopes?.Count() > 0) { foreach (var resourceScope in oauthDownParty.Client.ResourceScopes.Where(rs => !rs.Resource.Equals(oauthDownParty.Name, System.StringComparison.OrdinalIgnoreCase))) { try { _ = await tenantService.GetAsync <DownParty>(await DownParty.IdFormat(RouteBinding, resourceScope.Resource)); } catch (CosmosDataException ex) { if (ex.StatusCode == HttpStatusCode.NotFound) { isValid = false; var errorMessage = $"Resource scope down party resource '{resourceScope.Resource}' not found."; logger.Warning(ex, errorMessage); modelState.TryAddModelError($"{nameof(oauthDownParty.Client)}.{nameof(oauthDownParty.Client.ResourceScopes)}".ToCamelCase(), errorMessage); } else { throw; } } } } return(isValid); }
public async Task <OAuthDownParty> UpdateOAuthDownPartyAsync(OAuthDownParty party) => await PutResponseAsync <OAuthDownParty, OAuthDownParty>(oauthApiUri, party);
private OAuthDownPartyViewModel ToViewModel(GeneralOAuthDownPartyViewModel generalOAuthDownParty, OAuthDownParty oauthDownParty, List <OAuthClientSecretResponse> oauthDownSecrets) { return(oauthDownParty.Map <OAuthDownPartyViewModel>(afterMap => { if (afterMap.Client == null) { generalOAuthDownParty.EnableClientTab = false; } else { generalOAuthDownParty.EnableClientTab = true; afterMap.Client.ExistingSecrets = oauthDownSecrets.Select(s => new OAuthClientSecretViewModel { Name = s.Name, Info = s.Info }).ToList(); var defaultResourceScopeIndex = afterMap.Client.ResourceScopes.FindIndex(r => r.Resource.Equals(generalOAuthDownParty.Name, StringComparison.Ordinal)); if (defaultResourceScopeIndex > -1) { afterMap.Client.DefaultResourceScope = true; var defaultResourceScope = afterMap.Client.ResourceScopes[defaultResourceScopeIndex]; if (defaultResourceScope.Scopes?.Count() > 0) { foreach (var scope in defaultResourceScope.Scopes) { afterMap.Client.DefaultResourceScopeScopes.Add(scope); } } afterMap.Client.ResourceScopes.RemoveAt(defaultResourceScopeIndex); } else { afterMap.Client.DefaultResourceScope = false; } afterMap.Client.ScopesViewModel = afterMap.Client.Scopes.Map <List <OAuthDownScopeViewModel> >() ?? new List <OAuthDownScopeViewModel>(); } if (afterMap.Resource == null) { generalOAuthDownParty.EnableResourceTab = false; } else { generalOAuthDownParty.EnableResourceTab = true; } if (afterMap.ClaimTransforms?.Count > 0) { afterMap.ClaimTransforms = afterMap.ClaimTransforms.MapClaimTransforms(); } })); }