Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Player Password File for "account database" #2917

Merged
merged 58 commits into from
Aug 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
a39b327
send username upfront
cwisniew Jun 14, 2021
cfe56cb
Change MAC to be based on username
cwisniew Jun 14, 2021
b72687e
fix player pass
cwisniew Jun 14, 2021
0b77aa3
Use base64 encode of password for mac
cwisniew Jun 14, 2021
dfdf9b0
Start moving plain text to SecretKey for caclualting mac
cwisniew Jun 15, 2021
fe699f7
correct player v gm pass issue
cwisniew Jun 15, 2021
bd2b0b6
fix for verification
cwisniew Jun 16, 2021
81fa537
Merge branch 'develop' of github.com:RPTools/maptool into player-pass…
cwisniew Jun 17, 2021
8cbdb0f
cleanup
cwisniew Jun 17, 2021
2462ae3
Player refactor
cwisniew Jun 17, 2021
647e772
refactor LocalPlayer
cwisniew Jun 19, 2021
7b9659c
Refactor for Player Database
cwisniew Jun 19, 2021
483c953
Merge branch 'develop' of github.com:RPTools/maptool into player-pass…
cwisniew Jun 19, 2021
53e40bc
add key utility functions
cwisniew Jun 22, 2021
9aab4d8
Password Database update
cwisniew Jul 16, 2021
05e4391
start personal server player db
cwisniew Jul 16, 2021
4150849
Personal Server Working
cwisniew Jul 16, 2021
bde7903
Default Player Database
cwisniew Jul 16, 2021
398cee5
merge
cwisniew Jul 16, 2021
403398d
Add use password file to server start dialog
cwisniew Jul 16, 2021
3bf15ef
add password file checkmark
cwisniew Jul 17, 2021
7c6db67
start server with player database file
cwisniew Jul 17, 2021
18379bf
backup password file on update
cwisniew Jul 17, 2021
e02c911
Better error messages when reading password file fails
cwisniew Jul 18, 2021
bbc64cf
Add Web End Point
cwisniew Jul 18, 2021
9b26188
Start of Servlet Functionality
cwisniew Jul 19, 2021
9e0ed27
First servlet route
cwisniew Jul 19, 2021
a9971a2
start of api
cwisniew Jul 20, 2021
c7faa00
start to flesh out api
cwisniew Jul 20, 2021
750ecb3
start of player api
cwisniew Jul 20, 2021
6bbc21d
Add Players to API
cwisniew Jul 21, 2021
2d3b8bb
fix error with localtime serialization
cwisniew Jul 21, 2021
a5443b6
implement resteasy
cwisniew Jul 22, 2021
0a514bf
add json provider
cwisniew Jul 22, 2021
7649945
adding status values
cwisniew Jul 23, 2021
e40b478
fetch player details API
cwisniew Jul 24, 2021
0f1906e
Refactor of CipherUtil
cwisniew Jul 27, 2021
e036470
Merge branch 'develop' of https://github.com/RPTools/maptool into fea…
cwisniew Jul 29, 2021
f9188ea
Public/Private key store
cwisniew Jul 29, 2021
14ce875
text format for public key
cwisniew Jul 29, 2021
dd4ece7
Fix text representation of public key and add ability to regenrate
cwisniew Jul 30, 2021
447f240
initial work for public key in password file
cwisniew Jul 30, 2021
f954145
more public key additions
cwisniew Jul 30, 2021
480f268
add transferable player method
cwisniew Jul 31, 2021
a0d45bb
Merged RSA and resteasy branches
cwisniew Aug 2, 2021
b24bd0f
PlayerDB and Player info apis
cwisniew Aug 2, 2021
55d1b59
api updates
cwisniew Aug 3, 2021
be2f608
Merge branch 'develop' into feature-player-passwords
cwisniew Aug 19, 2021
762b744
fix for error
cwisniew Aug 19, 2021
015670a
Merged
cwisniew Aug 20, 2021
072b540
remove web endpoint code
cwisniew Aug 20, 2021
7f27efd
refactor
cwisniew Aug 20, 2021
f7352e3
start of public key handshake
cwisniew Aug 22, 2021
3807a83
public key file;
cwisniew Aug 23, 2021
665fa96
fix updating of password file containing priveate keys
cwisniew Aug 24, 2021
481497a
fix public key connection
cwisniew Aug 24, 2021
5f07580
logging and formatting
cwisniew Aug 24, 2021
333a17e
formatting
cwisniew Aug 24, 2021
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
11 changes: 11 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ spotless {
include 'src/**/*.java'
exclude '**/JTextAreaAppender.java'
exclude '**/TransferableHelper.java' // Temporary until switch expression is supported.
exclude '**/MapToolInfo.java' // Temporary until supported.
exclude '**/PlayerDatabaseInfo.java' // Temporary until supported.
exclude '**/PlayerInfo.java' // Temporary until supported.
exclude '**/PlayTimeInfo.java' // Temporary until supported.
exclude '**/NoData.java' // Temporary until supported.
exclude '**/PlayTime.java' // Temporary until supported.
exclude '**/CipherUtil.java' // Temporary until supported.
}
licenseHeaderFile 'spotless.license.java'

Expand Down Expand Up @@ -395,6 +402,10 @@ dependencies {
// Noise Generator
implementation 'com.github.cwisniew:NoiseLib:1.0.0' // The most recent version, 1.0.0 is build for a later java version: major version 55 is newer than 54, the highest major version supported by this compiler



// HTTP End Point
implementation 'javax.ws.rs:javax.ws.rs-api:2.1.1'
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public void sendMessage(String id, Object channel, byte[] message) {
* Server subclasses may override this method to perform serial handshaking before the connection
* is accepted into its pool. By default, this just returns true.
*
* @param conn
* @param id
* @return true if the connection should be added to the pool
*/
public boolean handleConnectionHandshake(String id, Socket socket) {
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/net/rptools/maptool/api/ApiData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* This software Copyright by the RPTools.net development team, and
* licensed under the Affero GPL Version 3 or, at your option, any later
* version.
*
* MapTool Source Code is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public
* License * along with this source Code. If not, please visit
* <http://www.gnu.org/licenses/> and specifically the Affero license
* text at <http://www.gnu.org/licenses/agpl.html>.
*/
package net.rptools.maptool.api;

import com.google.gson.Gson;
import com.google.gson.JsonObject;

public interface ApiData {

default JsonObject asJsonObject() {
Gson gson = new Gson();
return gson.toJsonTree(this).getAsJsonObject();
}
}
26 changes: 26 additions & 0 deletions src/main/java/net/rptools/maptool/api/ApiException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* This software Copyright by the RPTools.net development team, and
* licensed under the Affero GPL Version 3 or, at your option, any later
* version.
*
* MapTool Source Code is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public
* License * along with this source Code. If not, please visit
* <http://www.gnu.org/licenses/> and specifically the Affero license
* text at <http://www.gnu.org/licenses/agpl.html>.
*/
package net.rptools.maptool.api;

public class ApiException extends Exception {

public ApiException(String message) {
super(message);
}

public ApiException(String message, Throwable cause) {
super(message, cause);
}
}
25 changes: 25 additions & 0 deletions src/main/java/net/rptools/maptool/api/maptool/MapToolApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* This software Copyright by the RPTools.net development team, and
* licensed under the Affero GPL Version 3 or, at your option, any later
* version.
*
* MapTool Source Code is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public
* License * along with this source Code. If not, please visit
* <http://www.gnu.org/licenses/> and specifically the Affero license
* text at <http://www.gnu.org/licenses/agpl.html>.
*/
package net.rptools.maptool.api.maptool;

import java.util.concurrent.CompletableFuture;
import net.rptools.maptool.api.util.ApiResult;

public class MapToolApi {

public CompletableFuture<ApiResult<MapToolInfo>> getVersion() {
return CompletableFuture.completedFuture(new ApiResult<MapToolInfo>(new MapToolInfo()));
}
}
16 changes: 16 additions & 0 deletions src/main/java/net/rptools/maptool/api/maptool/MapToolInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package net.rptools.maptool.api.maptool;

import net.rptools.maptool.api.ApiData;
import net.rptools.maptool.client.MapTool;

//@XmlRootElement
public record MapToolInfo(
String mapToolVersion,
String webEndpointVersion,
boolean developmentVersion
) implements ApiData {

public MapToolInfo() {
this(MapTool.getVersion(), "unavailable", MapTool.isDevelopment());
}
}
27 changes: 27 additions & 0 deletions src/main/java/net/rptools/maptool/api/player/PlayTimeInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package net.rptools.maptool.api.player;

import com.google.gson.JsonObject;
import java.time.DayOfWeek;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import net.rptools.maptool.api.ApiData;
import net.rptools.maptool.model.player.PlayTime;

public record PlayTimeInfo(
DayOfWeek dayOfWeek,
LocalTime startTime,
LocalTime endTime
) implements ApiData {
public PlayTimeInfo(PlayTime playTime) {
this(playTime.dayOfWeek(), playTime.startTime(), playTime.endTime());
}

@Override
public JsonObject asJsonObject() {
JsonObject json = new JsonObject();
json.addProperty("dayOfWeek", dayOfWeek.getValue());
json.addProperty("startTime", startTime.format(DateTimeFormatter.ISO_LOCAL_TIME));
json.addProperty("endTime", startTime.format(DateTimeFormatter.ISO_LOCAL_TIME));
return json;
}
}
157 changes: 157 additions & 0 deletions src/main/java/net/rptools/maptool/api/player/PlayerApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* This software Copyright by the RPTools.net development team, and
* licensed under the Affero GPL Version 3 or, at your option, any later
* version.
*
* MapTool Source Code is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public
* License * along with this source Code. If not, please visit
* <http://www.gnu.org/licenses/> and specifically the Affero license
* text at <http://www.gnu.org/licenses/agpl.html>.
*/
package net.rptools.maptool.api.player;

import java.lang.reflect.InvocationTargetException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import net.rptools.maptool.api.ApiException;
import net.rptools.maptool.api.util.ApiCall;
import net.rptools.maptool.api.util.ApiListResult;
import net.rptools.maptool.api.util.ApiResult;
import net.rptools.maptool.client.MapTool;
import net.rptools.maptool.model.player.Player;
import net.rptools.maptool.model.player.Player.Role;
import net.rptools.maptool.model.player.PlayerDatabase;
import net.rptools.maptool.model.player.PlayerDatabaseFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class PlayerApi {

private static final Logger log = LogManager.getLogger(PlayerApi.class);

public CompletableFuture<ApiResult<PlayerInfo>> getPlayer(String name) {
return new ApiCall<PlayerInfo>().runOnSwingThread(() -> getPlayerInfo(name));
}

public CompletableFuture<ApiResult<PlayerInfo>> getPlayer() {
return new ApiCall<PlayerInfo>()
.runOnSwingThread(
() -> {
Player player = MapTool.getPlayer();
return getPlayerInfo(player.getName());
});
}

public CompletableFuture<ApiListResult<PlayerInfo>> getConnectedPlayers() {
return CompletableFuture.supplyAsync(
() -> {
try {
return new ApiListResult<>(
getPlayersInfo().stream()
.filter(PlayerInfo::connected)
.collect(Collectors.toList()));
} catch (InterruptedException
| InvocationTargetException
| NoSuchAlgorithmException
| InvalidKeySpecException e) {
log.error(e);
return new ApiListResult<>(new ApiException("err.internal", e));
}
});
}

public CompletableFuture<ApiListResult<PlayerInfo>> getDatabasePlayers() {
return CompletableFuture.supplyAsync(
() -> {
try {
return new ApiListResult<>(getPlayersInfo());
} catch (InterruptedException
| InvocationTargetException
| NoSuchAlgorithmException
| InvalidKeySpecException e) {
log.error(e);
return new ApiListResult<>(new ApiException("err.internal", e));
}
});
}

public CompletableFuture<ApiResult<PlayerDatabaseInfo>> getDatabaseCapabilities() {
return CompletableFuture.supplyAsync(() -> new ApiResult<>(getPlayerDatabaseInfo()));
}

/*
public CompletableFuture<ApiResult<NoData>> disablePlayer(String playerName, String reason) {
return CompletableFuture.supplyAsync(() -> {
PlayerDatabase playerDatabase = PlayerDatabaseFactory.getCurrentPlayerDatabase();
try {
Player player = playerDatabase.getPlayer(playerName);
if (player == null) {
return CompletableFuture.completedFuture(ApiResult.NOT_FOUND);
}
playerDatabase.disablePlayer(player, reason);
return new ApiResult<NoData>();
} catch (NoSuchAlgorithmException | InvalidKeySpecException | PasswordDatabaseException e) {
return CompletableFuture.completedFuture(new ApiResult<>(new ApiException("err.internal",
e)));
}
});
}
*/

private PlayerDatabaseInfo getPlayerDatabaseInfo() {
PlayerDatabase playerDatabase = PlayerDatabaseFactory.getCurrentPlayerDatabase();
return new PlayerDatabaseInfo(
playerDatabase.supportsDisabling(),
!playerDatabase.supportsRolePasswords(),
playerDatabase.supportsAsymmetricalKeys());
}

private PlayerInfo getPlayerInfo(String name)
throws NoSuchAlgorithmException, InvalidKeySpecException, InterruptedException,
InvocationTargetException {
PlayerDatabase playerDatabase = PlayerDatabaseFactory.getCurrentPlayerDatabase();
if (!playerDatabase.isPlayerRegistered(name)) {
return null;
}
Player player = playerDatabase.getPlayer(name);
Role role = player.getRole();
boolean supportsBlocking = playerDatabase.supportsDisabling();
String blockedReason = "";
boolean blocked = false;
if (supportsBlocking) {
blockedReason = playerDatabase.getDisabledReason(player);
if (blockedReason.length() > 0) {
blocked = true;
}
}
boolean connected = false;
for (Player p : MapTool.getPlayerList()) {
if (name.equals(p.getName())) {
connected = true;
break;
}
}

return new PlayerInfo(name, role, blocked, blockedReason, connected);
}

private List<PlayerInfo> getPlayersInfo()
throws InterruptedException, InvocationTargetException, NoSuchAlgorithmException,
InvalidKeySpecException {
List<PlayerInfo> players = new ArrayList<>();
PlayerDatabase playerDatabase = PlayerDatabaseFactory.getCurrentPlayerDatabase();
for (Player p : playerDatabase.getAllPlayers()) {
players.add(getPlayerInfo(p.getName()));
}

return players;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package net.rptools.maptool.api.player;

import net.rptools.maptool.api.ApiData;

public record PlayerDatabaseInfo(boolean supportsBlocking, boolean supportsIndividualPasswords,
boolean supportsAsymmetricalKeys) implements ApiData {
}
16 changes: 16 additions & 0 deletions src/main/java/net/rptools/maptool/api/player/PlayerInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package net.rptools.maptool.api.player;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import net.rptools.maptool.api.ApiData;
import net.rptools.maptool.model.player.Player.Role;

public record PlayerInfo(
String name,
Role role,
boolean blocked,
String blockedReason,
boolean connected
) implements ApiData {

}
51 changes: 51 additions & 0 deletions src/main/java/net/rptools/maptool/api/util/ApiCall.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* This software Copyright by the RPTools.net development team, and
* licensed under the Affero GPL Version 3 or, at your option, any later
* version.
*
* MapTool Source Code is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public
* License * along with this source Code. If not, please visit
* <http://www.gnu.org/licenses/> and specifically the Affero license
* text at <http://www.gnu.org/licenses/agpl.html>.
*/
package net.rptools.maptool.api.util;

import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import javax.swing.SwingUtilities;
import net.rptools.maptool.api.ApiData;
import net.rptools.maptool.api.ApiException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class ApiCall<T extends ApiData> {

private static final Logger log = LogManager.getLogger(ApiCall.class);

public CompletableFuture<ApiResult<T>> runOnSwingThread(Callable<T> callable) {
try {
if (SwingUtilities.isEventDispatchThread()) {
return CompletableFuture.completedFuture(doCall(callable));
} else {
return CompletableFuture.supplyAsync(() -> doCall(callable));
}
} catch (Exception e) {
log.error(e);
return CompletableFuture.completedFuture(
new ApiResult<>(new ApiException("err.internal", e)));
}
}

private ApiResult<T> doCall(Callable<T> callable) {
try {
return new ApiResult<T>(callable.call());
} catch (Exception e) {
log.error(e);
return new ApiResult<>(new ApiException("err.internal", e));
}
}
}
Loading