[FEATURE][EXPERIMENTAL] New permissions system

This commit is contained in:
Gravit 2020-03-30 10:56:23 +07:00
parent 8e1cf303ac
commit 0692fe367f
No known key found for this signature in database
GPG key ID: 061981E1E85D3216
10 changed files with 161 additions and 57 deletions

View file

@ -36,7 +36,7 @@ public void invoke(String... args) {
LogHelper.info("Client name %s | ip %s | connectUUID %s", client.username == null ? "null" : client.username, ip, frameHandler.getConnectUUID()); LogHelper.info("Client name %s | ip %s | connectUUID %s", client.username == null ? "null" : client.username, ip, frameHandler.getConnectUUID());
LogHelper.subInfo("Data: checkSign %s | auth_id %s", client.checkSign ? "true" : "false", LogHelper.subInfo("Data: checkSign %s | auth_id %s", client.checkSign ? "true" : "false",
client.auth_id); client.auth_id);
LogHelper.subInfo("Permissions: %s (long %d)", client.permissions == null ? "null" : client.permissions.toString(), client.permissions == null ? 0 : client.permissions.toLong()); LogHelper.subInfo("Permissions: %s (permissions %d | flags %d)", client.permissions == null ? "null" : client.permissions.toString(), client.permissions == null ? 0 : client.permissions.permissions, client.permissions == null ? 0 : client.permissions.flags);
} }
})); }));
} }

View file

@ -5,6 +5,7 @@
import pro.gravit.launcher.Launcher; import pro.gravit.launcher.Launcher;
import pro.gravit.launcher.LauncherConfig; import pro.gravit.launcher.LauncherConfig;
import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.Reconfigurable;
import pro.gravit.launchserver.auth.AuthProviderPair; import pro.gravit.launchserver.auth.AuthProviderPair;
import pro.gravit.launchserver.auth.handler.MemoryAuthHandler; import pro.gravit.launchserver.auth.handler.MemoryAuthHandler;
import pro.gravit.launchserver.auth.protect.ProtectHandler; import pro.gravit.launchserver.auth.protect.ProtectHandler;
@ -124,8 +125,10 @@ public void init(LaunchServer.ReloadType type) {
for (Map.Entry<String,AuthProviderPair> provider : auth.entrySet()) { for (Map.Entry<String,AuthProviderPair> provider : auth.entrySet()) {
provider.getValue().init(server, provider.getKey()); provider.getValue().init(server, provider.getKey());
} }
if (dao != null) if (dao != null) {
server.registerObject("dao", dao);
dao.init(server); dao.init(server);
}
if (protectHandler != null) { if (protectHandler != null) {
protectHandler.checkLaunchServerLicense(); protectHandler.checkLaunchServerLicense();
} }

View file

@ -2,14 +2,22 @@
import org.hibernate.SessionFactory; import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Configuration;
import pro.gravit.launcher.ClientPermissions;
import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.Reconfigurable;
import pro.gravit.launchserver.dao.User;
import pro.gravit.launchserver.dao.impl.UserHibernateImpl; import pro.gravit.launchserver.dao.impl.UserHibernateImpl;
import pro.gravit.launchserver.dao.impl.HibernateUserDAOImpl; import pro.gravit.launchserver.dao.impl.HibernateUserDAOImpl;
import pro.gravit.utils.command.Command;
import pro.gravit.utils.command.SubCommand;
import pro.gravit.utils.helper.CommonHelper; import pro.gravit.utils.helper.CommonHelper;
import pro.gravit.utils.helper.LogHelper;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class HibernateDaoProvider extends DaoProvider { public class HibernateDaoProvider extends DaoProvider implements Reconfigurable {
public String driver; public String driver;
public String url; public String url;
public String username; public String username;
@ -42,4 +50,65 @@ public void init(LaunchServer server) {
else else
init.run(); init.run();
} }
@Override
public Map<String, Command> getCommands() {
Map<String, Command> commands = new HashMap<>();
commands.put("getallusers", new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
int count = 0;
for (User user : userDAO.findAll()) {
LogHelper.subInfo("[%s] UUID: %s", user.getUsername(), user.getUuid().toString());
count++;
}
LogHelper.info("Print %d users", count);
}
});
commands.put("getuser", new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
verifyArgs(args, 1);
User user = userDAO.findByUsername(args[0]);
if (user == null) {
LogHelper.error("User %s not found", args[0]);
return;
}
LogHelper.info("[%s] UUID: %s | permissions %s", user.getUsername(), user.getUuid().toString(), user.getPermissions() == null ? "null" : user.getPermissions().toString());
}
});
commands.put("givepermission", new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
verifyArgs(args, 3);
User user = userDAO.findByUsername(args[0]);
if (user == null) {
LogHelper.error("User %s not found", args[0]);
return;
}
ClientPermissions permissions = user.getPermissions();
long perm = Long.parseLong(args[1]);
boolean value = Boolean.parseBoolean(args[2]);
permissions.setPermission(perm, value);
userDAO.update(user);
}
});
commands.put("giveflag", new SubCommand() {
@Override
public void invoke(String... args) throws Exception {
verifyArgs(args, 3);
User user = userDAO.findByUsername(args[0]);
if (user == null) {
LogHelper.error("User %s not found", args[0]);
return;
}
ClientPermissions permissions = user.getPermissions();
long perm = Long.parseLong(args[1]);
boolean value = Boolean.parseBoolean(args[2]);
permissions.setFlag(perm, value);
userDAO.update(user);
}
});
return commands;
}
} }

View file

@ -1,6 +1,7 @@
package pro.gravit.launchserver.socket.response.admin; package pro.gravit.launchserver.socket.response.admin;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import pro.gravit.launcher.ClientPermissions;
import pro.gravit.launcher.events.request.LogEvent; import pro.gravit.launcher.events.request.LogEvent;
import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.Client;
import pro.gravit.launchserver.socket.response.SimpleResponse; import pro.gravit.launchserver.socket.response.SimpleResponse;
@ -20,7 +21,7 @@ public void execute(ChannelHandlerContext ctx, Client client) {
sendError("Access denied"); sendError("Access denied");
return; return;
} }
if (!client.permissions.canAdmin) { if (!client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN)) {
sendError("Access denied"); sendError("Access denied");
return; return;
} }

View file

@ -1,6 +1,7 @@
package pro.gravit.launchserver.socket.response.admin; package pro.gravit.launchserver.socket.response.admin;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import pro.gravit.launcher.ClientPermissions;
import pro.gravit.launcher.events.request.ExecCommandRequestEvent; import pro.gravit.launcher.events.request.ExecCommandRequestEvent;
import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.Client;
import pro.gravit.launchserver.socket.response.SimpleResponse; import pro.gravit.launchserver.socket.response.SimpleResponse;
@ -15,7 +16,7 @@ public String getType() {
@Override @Override
public void execute(ChannelHandlerContext ctx, Client client) { public void execute(ChannelHandlerContext ctx, Client client) {
if (!client.isAuth || !client.permissions.canAdmin) { if (!client.isAuth || !client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN)) {
sendError("Access denied"); sendError("Access denied");
return; return;
} }

View file

@ -1,6 +1,7 @@
package pro.gravit.launchserver.socket.response.auth; package pro.gravit.launchserver.socket.response.auth;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import pro.gravit.launcher.ClientPermissions;
import pro.gravit.launcher.events.RequestEvent; import pro.gravit.launcher.events.RequestEvent;
import pro.gravit.launcher.events.request.ExitRequestEvent; import pro.gravit.launcher.events.request.ExitRequestEvent;
import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.Client;
@ -17,7 +18,7 @@ public String getType() {
@Override @Override
public void execute(ChannelHandlerContext ctx, Client client) throws Exception { public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
if(username != null && ( !client.isAuth || client.permissions == null || !client.permissions.canAdmin )) if(username != null && ( !client.isAuth || client.permissions == null || !client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN) ))
{ {
sendError("Permissions denied"); sendError("Permissions denied");
return; return;

View file

@ -1,6 +1,7 @@
package pro.gravit.launchserver.socket.response.auth; package pro.gravit.launchserver.socket.response.auth;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import pro.gravit.launcher.ClientPermissions;
import pro.gravit.launchserver.dao.User; import pro.gravit.launchserver.dao.User;
import pro.gravit.launchserver.dao.impl.UserHibernateImpl; import pro.gravit.launchserver.dao.impl.UserHibernateImpl;
import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.Client;
@ -21,7 +22,7 @@ public class RegisterResponse extends SimpleResponse {
@Override @Override
public void execute(ChannelHandlerContext ctx, Client client) throws Exception { public void execute(ChannelHandlerContext ctx, Client client) throws Exception {
byte[] normalHash = registerHash(login, server.runtime.registerApiKey); byte[] normalHash = registerHash(login, server.runtime.registerApiKey);
if (!(client.isAuth && client.permissions.canAdmin) && !Arrays.equals(normalHash, verifyHash)) { if (!(client.isAuth && client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN)) && !Arrays.equals(normalHash, verifyHash)) {
sendError("Hash invalid"); sendError("Hash invalid");
return; return;
} }

View file

@ -1,6 +1,7 @@
package pro.gravit.launchserver.socket.response.auth; package pro.gravit.launchserver.socket.response.auth;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import pro.gravit.launcher.ClientPermissions;
import pro.gravit.launcher.events.request.SetPasswordRequestEvent; import pro.gravit.launcher.events.request.SetPasswordRequestEvent;
import pro.gravit.launchserver.dao.User; import pro.gravit.launchserver.dao.User;
import pro.gravit.launchserver.socket.Client; import pro.gravit.launchserver.socket.Client;
@ -26,7 +27,7 @@ public void execute(ChannelHandlerContext ctx, Client client) {
sendError("You not authorized"); sendError("You not authorized");
return; return;
} }
if (username != null && !client.permissions.canAdmin) { if (username != null && !client.permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN)) {
sendError("You not admin"); sendError("You not admin");
return; return;
} }

View file

@ -12,10 +12,6 @@ public class AuthService {
public static ClientProfile profile; public static ClientProfile profile;
public static boolean isAdmin() { public static boolean isAdmin() {
return permissions.canAdmin; return permissions.isPermission(ClientPermissions.PermissionConsts.ADMIN);
}
public static boolean isServer() {
return permissions.canServer;
} }
} }

View file

@ -8,73 +8,104 @@
public class ClientPermissions { public class ClientPermissions {
public static final ClientPermissions DEFAULT = new ClientPermissions(); public static final ClientPermissions DEFAULT = new ClientPermissions();
@LauncherNetworkAPI public long permissions;
public boolean canAdmin; public long flags;
@LauncherNetworkAPI public enum PermissionConsts
public boolean canServer; {
@LauncherNetworkAPI ADMIN(0x01),
public final boolean canUSR1; MANAGEMENT(0x02);
@LauncherNetworkAPI public final long mask;
public final boolean canUSR2;
@LauncherNetworkAPI PermissionConsts(long mask) {
public final boolean canUSR3; this.mask = mask;
@LauncherNetworkAPI }
public boolean canBot; }
public enum FlagConsts
{
SYSTEM(0x01),
BANNED(0x02),
UNTRUSTED(0x04),
HIDDEN(0x08);
public final long mask;
FlagConsts(long mask) {
this.mask = mask;
}
}
public ClientPermissions(HInput input) throws IOException { public ClientPermissions(HInput input) throws IOException {
this(input.readLong()); this(input.readLong());
} }
public ClientPermissions() { public ClientPermissions() {
canAdmin = false;
canServer = false;
canUSR1 = false;
canUSR2 = false;
canUSR3 = false;
canBot = false;
} }
public ClientPermissions(long data) { public ClientPermissions(long permissions) {
canAdmin = (data & (1)) != 0; this.permissions = permissions;
canServer = (data & (1 << 1)) != 0;
canUSR1 = (data & (1 << 2)) != 0;
canUSR2 = (data & (1 << 3)) != 0;
canUSR3 = (data & (1 << 4)) != 0;
canBot = (data & (1 << 5)) != 0;
} }
public ClientPermissions(long permissions, long flags) {
this.permissions = permissions;
this.flags = flags;
}
public long toLong() { public long toLong() {
long result = 0; return permissions;
result |= !canAdmin ? 0 : 1;
result |= !canServer ? 0 : (1 << 1);
result |= !canUSR1 ? 0 : (1 << 2);
result |= !canUSR2 ? 0 : (1 << 3);
result |= !canUSR3 ? 0 : (1 << 4);
result |= !canBot ? 0 : (1 << 5);
return result;
} }
public static ClientPermissions getSuperuserAccount() { public static ClientPermissions getSuperuserAccount() {
ClientPermissions perm = new ClientPermissions(); ClientPermissions perm = new ClientPermissions();
perm.canServer = true;
perm.canAdmin = true;
return perm; return perm;
} }
@Deprecated
public void write(HOutput output) throws IOException { public void write(HOutput output) throws IOException {
output.writeLong(toLong()); output.writeLong(toLong());
} }
//Read methods
public final boolean isPermission(PermissionConsts con)
{
return (permissions & con.mask) != 0;
}
public final boolean isPermission(long mask)
{
return (permissions & mask) != 0;
}
public final boolean isFlag(FlagConsts con)
{
return (flags & con.mask) != 0;
}
public final boolean isFlag(long mask)
{
return (flags & mask) != 0;
}
//Write methods
public final void setPermission(PermissionConsts con, boolean value)
{
if(value) this.permissions |= con.mask;
else this.permissions &= ~con.mask;
}
public final void setPermission(long mask, boolean value)
{
if(value) this.permissions |= mask;
else this.permissions &= ~mask;
}
public final void setFlag(FlagConsts con, boolean value)
{
if(value) this.flags |= con.mask;
else this.flags &= ~con.mask;
}
public final void setFlag(long mask, boolean value)
{
if(value) this.flags |= mask;
else this.flags &= ~mask;
}
@Override @Override
public String toString() { public String toString() {
return new StringJoiner(", ", ClientPermissions.class.getSimpleName() + "[", "]") return String.format("permissions %d | flags %d", permissions, flags);
.add("canAdmin=" + canAdmin)
.add("canServer=" + canServer)
.add("canUSR1=" + canUSR1)
.add("canUSR2=" + canUSR2)
.add("canUSR3=" + canUSR3)
.add("canBot=" + canBot)
.toString();
} }
} }