예제 #1
0
        public async Task <IActionResult> Edit(string id, string returnUrl = null)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageApplications))
            {
                return(Forbid());
            }

            var application = await _applicationManager.FindByPhysicalIdAsync(id);

            if (application == null)
            {
                return(NotFound());
            }

            Task <bool> HasPermissionAsync(string permission) => _applicationManager.HasPermissionAsync(application, permission);

            var model = new EditOpenIdApplicationViewModel
            {
                AllowAuthorizationCodeFlow = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode),
                AllowClientCredentialsFlow = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.ClientCredentials),
                AllowImplicitFlow          = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.Implicit),
                AllowPasswordFlow          = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.Password),
                AllowRefreshTokenFlow      = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.RefreshToken),
                AllowLogoutEndpoint        = await HasPermissionAsync(OpenIddictConstants.Permissions.Endpoints.Logout),
                ClientId               = await _applicationManager.GetClientIdAsync(application),
                ConsentType            = await _applicationManager.GetConsentTypeAsync(application),
                DisplayName            = await _applicationManager.GetDisplayNameAsync(application),
                Id                     = await _applicationManager.GetPhysicalIdAsync(application),
                PostLogoutRedirectUris = string.Join(" ", await _applicationManager.GetPostLogoutRedirectUrisAsync(application)),
                RedirectUris           = string.Join(" ", await _applicationManager.GetRedirectUrisAsync(application)),
                Type                   = await _applicationManager.GetClientTypeAsync(application)
            };

            var roleService = HttpContext.RequestServices?.GetService <IRoleService>();

            if (roleService != null)
            {
                var roles = await _applicationManager.GetRolesAsync(application);

                foreach (var role in await roleService.GetRoleNamesAsync())
                {
                    model.RoleEntries.Add(new EditOpenIdApplicationViewModel.RoleEntry
                    {
                        Name     = role,
                        Selected = roles.Contains(role, StringComparer.OrdinalIgnoreCase)
                    });
                }
            }
            else
            {
                _notifier.Warning(H["There are no registered services to provide roles."]);
            }

            ViewData[nameof(OpenIdServerSettings)] = await GetServerSettingsAsync();

            ViewData["ReturnUrl"] = returnUrl;
            return(View(model));
        }
예제 #2
0
        public async Task <IActionResult> Edit(string id, string returnUrl = null)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageOpenIdApplications))
            {
                return(Unauthorized());
            }

            var openIdSettings = await _openIdService.GetOpenIdSettingsAsync();

            if (!_openIdService.IsValidOpenIdSettings(openIdSettings))
            {
                _notifier.Warning(H["OpenID Connect settings are not properly configured."]);
            }

            var application = await _applicationManager.FindByPhysicalIdAsync(id);

            if (application == null)
            {
                return(NotFound());
            }

            var model = new EditOpenIdApplicationViewModel
            {
                AllowAuthorizationCodeFlow = await _applicationManager.HasPermissionAsync(
                    application, OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode),
                AllowClientCredentialsFlow = await _applicationManager.HasPermissionAsync(
                    application, OpenIddictConstants.Permissions.GrantTypes.ClientCredentials),
                AllowImplicitFlow = await _applicationManager.HasPermissionAsync(
                    application, OpenIddictConstants.Permissions.GrantTypes.Implicit),
                AllowPasswordFlow = await _applicationManager.HasPermissionAsync(
                    application, OpenIddictConstants.Permissions.GrantTypes.Password),
                AllowRefreshTokenFlow = await _applicationManager.HasPermissionAsync(
                    application, OpenIddictConstants.Permissions.GrantTypes.RefreshToken),

                ClientId          = await _applicationManager.GetClientIdAsync(application),
                DisplayName       = await _applicationManager.GetDisplayNameAsync(application),
                Id                = await _applicationManager.GetPhysicalIdAsync(application),
                LogoutRedirectUri = (await _applicationManager.GetPostLogoutRedirectUrisAsync(application)).FirstOrDefault(),
                RedirectUri       = (await _applicationManager.GetRedirectUrisAsync(application)).FirstOrDefault(),
                SkipConsent       = string.Equals(await _applicationManager.GetConsentTypeAsync(application), OpenIddictConstants.ConsentTypes.Implicit),
                Type              = (ClientType)Enum.Parse(typeof(ClientType), await _applicationManager.GetClientTypeAsync(application), ignoreCase: true)
            };

            foreach (var role in await _roleProvider.GetRoleNamesAsync())
            {
                model.RoleEntries.Add(new RoleEntry
                {
                    Name     = role,
                    Selected = await _applicationManager.IsInRoleAsync(application, role)
                });
            }

            ViewData["OpenIdSettings"] = openIdSettings;
            ViewData["ReturnUrl"]      = returnUrl;
            return(View(model));
        }
예제 #3
0
        public async Task <IActionResult> Edit(string id, string returnUrl = null)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageOpenIdApplications))
            {
                return(Unauthorized());
            }

            var openIdSettings = await _openIdService.GetOpenIdSettingsAsync();

            if (!_openIdService.IsValidOpenIdSettings(openIdSettings))
            {
                _notifier.Warning(H["OpenID Connect settings are not properly configured."]);
            }

            var application = await _applicationManager.FindByIdAsync(id, HttpContext.RequestAborted);

            if (application == null)
            {
                return(NotFound());
            }

            var model = new EditOpenIdApplicationViewModel()
            {
                Id                = id,
                DisplayName       = application.DisplayName,
                RedirectUri       = application.RedirectUri,
                LogoutRedirectUri = application.LogoutRedirectUri,
                ClientId          = application.ClientId,
                Type              = application.Type,
                SkipConsent       = application.SkipConsent,
                RoleEntries       = (await _roleProvider.GetRoleNamesAsync())
                                    .Select(r => new RoleEntry()
                {
                    Name     = r,
                    Selected = application.RoleNames.Contains(r),
                }).ToList(),
                AllowAuthorizationCodeFlow = application.AllowAuthorizationCodeFlow,
                AllowClientCredentialsFlow = application.AllowClientCredentialsFlow,
                AllowImplicitFlow          = application.AllowImplicitFlow,
                AllowPasswordFlow          = application.AllowPasswordFlow,
                AllowRefreshTokenFlow      = application.AllowRefreshTokenFlow
            };

            ViewData["OpenIdSettings"] = openIdSettings;
            ViewData["ReturnUrl"]      = returnUrl;
            return(View(model));
        }
예제 #4
0
        public async Task <IActionResult> Edit(string id, string returnUrl = null)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageApplications))
            {
                return(Unauthorized());
            }

            var application = await _applicationManager.FindByPhysicalIdAsync(id);

            if (application == null)
            {
                return(NotFound());
            }

            Task <bool> HasPermissionAsync(string permission) => _applicationManager.HasPermissionAsync(application, permission);

            var model = new EditOpenIdApplicationViewModel
            {
                AllowAuthorizationCodeFlow = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode),
                AllowClientCredentialsFlow = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.ClientCredentials),
                AllowImplicitFlow          = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.Implicit),
                AllowPasswordFlow          = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.Password),
                AllowRefreshTokenFlow      = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.RefreshToken),
                AllowLogoutEndpoint        = await HasPermissionAsync(OpenIddictConstants.Permissions.Endpoints.Logout),
                ClientId               = await _applicationManager.GetClientIdAsync(application),
                ConsentType            = await _applicationManager.GetConsentTypeAsync(application),
                DisplayName            = await _applicationManager.GetDisplayNameAsync(application),
                Id                     = await _applicationManager.GetPhysicalIdAsync(application),
                PostLogoutRedirectUris = string.Join(" ", await _applicationManager.GetPostLogoutRedirectUrisAsync(application)),
                RedirectUris           = string.Join(" ", await _applicationManager.GetRedirectUrisAsync(application)),
                Type                   = await _applicationManager.GetClientTypeAsync(application)
            };

            foreach (var role in await _roleProvider.GetRoleNamesAsync())
            {
                model.RoleEntries.Add(new EditOpenIdApplicationViewModel.RoleEntry
                {
                    Name     = role,
                    Selected = await _applicationManager.IsInRoleAsync(application, role)
                });
            }

            ViewData[nameof(OpenIdServerSettings)] = await GetServerSettingsAsync();

            ViewData["ReturnUrl"] = returnUrl;
            return(View(model));
        }
예제 #5
0
        public async Task <IActionResult> Edit(EditOpenIdApplicationViewModel model, string returnUrl = null)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageOpenIdApplications))
            {
                return(Unauthorized());
            }

            if (model.Type == ClientType.Public && !string.IsNullOrEmpty(model.ClientSecret))
            {
                ModelState.AddModelError(nameof(model.ClientSecret), T["No client secret can be set for public applications."]);
            }
            else if (model.UpdateClientSecret)
            {
                var user = await _userManager.FindByNameAsync(User.Identity.Name);
                await ValidateClientSecretAsync(user, model.ClientSecret, (key, message) => ModelState.AddModelError(key, message));
            }

            OpenIdApplication application = null;

            if (ModelState.IsValid)
            {
                application = await _applicationManager.FindByIdAsync(model.Id, HttpContext.RequestAborted);

                if (application == null)
                {
                    return(NotFound());
                }

                if (application.Type == ClientType.Public && model.Type == ClientType.Confidential && !model.UpdateClientSecret)
                {
                    ModelState.AddModelError(nameof(model.UpdateClientSecret), T["Setting a new client secret is required"]);
                }
            }

            if (!ModelState.IsValid)
            {
                var openIdSettings = await _openIdService.GetOpenIdSettingsAsync();

                if (!_openIdService.IsValidOpenIdSettings(openIdSettings))
                {
                    _notifier.Warning(H["OpenID Connect settings are not properly configured."]);
                }

                ViewData["OpenIdSettings"] = openIdSettings;
                ViewData["ReturnUrl"]      = returnUrl;
                return(View(model));
            }

            // If the application was confidential and is now public, the client secret must be reset.
            if (application.Type == ClientType.Confidential && model.Type == ClientType.Public)
            {
                model.UpdateClientSecret = true;
                model.ClientSecret       = null;
            }

            application.DisplayName       = model.DisplayName;
            application.RedirectUri       = model.RedirectUri;
            application.LogoutRedirectUri = model.LogoutRedirectUri;
            application.ClientId          = model.ClientId;
            application.Type        = model.Type;
            application.SkipConsent = model.SkipConsent;
            application.AllowAuthorizationCodeFlow = model.AllowAuthorizationCodeFlow;
            application.AllowClientCredentialsFlow = model.AllowClientCredentialsFlow;
            application.AllowImplicitFlow          = model.AllowImplicitFlow;
            application.AllowPasswordFlow          = model.AllowPasswordFlow;
            application.AllowRefreshTokenFlow      = model.AllowRefreshTokenFlow;
            application.AllowHybridFlow            = model.AllowHybridFlow;

            application.RoleNames = new List <string>();
            if (application.Type == ClientType.Confidential && application.AllowClientCredentialsFlow)
            {
                application.RoleNames = model.RoleEntries.Where(r => r.Selected).Select(r => r.Name).ToList();
            }

            if (model.UpdateClientSecret)
            {
                await _applicationManager.UpdateAsync(application, model.ClientSecret, HttpContext.RequestAborted);
            }
            else
            {
                await _applicationManager.UpdateAsync(application, HttpContext.RequestAborted);
            }

            if (string.IsNullOrEmpty(returnUrl))
            {
                return(RedirectToAction("Index"));
            }

            return(LocalRedirect(returnUrl));
        }
        public async Task <IActionResult> Edit(EditOpenIdApplicationViewModel model, string returnUrl = null)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageApplications))
            {
                return(Unauthorized());
            }

            var application = await _applicationManager.FindByPhysicalIdAsync(model.Id);

            if (application == null)
            {
                return(NotFound());
            }

            // If the application was a public client and is now a confidential client, ensure a client secret was provided.
            if (string.IsNullOrEmpty(model.ClientSecret) &&
                !string.Equals(model.Type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase) &&
                await _applicationManager.IsPublicAsync(application))
            {
                ModelState.AddModelError(nameof(model.ClientSecret), T["Setting a new client secret is required."]);
            }

            if (!string.IsNullOrEmpty(model.ClientSecret) &&
                string.Equals(model.Type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
            {
                ModelState.AddModelError(nameof(model.ClientSecret), T["No client secret can be set for public applications."]);
            }

            if (ModelState.IsValid)
            {
                var other = await _applicationManager.FindByClientIdAsync(model.ClientId);

                if (other != null && !string.Equals(
                        await _applicationManager.GetIdAsync(other),
                        await _applicationManager.GetIdAsync(application), StringComparison.Ordinal))
                {
                    ModelState.AddModelError(nameof(model.ClientId), T["The client identifier is already taken by another application."]);
                }
            }

            if (!ModelState.IsValid)
            {
                ViewData[nameof(OpenIdServerSettings)] = await GetServerSettingsAsync();

                ViewData["ReturnUrl"] = returnUrl;
                return(View(model));
            }

            var descriptor = new OpenIdApplicationDescriptor();
            await _applicationManager.PopulateAsync(descriptor, application);

            descriptor.ClientId    = model.ClientId;
            descriptor.ConsentType = model.ConsentType;
            descriptor.DisplayName = model.DisplayName;
            descriptor.Type        = model.Type;

            if (!string.IsNullOrEmpty(model.ClientSecret))
            {
                descriptor.ClientSecret = model.ClientSecret;
            }

            if (string.Equals(descriptor.Type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
            {
                descriptor.ClientSecret = null;
            }

            if (model.AllowLogoutEndpoint)
            {
                descriptor.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Logout);
            }
            else
            {
                descriptor.Permissions.Remove(OpenIddictConstants.Permissions.Endpoints.Logout);
            }

            if (model.AllowAuthorizationCodeFlow)
            {
                descriptor.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode);
            }
            else
            {
                descriptor.Permissions.Remove(OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode);
            }

            if (model.AllowClientCredentialsFlow)
            {
                descriptor.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.ClientCredentials);
            }
            else
            {
                descriptor.Permissions.Remove(OpenIddictConstants.Permissions.GrantTypes.ClientCredentials);
            }

            if (model.AllowImplicitFlow)
            {
                descriptor.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Implicit);
            }
            else
            {
                descriptor.Permissions.Remove(OpenIddictConstants.Permissions.GrantTypes.Implicit);
            }

            if (model.AllowPasswordFlow)
            {
                descriptor.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Password);
            }
            else
            {
                descriptor.Permissions.Remove(OpenIddictConstants.Permissions.GrantTypes.Password);
            }

            if (model.AllowRefreshTokenFlow)
            {
                descriptor.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.RefreshToken);
            }
            else
            {
                descriptor.Permissions.Remove(OpenIddictConstants.Permissions.GrantTypes.RefreshToken);
            }

            if (model.AllowAuthorizationCodeFlow || model.AllowImplicitFlow)
            {
                descriptor.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Authorization);
            }
            else
            {
                descriptor.Permissions.Remove(OpenIddictConstants.Permissions.Endpoints.Authorization);
            }

            if (model.AllowAuthorizationCodeFlow || model.AllowClientCredentialsFlow ||
                model.AllowPasswordFlow || model.AllowRefreshTokenFlow)
            {
                descriptor.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Token);
            }
            else
            {
                descriptor.Permissions.Remove(OpenIddictConstants.Permissions.Endpoints.Token);
            }

            descriptor.Roles.Clear();

            foreach (string selectedRole in (model.RoleEntries
                                             .Where(role => role.Selected)
                                             .Select(role => role.Name)))
            {
                descriptor.Roles.Add(selectedRole);
            }

            descriptor.PostLogoutRedirectUris.Clear();
            foreach (Uri uri in
                     (from uri in model.PostLogoutRedirectUris?.Split(new[] { " ", "," }, StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty <string>()
                      select new Uri(uri, UriKind.Absolute)))
            {
                descriptor.PostLogoutRedirectUris.Add(uri);
            }

            descriptor.RedirectUris.Clear();
            foreach (Uri uri in
                     (from uri in model.RedirectUris?.Split(new[] { " ", "," }, StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty <string>()
                      select new Uri(uri, UriKind.Absolute)))
            {
                descriptor.RedirectUris.Add(uri);
            }

            await _applicationManager.UpdateAsync(application, descriptor);

            if (string.IsNullOrEmpty(returnUrl))
            {
                return(RedirectToAction("Index"));
            }

            return(LocalRedirect(returnUrl));
        }
예제 #7
0
        public virtual async Task UpdateAsync(IOpenIdApplication application,
                                              EditOpenIdApplicationViewModel model, CancellationToken cancellationToken = default)
        {
            if (application == null)
            {
                throw new ArgumentNullException(nameof(application));
            }

            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            await Store.SetClientIdAsync(application, model.ClientId, cancellationToken);

            await Store.SetClientTypeAsync(application, model.Type.ToString().ToLowerInvariant(), cancellationToken);

            await Store.SetDisplayNameAsync(application, model.DisplayName, cancellationToken);

            await Store.SetConsentTypeAsync(application, model.SkipConsent?
                                            OpenIddictConstants.ConsentTypes.Implicit :
                                            OpenIddictConstants.ConsentTypes.Explicit, cancellationToken);

            var permissions = new HashSet <string>(await Store.GetPermissionsAsync(application, cancellationToken), StringComparer.OrdinalIgnoreCase);

            if (model.AllowAuthorizationCodeFlow)
            {
                permissions.Add(OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode);
            }
            else
            {
                permissions.Remove(OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode);
            }

            if (model.AllowClientCredentialsFlow)
            {
                permissions.Add(OpenIddictConstants.Permissions.GrantTypes.ClientCredentials);
            }
            else
            {
                permissions.Remove(OpenIddictConstants.Permissions.GrantTypes.ClientCredentials);
            }

            if (model.AllowImplicitFlow)
            {
                permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Implicit);
            }
            else
            {
                permissions.Remove(OpenIddictConstants.Permissions.GrantTypes.Implicit);
            }

            if (model.AllowPasswordFlow)
            {
                permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Password);
            }
            else
            {
                permissions.Remove(OpenIddictConstants.Permissions.GrantTypes.Password);
            }

            if (model.AllowRefreshTokenFlow)
            {
                permissions.Add(OpenIddictConstants.Permissions.GrantTypes.RefreshToken);
            }
            else
            {
                permissions.Remove(OpenIddictConstants.Permissions.GrantTypes.RefreshToken);
            }

            if (model.AllowAuthorizationCodeFlow || model.AllowImplicitFlow)
            {
                permissions.Add(OpenIddictConstants.Permissions.Endpoints.Authorization);
            }
            else
            {
                permissions.Remove(OpenIddictConstants.Permissions.Endpoints.Authorization);
            }

            if (model.AllowAuthorizationCodeFlow || model.AllowClientCredentialsFlow ||
                model.AllowPasswordFlow || model.AllowRefreshTokenFlow)
            {
                permissions.Add(OpenIddictConstants.Permissions.Endpoints.Token);
            }
            else
            {
                permissions.Remove(OpenIddictConstants.Permissions.Endpoints.Token);
            }

            await Store.SetPermissionsAsync(application, permissions.ToImmutableArray(), cancellationToken);

            await Store.SetRolesAsync(application, model.RoleEntries
                                      .Where(role => role.Selected)
                                      .Select(role => role.Name)
                                      .ToImmutableArray(), cancellationToken);

            if (!string.IsNullOrEmpty(model.LogoutRedirectUri))
            {
                await Store.SetPostLogoutRedirectUrisAsync(application, ImmutableArray.Create(model.LogoutRedirectUri), cancellationToken);
            }
            else
            {
                await Store.SetPostLogoutRedirectUrisAsync(application, ImmutableArray.Create <string>(), cancellationToken);
            }

            if (!string.IsNullOrEmpty(model.RedirectUri))
            {
                await Store.SetRedirectUrisAsync(application, ImmutableArray.Create(model.RedirectUri), cancellationToken);
            }
            else
            {
                await Store.SetRedirectUrisAsync(application, ImmutableArray.Create <string>(), cancellationToken);
            }

            if (model.UpdateClientSecret)
            {
                await UpdateAsync(application, model.ClientSecret, cancellationToken);
            }
            else
            {
                await UpdateAsync(application, cancellationToken);
            }
        }
예제 #8
0
        public async Task <IActionResult> Edit(EditOpenIdApplicationViewModel model, string returnUrl = null)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageOpenIdApplications))
            {
                return(Unauthorized());
            }

            if (model.Type == ClientType.Public && !string.IsNullOrEmpty(model.ClientSecret))
            {
                ModelState.AddModelError(nameof(model.ClientSecret), T["No client secret can be set for public applications."]);
            }
            else if (model.UpdateClientSecret)
            {
                var user = await _userManager.FindByNameAsync(User.Identity.Name);
                await ValidateClientSecretAsync(user, model.ClientSecret, (key, message) => ModelState.AddModelError(key, message));
            }

            if (!model.AllowAuthorizationCodeFlow && !model.AllowClientCredentialsFlow &&
                !model.AllowImplicitFlow && !model.AllowPasswordFlow && !model.AllowRefreshTokenFlow)
            {
                ModelState.AddModelError(string.Empty, "At least one flow must be enabled.");
            }

            IOpenIdApplication application = null;

            if (ModelState.IsValid)
            {
                application = await _applicationManager.FindByPhysicalIdAsync(model.Id);

                if (application == null)
                {
                    return(NotFound());
                }

                if (model.Type == ClientType.Confidential && !model.UpdateClientSecret &&
                    await _applicationManager.IsPublicAsync(application))
                {
                    ModelState.AddModelError(nameof(model.UpdateClientSecret), T["Setting a new client secret is required"]);
                }

                var other = await _applicationManager.FindByClientIdAsync(model.ClientId);

                if (other != null && !string.Equals(
                        await _applicationManager.GetIdAsync(other),
                        await _applicationManager.GetIdAsync(application), StringComparison.Ordinal))
                {
                    ModelState.AddModelError(nameof(model.ClientId), T["The client identifier is already taken by another application."]);
                }
            }

            if (!ModelState.IsValid)
            {
                var openIdSettings = await _openIdService.GetOpenIdSettingsAsync();

                if (!_openIdService.IsValidOpenIdSettings(openIdSettings))
                {
                    _notifier.Warning(H["OpenID Connect settings are not properly configured."]);
                }

                ViewData["OpenIdSettings"] = openIdSettings;
                ViewData["ReturnUrl"]      = returnUrl;
                return(View(model));
            }

            await _applicationManager.UpdateAsync(application, model);

            if (string.IsNullOrEmpty(returnUrl))
            {
                return(RedirectToAction("Index"));
            }

            return(LocalRedirect(returnUrl));
        }
        public async Task <IActionResult> Edit(EditOpenIdApplicationViewModel model, string returnUrl = null)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageApplications))
            {
                return(Forbid());
            }

            var application = await _applicationManager.FindByPhysicalIdAsync(model.Id);

            if (application == null)
            {
                return(NotFound());
            }

            // If the application was a public client and is now a confidential client, ensure a client secret was provided.
            if (string.IsNullOrEmpty(model.ClientSecret) &&
                !string.Equals(model.Type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase) &&
                await _applicationManager.HasClientTypeAsync(application, OpenIddictConstants.ClientTypes.Public))
            {
                ModelState.AddModelError(nameof(model.ClientSecret), S["Setting a new client secret is required."]);
            }

            if (!string.IsNullOrEmpty(model.ClientSecret) &&
                string.Equals(model.Type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
            {
                ModelState.AddModelError(nameof(model.ClientSecret), S["No client secret can be set for public applications."]);
            }

            if (ModelState.IsValid)
            {
                var other = await _applicationManager.FindByClientIdAsync(model.ClientId);

                if (other != null && !string.Equals(
                        await _applicationManager.GetIdAsync(other),
                        await _applicationManager.GetIdAsync(application), StringComparison.Ordinal))
                {
                    ModelState.AddModelError(nameof(model.ClientId), S["The client identifier is already taken by another application."]);
                }
            }

            if (!ModelState.IsValid)
            {
                ViewData[nameof(OpenIdServerSettings)] = await GetServerSettingsAsync();

                ViewData["ReturnUrl"] = returnUrl;
                return(View(model));
            }

            var settings = new OpenIdApplicationSettings()
            {
                AllowAuthorizationCodeFlow = model.AllowAuthorizationCodeFlow,
                AllowClientCredentialsFlow = model.AllowClientCredentialsFlow,
                AllowHybridFlow            = model.AllowHybridFlow,
                AllowImplicitFlow          = model.AllowImplicitFlow,
                AllowLogoutEndpoint        = model.AllowLogoutEndpoint,
                AllowPasswordFlow          = model.AllowPasswordFlow,
                AllowRefreshTokenFlow      = model.AllowRefreshTokenFlow,
                ClientId               = model.ClientId,
                ClientSecret           = model.ClientSecret,
                ConsentType            = model.ConsentType,
                DisplayName            = model.DisplayName,
                PostLogoutRedirectUris = model.PostLogoutRedirectUris,
                RedirectUris           = model.RedirectUris,
                Roles  = model.RoleEntries.Where(x => x.Selected).Select(x => x.Name).ToArray(),
                Scopes = model.ScopeEntries.Where(x => x.Selected).Select(x => x.Name).ToArray(),
                Type   = model.Type
            };

            await _applicationManager.UpdateDescriptorFromSettings(settings, application);

            if (string.IsNullOrEmpty(returnUrl))
            {
                return(RedirectToAction(nameof(Index)));
            }

            return(this.LocalRedirect(returnUrl, true));
        }
        public async Task <IActionResult> Edit(string id, string returnUrl = null)
        {
            if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageApplications))
            {
                return(Forbid());
            }

            var application = await _applicationManager.FindByPhysicalIdAsync(id);

            if (application == null)
            {
                return(NotFound());
            }

            ValueTask <bool> HasPermissionAsync(string permission) => _applicationManager.HasPermissionAsync(application, permission);

            var model = new EditOpenIdApplicationViewModel
            {
                AllowAuthorizationCodeFlow = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode) &&
                                             await HasPermissionAsync(OpenIddictConstants.Permissions.ResponseTypes.Code),

                AllowClientCredentialsFlow = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.ClientCredentials),

                // Note: the hybrid flow doesn't have a dedicated grant_type but is treated as a combination
                // of both the authorization code and implicit grants. As such, to determine whether the hybrid
                // flow is enabled, both the authorization code grant and the implicit grant MUST be enabled.
                AllowHybridFlow = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode) &&
                                  await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.Implicit) &&
                                  (await HasPermissionAsync(OpenIddictConstants.Permissions.ResponseTypes.CodeIdToken) ||
                                   await HasPermissionAsync(OpenIddictConstants.Permissions.ResponseTypes.CodeIdTokenToken) ||
                                   await HasPermissionAsync(OpenIddictConstants.Permissions.ResponseTypes.CodeToken)),

                AllowImplicitFlow = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.Implicit) &&
                                    (await HasPermissionAsync(OpenIddictConstants.Permissions.ResponseTypes.IdToken) ||
                                     await HasPermissionAsync(OpenIddictConstants.Permissions.ResponseTypes.IdTokenToken) ||
                                     await HasPermissionAsync(OpenIddictConstants.Permissions.ResponseTypes.Token)),

                AllowPasswordFlow     = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.Password),
                AllowRefreshTokenFlow = await HasPermissionAsync(OpenIddictConstants.Permissions.GrantTypes.RefreshToken),
                AllowLogoutEndpoint   = await HasPermissionAsync(OpenIddictConstants.Permissions.Endpoints.Logout),
                ClientId               = await _applicationManager.GetClientIdAsync(application),
                ConsentType            = await _applicationManager.GetConsentTypeAsync(application),
                DisplayName            = await _applicationManager.GetDisplayNameAsync(application),
                Id                     = await _applicationManager.GetPhysicalIdAsync(application),
                PostLogoutRedirectUris = string.Join(" ", await _applicationManager.GetPostLogoutRedirectUrisAsync(application)),
                RedirectUris           = string.Join(" ", await _applicationManager.GetRedirectUrisAsync(application)),
                Type                   = await _applicationManager.GetClientTypeAsync(application)
            };

            var roleService = HttpContext.RequestServices?.GetService <IRoleService>();

            if (roleService != null)
            {
                var roles = await _applicationManager.GetRolesAsync(application);

                foreach (var role in await roleService.GetRoleNamesAsync())
                {
                    model.RoleEntries.Add(new EditOpenIdApplicationViewModel.RoleEntry
                    {
                        Name     = role,
                        Selected = roles.Contains(role, StringComparer.OrdinalIgnoreCase)
                    });
                }
            }
            else
            {
                await _notifier.WarningAsync(H["There are no registered services to provide roles."]);
            }

            var permissions = await _applicationManager.GetPermissionsAsync(application);

            await foreach (var scope in _scopeManager.ListAsync())
            {
                var scopeName = await _scopeManager.GetNameAsync(scope);

                model.ScopeEntries.Add(new EditOpenIdApplicationViewModel.ScopeEntry
                {
                    Name     = scopeName,
                    Selected = await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Prefixes.Scope + scopeName)
                });
            }

            ViewData[nameof(OpenIdServerSettings)] = await GetServerSettingsAsync();

            ViewData["ReturnUrl"] = returnUrl;
            return(View(model));
        }