From c5e1644d1786e9007a153fbc9b82c6b73411c15f Mon Sep 17 00:00:00 2001
From: Matthew Strasiotto <39424834+matthewstrasiotto@users.noreply.github.com>
Date: Mon, 30 May 2022 02:24:22 +1000
Subject: [PATCH] implement api for listing and deleting links
---
SSO-Auth/Api/SSOController.cs | 89 +++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
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.
///