Skip to content
This repository has been archived by the owner on Mar 11, 2024. It is now read-only.

Commit

Permalink
Permissions API
Browse files Browse the repository at this point in the history
  • Loading branch information
Raft08 committed Jan 17, 2024
1 parent 6674cce commit 54ae291
Show file tree
Hide file tree
Showing 13 changed files with 453 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package fr.atlasworld.network.api.command.permission;

/**
* Abstract representation of a permission.
*/
public interface Permission {

/**
* Get the identifier of the permission.
* <p>
* The identifier of a permission usually look like this {@code type.product.root.children}
* @return identifier of the permission.
*/
String identifier();

/**
* Get the display name of the permission.
* @return display name of the permission.
*/
String name();

/**
* Get the description of the permission.
* @return description of the permission.
*/
String description();


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package fr.atlasworld.network.api.command.permission;

import com.google.common.base.Preconditions;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
* Create permissions.
*/
public class PermissionBuilder {
protected final List<ChildPermissionBuilder> children;

protected String id;
protected String name;
protected String description;

public PermissionBuilder() {
this.children = new ArrayList<>();
}

public PermissionBuilder(@NotNull String id) {
Preconditions.checkArgument(id != null && !id.isEmpty(), "Identifier may not be null nor can it be empty!");

this.children = new ArrayList<>();
this.id = id;
}

public PermissionBuilder(@NotNull String id, String name, String description) {
Preconditions.checkArgument(id != null && !id.isEmpty(), "Identifier may not be null nor can it be empty!");

this.children = new ArrayList<>();

this.id = id;
this.name = name;
this.description = description;
}

private PermissionBuilder(@NotNull String id, String name, String description, List<ChildPermissionBuilder> children) {
Preconditions.checkArgument(id != null && !id.isEmpty(), "Identifier may not be null nor can it be empty!");

this.children = children;

this.id = id;
this.name = name;
this.description = description;
}

public PermissionBuilder identifier(@NotNull String id) {
Preconditions.checkArgument(id != null && !id.isEmpty(), "Identifier may not be null nor can it be empty!");

this.id = id;
return this;
}

public PermissionBuilder name(@NotNull String name) {
Preconditions.checkArgument(name != null && !name.isEmpty(), "Name may not be null nor can it be empty!");

this.name = name;
return this;
}

public PermissionBuilder description(@NotNull String description) {
Preconditions.checkArgument(description != null && !description.isEmpty(), "Description may not be null nor can it be empty!");

this.description = description;
return this;
}

public PermissionBuilder addChildren(@NotNull String childId, Consumer<ChildPermissionBuilder> builder) {
ChildPermissionBuilder child = new ChildPermissionBuilder(childId, this);
builder.accept(child);

this.children.add(child);
return this;
}

public Permission build() {
Preconditions.checkNotNull(this.id);

return Permissions.create(this);
}

public String getId() {
return id;
}

public String getName() {
return name;
}

public String getDescription() {
return description;
}

public List<ChildPermissionBuilder> getChildren() {
return children;
}


public static final class ChildPermissionBuilder extends PermissionBuilder {
private final PermissionBuilder parent;

private ChildPermissionBuilder(@NotNull String id, PermissionBuilder parent) {
super(id);
this.parent = parent;

Preconditions.checkArgument(id != null && !id.isEmpty(), "Identifier may not be null nor can it be empty!");
Preconditions.checkArgument(!id.contains("."), "Child permission identifier may not contain a '.'!");
}

@Override
public PermissionBuilder identifier(@NotNull String id) {
Preconditions.checkArgument(id != null && !id.isEmpty(), "Identifier may not be null nor can it be empty!");
Preconditions.checkArgument(!id.contains("."), "Child permission identifier may not contain a '.'!");

return super.identifier(id);
}

@Override
public String getId() {
return this.parent.getId() + "." + this.id;
}

@Override
public Permission build() {
return Permissions.create(new PermissionBuilder(this.getId(), this.name, this.description, this.children));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package fr.atlasworld.network.api.command.permission;

import fr.atlasworld.network.api.registry.event.RegistrationEvent;

public interface PermissionRegistrationEvent extends RegistrationEvent<Permission> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package fr.atlasworld.network.api.command.permission;

import com.google.common.base.Preconditions;
import fr.atlasworld.network.api.command.permission.internal.PermissionDelegate;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;

public class Permissions {
private static PermissionDelegate delegate;

/**
* Create a permission from a permission builder.
* @param builder the builder.
* @return newly created permission.
*/
public static Permission create(@NotNull PermissionBuilder builder) {
Preconditions.checkNotNull(builder);

return delegate.create(builder);
}

/**
* Get a permission from an identifier.
* @param identifier permission identifier.
* @return found permission.
* @throws IllegalArgumentException if no permissions with this identifier could be found.
*/
public static Permission of(@NotNull String identifier) {
Preconditions.checkNotNull(identifier);

return delegate.get(identifier);
}

@ApiStatus.Internal
public static void setDelegate(PermissionDelegate delegate) {
if (Permissions.delegate != null)
throw new UnsupportedOperationException("Delegate cannot be redefined.");

Permissions.delegate = delegate;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package fr.atlasworld.network.api.command.permission.internal;

import fr.atlasworld.network.api.command.permission.Permission;
import fr.atlasworld.network.api.command.permission.PermissionBuilder;
import org.jetbrains.annotations.ApiStatus;

@ApiStatus.Internal
public interface PermissionDelegate {
Permission create(PermissionBuilder builder);

Permission get(String permission);
}
5 changes: 5 additions & 0 deletions src/main/java/fr/atlasworld/network/core/AtlasNetwork.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import fr.atlasworld.network.core.concurrent.action.ActionUtilities;
import fr.atlasworld.network.core.console.SystemConsole;
import fr.atlasworld.network.core.console.commands.Commands;
import fr.atlasworld.network.core.console.permission.Permissions;
import fr.atlasworld.network.core.console.permission.api.PermissionDelegateImpl;
import fr.atlasworld.network.core.database.mongo.MongoDatabaseManager;
import fr.atlasworld.network.core.diagnostics.environment.Environment;
import fr.atlasworld.network.core.diagnostics.version.VersionFile;
Expand Down Expand Up @@ -94,6 +96,8 @@ public static AtlasNetwork getInstance() {
public void start() {
LOGGER.info("Loading AtlasNetwork..");

PermissionDelegateImpl.init(); // Register delegate.

SystemModuleManager.INSTANCE.loadModules(this); // Load Modules
SystemServerManager.load(this);

Expand All @@ -103,6 +107,7 @@ public void start() {

// Events Listener
SystemModuleManager.INSTANCE.registerListener(this, new Commands());
SystemModuleManager.INSTANCE.registerListener(this, new Permissions());

this.socket.register(); // Register Packets and Handshake info
this.console.register(); // Register commands & stuff
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import fr.atlasworld.network.core.AtlasNetwork;
import fr.atlasworld.network.core.boot.Bootstrap;
import fr.atlasworld.network.core.console.event.CommandRegistrationEventImpl;
import fr.atlasworld.network.core.console.permission.api.PermissionDelegateImpl;
import fr.atlasworld.network.core.console.permission.event.PermissionRegistrationEventImpl;
import fr.atlasworld.network.core.logging.LogUtils;
import fr.atlasworld.network.core.module.SystemModuleManager;
import fr.atlasworld.network.core.registry.NetworkRegistries;
Expand All @@ -34,6 +36,7 @@ public SystemConsole(CommandDispatcher<CommandSource> dispatcher) {

public void register() {
SystemModuleManager.INSTANCE.callEvent(new CommandRegistrationEventImpl()).syncUninterruptibly(); // Block until all listeners are called.
SystemModuleManager.INSTANCE.callEvent(new PermissionRegistrationEventImpl()).syncUninterruptibly();

NetworkRegistries.COMMANDS.getAllEntries()
.forEach(command -> this.dispatcher.register(command.getCommand()));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package fr.atlasworld.network.core.console.permission;

import fr.atlasworld.network.api.command.permission.Permission;
import fr.atlasworld.network.api.command.permission.PermissionBuilder;
import fr.atlasworld.network.api.command.permission.PermissionRegistrationEvent;
import fr.atlasworld.network.api.event.EventHandler;
import fr.atlasworld.network.api.event.EventListener;
import fr.atlasworld.network.api.registry.Register;
import fr.atlasworld.network.api.registry.RegistryObject;
import fr.atlasworld.network.api.util.Priority;
import fr.atlasworld.network.core.AtlasNetwork;

public class Permissions implements EventListener {
private static final Register<Permission> PERMISSIONS = new Register<>(AtlasNetwork.getInstance());

public static final RegistryObject<Permission> LOGGING_COMMAND_PERMISSION = PERMISSIONS.register("logging_command",
() -> new PermissionBuilder()
.identifier("command.network.logging")
.name("Logging Command Permission")
.description("Allows the user to use the '/logging' command.")
.addChildren("level", builder ->
builder.name("Logging Level Command Permission")
.description("Allows the user to use the '/logging level' command.")
)
.build()
);

public static final RegistryObject<Permission> SERVERS_COMMAND_PERMISSION = PERMISSIONS.register("servers_command",
() -> new PermissionBuilder()
.identifier("command.network.servers")
.name("Servers Command Permission")
.description("Allows the user to use the '/servers' command")
.addChildren("list", builder ->
builder.name("Servers List Command")
.description("Allows the user to use the '/servers list' command."))
.addChildren("create", builder ->
builder.name("Servers Create Command")
.description("Allows the user to use the '/servers create <bleuprint> <name> <dynamic>' command.")
)
.addChildren("purge", builder ->
builder.name("Servers Purge Command")
.description("Allows the user to use the '/servers purge' command.")
)
.addChildren("manage", builder ->
builder.name("Server Manage Command")
.description("Allows the user to use the '/servers manage' command.")
.addChildren("delete", dBuilder ->
dBuilder.name("Server Manage Delete Command.")
.description("Allows the user to use the '/servers manage <server> delete' command.")
)
.addChildren("start", dBuilder ->
dBuilder.name("Server Manage Start Command.")
.description("Allows the user to use the '/servers manage <server> start' command.")
)
.addChildren("stop", dBuilder ->
dBuilder.name("Server Manage Stop Command.")
.description("Allows the user to use the '/servers manage <server> stop' command.")
)
.addChildren("status", dBuilder ->
dBuilder.name("Server Manage Status Command.")
.description("Allows the user to use the '/servers manage <server> status' command.")
)
)
.build()
);

@EventHandler(priority = Priority.HIGHEST)
private void onRegister(PermissionRegistrationEvent event) {
PERMISSIONS.register(event);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package fr.atlasworld.network.core.console.permission.api;

import fr.atlasworld.network.api.command.permission.Permission;
import fr.atlasworld.network.api.command.permission.PermissionBuilder;
import fr.atlasworld.network.api.command.permission.PermissionRegistrationEvent;
import fr.atlasworld.network.api.command.permission.Permissions;
import fr.atlasworld.network.api.command.permission.internal.PermissionDelegate;
import fr.atlasworld.network.api.event.EventHandler;
import fr.atlasworld.network.api.event.EventListener;
import fr.atlasworld.network.api.util.Priority;
import fr.atlasworld.network.core.registry.NetworkRegistries;

public class PermissionDelegateImpl implements PermissionDelegate {

public static void init() {
try {
Permissions.setDelegate(new PermissionDelegateImpl());
} catch (UnsupportedOperationException e) {
throw new UnsupportedOperationException("Permission Delegate has already been initialized.");
}
}

private PermissionDelegateImpl() {
}

@Override
public Permission create(PermissionBuilder builder) {
return new PermissionImpl(builder.getId(), builder.getName(), builder.getDescription(), builder
.getChildren()
.stream()
.map(cBuilder -> (PermissionImpl) cBuilder.build())
.toList()
);
}

@Override
public Permission get(String permission) {
return NetworkRegistries.PERMISSIONS.getAsOptional(permission).orElseThrow(() ->
new IllegalArgumentException("Unknown permission '" + permission + "'!"));
}
}
Loading

0 comments on commit 54ae291

Please sign in to comment.