diff --git a/SSO-Auth/Api/SSOController.cs b/SSO-Auth/Api/SSOController.cs index 4baacfa..0c203bc 100644 --- a/SSO-Auth/Api/SSOController.cs +++ b/SSO-Auth/Api/SSOController.cs @@ -677,6 +677,95 @@ public class SSOController : ControllerBase } } + /// + /// Unregisters a given mapping from id within provider to user. + /// + /// The mode of the function; SAML or OID. + /// The name of the provider from which the link should be removed. + /// The user ID within jellyfin to unlink from the provider. + /// The user ID within jellyfin to unlink. + /// Whether this API endpoint succeeded. + [Authorize(Policy = "DefaultAuthorization")] + [HttpDelete("{mode}/Link/{provider}/{jellyfinUserId}/{canonicalName}")] + [Consumes(MediaTypeNames.Application.Json)] + [Produces(MediaTypeNames.Application.Json)] + public async Task DeleteCanonicalLink([FromRoute] string mode, [FromRoute] string provider, [FromRoute] Guid jellyfinUserId, [FromRoute] string canonicalName) + { + if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, jellyfinUserId, true).ConfigureAwait(false)) + { + return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to link SSO providers."); + } + + Guid linkedId = GetCanonicalLink(mode, provider, canonicalName); + + if (linkedId != jellyfinUserId) + { + return StatusCode(StatusCodes.Status409Conflict, "jellyfin UID does not match id registered to that canonical name."); + } + + var links = GetCanonicalLinks(mode, provider); + + links.Remove(canonicalName); + + return UpdateCanonicalLinkConfig(links, mode, provider); + } + + /// + /// Gets all the saml links for a user. + /// + /// The user ID within jellyfin for which to return the links. + /// A dictionary of provider : link mappings. + [Authorize(Policy = "DefaultAuthorization")] + [HttpGet("saml/links/{jellyfinUserId}")] + [Produces(MediaTypeNames.Application.Json)] + public async Task>>> GetSamlLinksByUser(Guid jellyfinUserId) + { + if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, jellyfinUserId, true).ConfigureAwait(false)) + { + return StatusCode(StatusCodes.Status403Forbidden, "Non-admin is not allowed to query other user's mappings."); + } + + var mappings = new SerializableDictionary>(); + var providerList = SSOPlugin.Instance.Configuration.SamlConfigs; + + foreach (var providerName in providerList.Keys) + { + var canonLinks = providerList[providerName].CanonicalLinks; + var canonKeys = from link in canonLinks where link.Value == jellyfinUserId select link.Key; + mappings[providerName] = canonKeys; + } + + return mappings; + } + + /// + /// Gets all the oid links for a user. + /// + /// The user ID within jellyfin for which to return the links. + /// A dictionary of provider : link mappings. + [Authorize(Policy = "DefaultAuthorization")] + [HttpGet("oid/links/{jellyfinUserId}")] + [Produces(MediaTypeNames.Application.Json)] + public async Task>>> GetOidLinksByUser(Guid jellyfinUserId) + { + if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, jellyfinUserId, true).ConfigureAwait(false)) + { + return StatusCode(StatusCodes.Status403Forbidden, "Non-admin is not allowed to query other user's mappings."); + } + + var mappings = new SerializableDictionary>(); + var providerList = SSOPlugin.Instance.Configuration.OidConfigs; + + foreach (var providerName in providerList.Keys) + { + var canonLinks = providerList[providerName].CanonicalLinks; + var canonKeys = from link in canonLinks where link.Value == jellyfinUserId select link.Key; + mappings[providerName] = canonKeys; + } + + return mappings; + } + /// /// Validate a saml link request and create the link if it is valid. ///