summaryrefslogtreecommitdiff
path: root/src/main/java/moe/nea/prickly/util/OAuthUtil.java
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2025-10-12 20:05:48 +0200
committerLinnea Gräf <nea@nea.moe>2025-10-12 20:21:32 +0200
commit60dfd15a88242893a7a422b82604d25171809f77 (patch)
treeeeab8a964e8f449c71083f7c6da6816350fb964d /src/main/java/moe/nea/prickly/util/OAuthUtil.java
parentabc83ee7180e2ea4c5d65689dca48bfe88023862 (diff)
downloadprickly-60dfd15a88242893a7a422b82604d25171809f77.tar.gz
prickly-60dfd15a88242893a7a422b82604d25171809f77.tar.bz2
prickly-60dfd15a88242893a7a422b82604d25171809f77.zip
feat: add basic authorize endpoint
Diffstat (limited to 'src/main/java/moe/nea/prickly/util/OAuthUtil.java')
-rw-r--r--src/main/java/moe/nea/prickly/util/OAuthUtil.java54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/main/java/moe/nea/prickly/util/OAuthUtil.java b/src/main/java/moe/nea/prickly/util/OAuthUtil.java
new file mode 100644
index 0000000..ec3b7fd
--- /dev/null
+++ b/src/main/java/moe/nea/prickly/util/OAuthUtil.java
@@ -0,0 +1,54 @@
+/* (C) 2025 Linnea Gräf - Licensed to everyone under the BSD 3 Clause License */
+package moe.nea.prickly.util;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+import java.net.URI;
+import java.util.List;
+import java.util.Objects;
+import org.jspecify.annotations.Nullable;
+
+public class OAuthUtil {
+ private static final Splitter SCOPE_SPLITTER =
+ Splitter.on(' ').omitEmptyStrings().trimResults();
+
+ public static List<String> parseScopes(@Nullable String scope) {
+ if (scope == null) return List.of();
+ return SCOPE_SPLITTER.splitToList(scope);
+ }
+
+ public static URI verifyRedirectUrl(@Nullable String actualRedirectUri, String expectedRedirectUri) {
+ Objects.requireNonNull(expectedRedirectUri, "expected redirect uri is null");
+ if (actualRedirectUri == null) return verifyRedirectUrl(expectedRedirectUri, expectedRedirectUri);
+
+ var expected = URI.create(expectedRedirectUri);
+ var actual = URI.create(actualRedirectUri).normalize();
+ Preconditions.checkArgument(actual.isAbsolute(), "redirect URI must be absolute");
+ Preconditions.checkArgument(actual.getFragment() == null, "redirect URI must not have a fragment");
+ Preconditions.checkArgument(
+ Objects.equals(actual.getScheme(), expected.getScheme()),
+ "scheme differs from registered redirect URI");
+ Preconditions.checkArgument(
+ Objects.equals(actual.getAuthority(), expected.getAuthority()),
+ "origin differs from registered redirect URI");
+ Preconditions.checkArgument(actual.getUserInfo() == null, "redirect URI must not have a user info");
+ Preconditions.checkArgument(
+ expected.getPath() == null || actual.getPath().startsWith(expected.getPath()),
+ "redirect URI must be a subpath of registered redirect URI");
+ return actual;
+ }
+
+ public static ResponseType parseResponseType(@Nullable String responseType) {
+ return switch (responseType) {
+ case "code" -> ResponseType.CODE;
+ case "token" -> ResponseType.TOKEN;
+ case null -> throw new IllegalArgumentException("missing response_type");
+ default -> throw new IllegalArgumentException("invalid response_type " + responseType);
+ };
+ }
+
+ public enum ResponseType {
+ TOKEN,
+ CODE
+ }
+}