Skip to content
This repository has been archived by the owner on Apr 16, 2023. It is now read-only.

Token-based authentication with user context #209

Draft
wants to merge 16 commits into
base: bleeding-1.X.X
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
group 'de.fearnixx'
version '1.1.3'
version '1.1.4'
def projectVersion = project.version

apply plugin: 'java'
Expand Down
26 changes: 0 additions & 26 deletions src/api/java/de/fearnixx/jeak/reflect/RequestMapping.java

This file was deleted.

8 changes: 0 additions & 8 deletions src/api/java/de/fearnixx/jeak/reflect/Transactional.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.fearnixx.jeak.reflect;
package de.fearnixx.jeak.reflect.http;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.fearnixx.jeak.reflect;
package de.fearnixx.jeak.reflect.http;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
33 changes: 33 additions & 0 deletions src/api/java/de/fearnixx/jeak/reflect/http/RequestContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package de.fearnixx.jeak.reflect.http;

import de.fearnixx.jeak.service.http.request.IRequestContext;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Denotes a parameter to be filled from the request context.
*
* @apiNote The parameter injection will work within the bounds of class assignability compatibility.
* @implNote Some usages of this cause side-effects, please see the implementation notes on {@link IRequestContext.Attributes}
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestContext {

/**
* Denotes the attribute name to be used for the lookup.
* If none, the parameter injection will attempt to insert the {@link IRequestContext} instance.
*
* @see IRequestContext.Attributes for more information on available attributes.
*/
String attribute() default "";

/**
* Whether or not this parameter has to be set.
* Unset, non-required values are passed as {@code null}.
*/
boolean required() default true;
}
38 changes: 38 additions & 0 deletions src/api/java/de/fearnixx/jeak/reflect/http/RequestMapping.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package de.fearnixx.jeak.reflect.http;

import de.fearnixx.jeak.service.http.RequestMethod;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Mark a method as method to be available via the controller.
*
* method(): REQUIRED Specify the used HTTP-method.
*
* endpoint(): REQUIRED Specify the endpoint for the annotated method.
*
* requireAuth(): Specify whether the calls to this endpoint should use an authorization scheme.
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequestMapping {

/**
* The HTTP method associated with this endpoint.
*/
RequestMethod method() default RequestMethod.GET;

/**
* URI appendix for this endpoint.
*/
String endpoint();

/**
* Whether or not request against this endpoint <em>MUST BE</em> authenticated.
*/
boolean requireAuth() default true;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.fearnixx.jeak.reflect;
package de.fearnixx.jeak.reflect.http;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.fearnixx.jeak.reflect;
package de.fearnixx.jeak.reflect.http;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
package de.fearnixx.jeak.service.controller;
package de.fearnixx.jeak.service.http;

import java.util.Map;
import java.util.Optional;

/**
* The controller manager allows plugins to register services to a specified REST method.
*
*/
public interface IRestControllerService {
public interface IControllerService {

/**
* Registers a new REST controller to the controller manager.
*
* @param cntrlrClass The class the controller provides.
* @param restController The controller to be registered.
* @param <T> The Type of the service.
* @param cntrlrClass The class the controller provides.
* @param instance The controller to be registered.
* @param <T> The Type of the service.
*/
<T> void registerController(Class<T> cntrlrClass, T restController);
<T> void registerController(Class<T> cntrlrClass, T instance);

/**
* Optionally get a controller of the specified class.
*
* @param cntrlrClass The desired controller class.
* @param <T> The desired controller type.
* @param <T> The desired controller type.
* @return An {@link Optional<T>} representing the result.
*/
<T> Optional<T> provide(Class<T> cntrlrClass);
Expand All @@ -33,16 +32,16 @@ public interface IRestControllerService {
* This method performs no checks!
*
* @param cntrlrClass The desired service class.
* @param <T> The desired controller type.
* @param <T> The desired controller type.
* @return Either the controller instance,
* or {@core null} and a {@link ClassCastException} is thrown.
* or {@code null} and a {@link ClassCastException} is thrown.
*/
<T> T provideUnchecked(Class<T> cntrlrClass);

/**
* Provide all the registered controllers.
*
* @return A {@link Map<Class<?>, Object>} representing the controller.
* @return A {@code Map<Class<?>, Object>} representing the controller.
*/
Map<Class<?>, Object> provideAll();
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.fearnixx.jeak.service.controller;
package de.fearnixx.jeak.service.http;

import java.util.Map;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.fearnixx.jeak.service.controller;
package de.fearnixx.jeak.service.http;

public enum RequestMethod {
POST,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.fearnixx.jeak.service.controller;
package de.fearnixx.jeak.service.http;

import java.util.HashMap;
import java.util.Map;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.fearnixx.jeak.service.controller.exceptions;
package de.fearnixx.jeak.service.http.exceptions;

public class RegisterControllerException extends RuntimeException{
public RegisterControllerException(String message) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package de.fearnixx.jeak.service.http.request;

import de.fearnixx.jeak.service.http.request.token.IAuthenticationToken;

import java.util.Optional;

public interface IRequestContext {

/**
* Optionally retrieves a request attribute from the context.
* For officially supported attributes, see {@link Attributes}.
*/
<T> Optional<T> optAttribute(String name, Class<T> hint);

final class Attributes {

/**
* {@link IRequestContext}
*
* @apiNote Self-reference, mainly for internal purposes.
*/
public static final String REQUEST_CONTEXT = "http:requestContext";

/**
* {@link IAuthenticationToken}
*
* @apiNote Optionally filled, if authentication is successful AND the "Token" authentication scheme is used.
*
* @implNote Required parameter injections cause {@link org.eclipse.jetty.http.HttpStatus#UNAUTHORIZED_401} on unsuccessful authentication.
*/
public static final String AUTHENTICATION_TOKEN = "auth:token:authenticationToken";

/**
* {@link de.fearnixx.jeak.teamspeak.data.IUser}
*
* @apiNote Optionally filled, if authentication is successful AND the subject is an user.
* @implNote Required parameter injections cause {@link org.eclipse.jetty.http.HttpStatus#UNAUTHORIZED_401} on unsuccessful authentication or {@link org.eclipse.jetty.http.HttpStatus#FORBIDDEN_403} for principals that aren't users.
*/
public static final String AUTHENTICATION_USER = "auth:subject:authenticatedUser";

private Attributes() {
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package de.fearnixx.jeak.service.http.request.token;

import de.fearnixx.jeak.service.permission.base.ISubject;
import de.fearnixx.jeak.teamspeak.data.IUser;

import java.time.ZonedDateTime;
import java.util.Optional;

public interface IAuthenticationToken {

String getTokenString();

IUser getTokenOwner();

Optional<ZonedDateTime> getExpiry();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package de.fearnixx.jeak.service.http.request.token;

import de.fearnixx.jeak.teamspeak.data.IUser;

import java.time.ZonedDateTime;

public interface ITokenAuthService {

IAuthenticationToken generateToken(IUser tokenOwner);

void setTokenExpiry(IAuthenticationToken token, ZonedDateTime expiryValue);

void revokeToken(IAuthenticationToken token);

void revokeTokens(IUser tokenOwner);
}
6 changes: 2 additions & 4 deletions src/main/java/de/fearnixx/jeak/JeakBot.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,16 @@
import de.fearnixx.jeak.service.command.ICommandService;
import de.fearnixx.jeak.service.command.TypedCommandService;
import de.fearnixx.jeak.service.command.matcher.MatcherRegistry;
import de.fearnixx.jeak.service.controller.RestControllerService;
import de.fearnixx.jeak.service.database.DatabaseService;
import de.fearnixx.jeak.service.event.IEventService;
import de.fearnixx.jeak.service.http.ControllerService;
import de.fearnixx.jeak.service.locale.LocalizationService;
import de.fearnixx.jeak.service.mail.MailService;
import de.fearnixx.jeak.service.notification.NotificationService;
import de.fearnixx.jeak.service.permission.base.PermissionService;
import de.fearnixx.jeak.service.profile.ProfileService;
import de.fearnixx.jeak.service.task.ITaskService;
import de.fearnixx.jeak.service.teamspeak.UserService;
import de.fearnixx.jeak.service.token.TokenService;
import de.fearnixx.jeak.service.util.UtilCommands;
import de.fearnixx.jeak.task.TaskService;
import de.fearnixx.jeak.teamspeak.IServer;
Expand Down Expand Up @@ -187,8 +186,7 @@ protected void doServiceStartup() {
initializeService(new ProfileService(new File(confDir, "profiles")));
initializeService(new PermissionService());
initializeService(new UserService());
initializeService(new TokenService());
initializeService(new RestControllerService());
initializeService(new ControllerService());

if (ENABLE_VOICE_CONNECTIONS) {
initializeService(new VoiceConnectionService());
Expand Down

This file was deleted.

This file was deleted.

Loading