Add UserHandler with promote/demote capabilities.
Fix bug in ConfigLoad preventing salt and hash fields from being populated when loading users. Convert User to a class. Fix UserService.getUser bug where it would compare the input user string instead of the resulting user against null.
This commit is contained in:
parent
f6c6930e50
commit
9f4c55e80d
8 changed files with 95 additions and 4 deletions
|
|
@ -20,7 +20,9 @@ The server includes a (working but very WIP) HTTP API for third-party clients an
|
|||
- [x] Search
|
||||
- [x] Downloads
|
||||
- [ ] Resumable downloads
|
||||
- [ ] User Management
|
||||
- [x] User Management
|
||||
- [x] Promote/demote users
|
||||
- [ ] Create/delete users
|
||||
|
||||
### Web interface
|
||||
- [x] Authentication
|
||||
|
|
|
|||
|
|
@ -1,9 +1,40 @@
|
|||
package org.adrianvictor.livingroom.auth;
|
||||
|
||||
import org.adrianvictor.livingroom.config.AppConfig;
|
||||
import org.adrianvictor.livingroom.utils.PasswordUtils;
|
||||
|
||||
public record User(String username, String hashedPassword, String salt, Role role) {
|
||||
public class User {
|
||||
private final String username;
|
||||
private final String hashedPassword;
|
||||
private final String salt;
|
||||
private Role role;
|
||||
|
||||
public User(String username, String hashedPassword, String salt, Role role) {
|
||||
this.username = username;
|
||||
this.hashedPassword = hashedPassword;
|
||||
this.salt = salt;
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public boolean auth(String password) {
|
||||
return PasswordUtils.verifyPassword(password, salt, hashedPassword);
|
||||
}
|
||||
|
||||
public AppConfig.UserConfig toConfig() {
|
||||
AppConfig.UserConfig config = new AppConfig.UserConfig();
|
||||
config.setRole(role.toString().toLowerCase());
|
||||
config.setHash(this.hashedPassword);
|
||||
config.setSalt(this.salt);
|
||||
return config;
|
||||
}
|
||||
|
||||
public void setRole(Role role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public Role role() { return role; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.adrianvictor.livingroom.config;
|
||||
|
||||
import org.adrianvictor.livingroom.Logger;
|
||||
import org.adrianvictor.livingroom.auth.User;
|
||||
import org.adrianvictor.livingroom.utils.PasswordUtils;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ public class ConfigLoader {
|
|||
AppConfig.UserConfig user = new AppConfig.UserConfig();
|
||||
user.setRole((String) userJson.get("role"));
|
||||
user.setPassword((String) userJson.get("password"));
|
||||
user.setSalt((String) userJson.get("salt"));
|
||||
user.setHash((String) userJson.get("hash"));
|
||||
|
||||
users.put(username, user);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.adrianvictor.livingroom.http;
|
||||
|
||||
import org.adrianvictor.livingroom.http.handlers.*;
|
||||
import org.adrianvictor.livingroom.http.handlers.UserHandler;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
|
|
@ -16,6 +17,7 @@ public class Handlers {
|
|||
map.put(new WebRedirectHandler(), "/");
|
||||
map.put(new LoginHandler(), "/login");
|
||||
map.put(new SearchHandler(), "/search");
|
||||
map.put(new UserHandler(), "/user");
|
||||
}
|
||||
|
||||
public static HashMap<Handler, String> getAll() {
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ public class Server {
|
|||
if (session == null) {
|
||||
try {
|
||||
AuthenticationHelper.sendUnauthorized(exchange, null);
|
||||
return;
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
}
|
||||
|
|
@ -98,7 +99,7 @@ public class Server {
|
|||
} catch (IOException ignored) {
|
||||
} catch (Exception e) {
|
||||
Logger.error("Handler error: " + e.getMessage());
|
||||
//e.printStackTrace();
|
||||
e.printStackTrace();
|
||||
try {
|
||||
exchange.sendResponseHeaders(500, 0);
|
||||
exchange.close();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
package org.adrianvictor.livingroom.http.handlers;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import org.adrianvictor.livingroom.Main;
|
||||
import org.adrianvictor.livingroom.auth.Role;
|
||||
import org.adrianvictor.livingroom.auth.Session;
|
||||
import org.adrianvictor.livingroom.auth.User;
|
||||
import org.adrianvictor.livingroom.http.Handler;
|
||||
import org.adrianvictor.livingroom.http.HttpResponse;
|
||||
import org.adrianvictor.livingroom.http.utils.AuthenticationHelper;
|
||||
import org.adrianvictor.livingroom.services.UserService;
|
||||
|
||||
public class UserHandler implements Handler {
|
||||
@Override
|
||||
public HttpResponse result(String baseAddress, String path, HttpExchange exchange) {
|
||||
String[] parts = path.split("/");
|
||||
Session session = AuthenticationHelper.getAuthenticatedSession(exchange);
|
||||
String username = session.getUsername();
|
||||
|
||||
if (parts.length < 2) {
|
||||
return HttpResponse.json(400, "Usage: '.../user/<promote|demote>/<username>'");
|
||||
}
|
||||
if (UserService.getInstance().getUser(username).role() != Role.ADMIN) {
|
||||
return HttpResponse.json(401, "You are not an administrator.");
|
||||
}
|
||||
|
||||
User user = UserService.getInstance().getUser(parts[1]);
|
||||
if (user == null) {
|
||||
return HttpResponse.json(401, "This user does not exist.");
|
||||
}
|
||||
|
||||
try {
|
||||
switch (parts[0]) {
|
||||
case "promote":
|
||||
user.setRole(Role.ADMIN);
|
||||
break;
|
||||
case "demote":
|
||||
user.setRole(Role.USER);
|
||||
break;
|
||||
default:
|
||||
return HttpResponse.json(400, "Usage: '.../user/<promote|demote>/<username>'");
|
||||
}
|
||||
|
||||
Main.getConfig().addUser(user.getName(), user.toConfig());
|
||||
Main.getConfig().saveConfig();
|
||||
|
||||
return HttpResponse.json(200, "Success.");
|
||||
} catch (Exception e) {
|
||||
return HttpResponse.json(500, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ public class UserService {
|
|||
public User getUser(String user) {
|
||||
AppConfig.UserConfig raw = users.get(user);
|
||||
|
||||
if (user == null) {
|
||||
if (raw == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue