mirror of
https://github.com/plexusorg/Module-HTTPD.git
synced 2024-12-22 16:04:59 +00:00
begin oauth2 setup
This commit is contained in:
parent
ff9cf12acc
commit
2e40ddc6bc
8 changed files with 252 additions and 16 deletions
|
@ -1,35 +1,26 @@
|
||||||
package dev.plex;
|
package dev.plex;
|
||||||
|
|
||||||
|
import dev.plex.authentication.AuthenticationManager;
|
||||||
import dev.plex.cache.FileCache;
|
import dev.plex.cache.FileCache;
|
||||||
import dev.plex.config.ModuleConfig;
|
import dev.plex.config.ModuleConfig;
|
||||||
import dev.plex.module.PlexModule;
|
import dev.plex.module.PlexModule;
|
||||||
import dev.plex.request.AbstractServlet;
|
import dev.plex.request.AbstractServlet;
|
||||||
import dev.plex.request.SchematicUploadServlet;
|
import dev.plex.request.SchematicUploadServlet;
|
||||||
import dev.plex.request.impl.CommandsEndpoint;
|
import dev.plex.request.impl.*;
|
||||||
import dev.plex.request.impl.IndefBansEndpoint;
|
|
||||||
import dev.plex.request.impl.IndexEndpoint;
|
|
||||||
import dev.plex.request.impl.ListEndpoint;
|
|
||||||
import dev.plex.request.impl.PunishmentsEndpoint;
|
|
||||||
import dev.plex.request.impl.SchematicDownloadEndpoint;
|
|
||||||
import dev.plex.request.impl.SchematicUploadEndpoint;
|
|
||||||
import dev.plex.util.PlexLog;
|
import dev.plex.util.PlexLog;
|
||||||
import jakarta.servlet.MultipartConfigElement;
|
import jakarta.servlet.MultipartConfigElement;
|
||||||
import java.io.File;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.milkbowl.vault.permission.Permission;
|
import net.milkbowl.vault.permission.Permission;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
import org.eclipse.jetty.server.Connector;
|
import org.eclipse.jetty.server.*;
|
||||||
import org.eclipse.jetty.server.ForwardedRequestCustomizer;
|
|
||||||
import org.eclipse.jetty.server.HttpConfiguration;
|
|
||||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
import org.eclipse.jetty.server.ServerConnector;
|
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHandler;
|
import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
public class HTTPDModule extends PlexModule
|
public class HTTPDModule extends PlexModule
|
||||||
{
|
{
|
||||||
public static ServletContextHandler context;
|
public static ServletContextHandler context;
|
||||||
|
@ -45,6 +36,8 @@ public class HTTPDModule extends PlexModule
|
||||||
|
|
||||||
public static final String template = AbstractServlet.readFileReal(HTTPDModule.class.getResourceAsStream("/httpd/template.html"));
|
public static final String template = AbstractServlet.readFileReal(HTTPDModule.class.getResourceAsStream("/httpd/template.html"));
|
||||||
|
|
||||||
|
private AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load()
|
public void load()
|
||||||
{
|
{
|
||||||
|
@ -61,6 +54,18 @@ public class HTTPDModule extends PlexModule
|
||||||
{
|
{
|
||||||
throw new RuntimeException("Plex-HTTPD requires the 'Vault' plugin as well as a Permissions plugin that hooks into 'Vault'. We recommend LuckPerms!");
|
throw new RuntimeException("Plex-HTTPD requires the 'Vault' plugin as well as a Permissions plugin that hooks into 'Vault'. We recommend LuckPerms!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.authenticationManager = new AuthenticationManager();
|
||||||
|
if (this.authenticationManager.provider() != null)
|
||||||
|
{
|
||||||
|
PlexLog.debug(this.authenticationManager.provider().generateLogin());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlexLog.debug("Provider was not found for Authentication so disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
serverThread = new Thread(() ->
|
serverThread = new Thread(() ->
|
||||||
{
|
{
|
||||||
Server server = new Server();
|
Server server = new Server();
|
||||||
|
|
24
src/main/java/dev/plex/authentication/AuthenticatedUser.java
Normal file
24
src/main/java/dev/plex/authentication/AuthenticatedUser.java
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package dev.plex.authentication;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Taah
|
||||||
|
* @since 6:37 PM [03-05-2024]
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(fluent = true)
|
||||||
|
public class AuthenticatedUser
|
||||||
|
{
|
||||||
|
private final String ip;
|
||||||
|
private final ZonedDateTime lastAuthenticated;
|
||||||
|
private final LinkedList<String> roles = Lists.newLinkedList();
|
||||||
|
private final UserType userType = UserType.UNKNOWN;
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package dev.plex.authentication;
|
||||||
|
|
||||||
|
import dev.plex.HTTPDModule;
|
||||||
|
import dev.plex.authentication.impl.DiscordOAuth2Provider;
|
||||||
|
import dev.plex.util.PlexLog;
|
||||||
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Taah
|
||||||
|
* @since 7:08 PM [03-05-2024]
|
||||||
|
*/
|
||||||
|
public class AuthenticationManager
|
||||||
|
{
|
||||||
|
private final OAuth2Provider provider;
|
||||||
|
|
||||||
|
public AuthenticationManager()
|
||||||
|
{
|
||||||
|
final boolean enabled = HTTPDModule.moduleConfig.getBoolean("authentication.enabled", false);
|
||||||
|
if (!enabled)
|
||||||
|
{
|
||||||
|
provider = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlexLog.debug("[HTTPD] Auth is enabled");
|
||||||
|
|
||||||
|
final String providerName = HTTPDModule.moduleConfig.getString("authentication.provider.name", "");
|
||||||
|
if (providerName.isEmpty())
|
||||||
|
{
|
||||||
|
PlexLog.error("OAuth2 Authentication is enabled but no provider was given!");
|
||||||
|
provider = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlexLog.debug("[HTTPD] Provider name is {0}", providerName);
|
||||||
|
|
||||||
|
switch (providerName.toLowerCase())
|
||||||
|
{
|
||||||
|
case "discord" -> {
|
||||||
|
provider = new DiscordOAuth2Provider();
|
||||||
|
}
|
||||||
|
case "xenforo" -> {
|
||||||
|
throw new NotImplementedException("XenForo OAuth2 is not implemented yet!");
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
provider = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PlexLog.log("Using {0} provider for authentication", providerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OAuth2Provider provider()
|
||||||
|
{
|
||||||
|
return this.provider;
|
||||||
|
}
|
||||||
|
}
|
21
src/main/java/dev/plex/authentication/OAuth2Provider.java
Normal file
21
src/main/java/dev/plex/authentication/OAuth2Provider.java
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package dev.plex.authentication;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.Response;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Taah
|
||||||
|
* @since 6:36 PM [03-05-2024]
|
||||||
|
*/
|
||||||
|
public interface OAuth2Provider
|
||||||
|
{
|
||||||
|
HashMap<String, AuthenticatedUser> sessions();
|
||||||
|
|
||||||
|
AuthenticatedUser login(Response response, UserType type);
|
||||||
|
|
||||||
|
String[] roles(AuthenticatedUser user);
|
||||||
|
|
||||||
|
String generateLogin();
|
||||||
|
|
||||||
|
}
|
10
src/main/java/dev/plex/authentication/UserType.java
Normal file
10
src/main/java/dev/plex/authentication/UserType.java
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package dev.plex.authentication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Taah
|
||||||
|
* @since 6:37 PM [03-05-2024]
|
||||||
|
*/
|
||||||
|
public enum UserType
|
||||||
|
{
|
||||||
|
DISCORD, UNKNOWN
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
package dev.plex.authentication.impl;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import dev.plex.HTTPDModule;
|
||||||
|
import dev.plex.authentication.AuthenticatedUser;
|
||||||
|
import dev.plex.authentication.OAuth2Provider;
|
||||||
|
import dev.plex.authentication.UserType;
|
||||||
|
import dev.plex.util.PlexLog;
|
||||||
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
|
import org.eclipse.jetty.server.Response;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Taah
|
||||||
|
* @since 6:41 PM [03-05-2024]
|
||||||
|
*/
|
||||||
|
public class DiscordOAuth2Provider implements OAuth2Provider
|
||||||
|
{
|
||||||
|
private final HashMap<String, AuthenticatedUser> sessions = Maps.newHashMap();
|
||||||
|
|
||||||
|
private final String token;
|
||||||
|
private final String clientId;
|
||||||
|
private final String redirectUri;
|
||||||
|
|
||||||
|
public DiscordOAuth2Provider()
|
||||||
|
{
|
||||||
|
token = System.getenv("BOT_TOKEN").isEmpty() ? HTTPDModule.moduleConfig.getString("authentication.provider.discord.token", System.getProperty("BOT_TOKEN", "")) : System.getenv("BOT_TOKEN");
|
||||||
|
clientId = HTTPDModule.moduleConfig.getString("authentication.provider.discord.clientId", "");
|
||||||
|
redirectUri = URLEncoder.encode(HTTPDModule.moduleConfig.getString("authentication.provider.redirectUri", ""), StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
PlexLog.debug("[HTTPD] Client ID: {0}, Redirect URL: {1}", clientId, redirectUri);
|
||||||
|
|
||||||
|
if (redirectUri.isEmpty())
|
||||||
|
{
|
||||||
|
PlexLog.error("Provided authentication redirect url was empty for HTTPD!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token.isEmpty())
|
||||||
|
{
|
||||||
|
PlexLog.error("Provided discord authentication token was empty for HTTPD!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientId.isEmpty())
|
||||||
|
{
|
||||||
|
PlexLog.error("Provided discord client ID was empty for HTTPD!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HashMap<String, AuthenticatedUser> sessions()
|
||||||
|
{
|
||||||
|
return sessions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthenticatedUser login(Response response, UserType type)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] roles(AuthenticatedUser user)
|
||||||
|
{
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String generateLogin()
|
||||||
|
{
|
||||||
|
return String.format("https://discord.com/oauth2/authorize?client_id=%s&scope=%s&redirect_uri=%s",
|
||||||
|
clientId,
|
||||||
|
"identify%20guilds%20guilds.members.read",
|
||||||
|
redirectUri);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package dev.plex.request.impl;
|
||||||
|
|
||||||
|
import dev.plex.command.PlexCommand;
|
||||||
|
import dev.plex.command.annotation.CommandPermissions;
|
||||||
|
import dev.plex.request.AbstractServlet;
|
||||||
|
import dev.plex.request.GetMapping;
|
||||||
|
import dev.plex.util.PlexLog;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandMap;
|
||||||
|
import org.bukkit.command.PluginIdentifiableCommand;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class AuthenticationEndpoint extends AbstractServlet
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping(endpoint = "/oauth2")
|
||||||
|
public String login(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
{
|
||||||
|
// TODO: Nuh uh
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,3 +2,14 @@ server:
|
||||||
bind-address: 0.0.0.0
|
bind-address: 0.0.0.0
|
||||||
port: 27192
|
port: 27192
|
||||||
logging: false
|
logging: false
|
||||||
|
|
||||||
|
authentication:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
# Providers: discord
|
||||||
|
provider:
|
||||||
|
name: discord
|
||||||
|
redirectUri: ""
|
||||||
|
discord: # Fill if using discord provider
|
||||||
|
clientId: ""
|
||||||
|
token: "" # Can also use environment variable or system property BOT_TOKEN
|
Loading…
Reference in a new issue