Skip to content

Commit

Permalink
begin oauth2 setup
Browse files Browse the repository at this point in the history
  • Loading branch information
Taah committed Mar 6, 2024
1 parent ff9cf12 commit 2e40ddc
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 16 deletions.
35 changes: 20 additions & 15 deletions src/main/java/dev/plex/HTTPDModule.java
Original file line number Diff line number Diff line change
@@ -1,35 +1,26 @@
package dev.plex;

import dev.plex.authentication.AuthenticationManager;
import dev.plex.cache.FileCache;
import dev.plex.config.ModuleConfig;
import dev.plex.module.PlexModule;
import dev.plex.request.AbstractServlet;
import dev.plex.request.SchematicUploadServlet;
import dev.plex.request.impl.CommandsEndpoint;
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.request.impl.*;
import dev.plex.util.PlexLog;
import jakarta.servlet.MultipartConfigElement;
import java.io.File;
import java.util.concurrent.atomic.AtomicReference;
import lombok.Getter;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.eclipse.jetty.server.Connector;
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.server.*;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;

import java.io.File;
import java.util.concurrent.atomic.AtomicReference;

public class HTTPDModule extends PlexModule
{
public static ServletContextHandler context;
Expand All @@ -45,6 +36,8 @@ public class HTTPDModule extends PlexModule

public static final String template = AbstractServlet.readFileReal(HTTPDModule.class.getResourceAsStream("/httpd/template.html"));

private AuthenticationManager authenticationManager;

@Override
public void load()
{
Expand All @@ -61,6 +54,18 @@ public void enable()
{
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(() ->
{
Server server = new Server();
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/dev/plex/authentication/AuthenticatedUser.java
Original file line number Diff line number Diff line change
@@ -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;
}
57 changes: 57 additions & 0 deletions src/main/java/dev/plex/authentication/AuthenticationManager.java
Original file line number Diff line number Diff line change
@@ -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 changes: 21 additions & 0 deletions src/main/java/dev/plex/authentication/OAuth2Provider.java
Original file line number Diff line number Diff line change
@@ -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 changes: 10 additions & 0 deletions src/main/java/dev/plex/authentication/UserType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package dev.plex.authentication;

/**
* @author Taah
* @since 6:37 PM [03-05-2024]
*/
public enum UserType
{
DISCORD, UNKNOWN
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
27 changes: 27 additions & 0 deletions src/main/java/dev/plex/request/impl/AuthenticationEndpoint.java
Original file line number Diff line number Diff line change
@@ -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 "";
}
}
13 changes: 12 additions & 1 deletion src/main/resources/httpd/config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
server:
bind-address: 0.0.0.0
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

0 comments on commit 2e40ddc

Please sign in to comment.