Merge branch 'master' into External-master

This commit is contained in:
Failure 2025-01-10 15:38:18 -08:00
commit c19616a5fb
65 changed files with 282 additions and 160 deletions

View file

@ -64,6 +64,7 @@ public class AuthorizedUser {
public boolean doCredentialsMatch(String name, String password) {
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(this.hashAlgorithm);
matcher.setHashIterations(this.hashIterations);
AuthenticationToken token = new UsernamePasswordToken(name, password);
AuthenticationInfo info = new SimpleAuthenticationInfo(this.name,
ByteSource.Util.bytes(Base64.decode(this.password)),

View file

@ -18,6 +18,17 @@ import org.jboss.remoting.callback.Callback;
import org.jboss.remoting.callback.HandleCallbackException;
import org.jboss.remoting.callback.InvokerCallbackHandler;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@ -152,8 +163,8 @@ public class Session {
if (userName.length() > config.getMaxUserNameLength()) {
return "User name may not be longer than " + config.getMaxUserNameLength() + " characters";
}
if (userName.length() <= 3) {
return "User name is too short (3 characters or fewer)";
if (userName.length() <= 1) {
return "User name is too short (1 characters or fewer)";
}
if (userName.length() >= 500) {
return "User name is too long (500 characters or more)";
@ -242,6 +253,7 @@ public class Session {
// find auth user
AuthorizedUser authorizedUser = null;
if (managerFactory.configSettings().isAuthenticationActivated()) {
authorizedUser = AuthorizedUserRepository.getInstance().getByName(userName);
String errorMsg = "Wrong username or password. You must register your account first.";
@ -267,6 +279,51 @@ public class Session {
}
}
}
if (managerFactory.configSettings().isHttpAuth()) {
try {
JsonObject body = new JsonObject();
body.addProperty("token", password);
body.addProperty("username", userName);
String json = body.toString();
URL url = new URL(managerFactory.configSettings().getAuthUrl());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Content-Length", Integer.toString(json.length()));
conn.setRequestProperty("User-Agent", "Tainted-Mage/1.0");
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
os.write(json.getBytes());
os.flush();
os.close();
int responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String resp = in.readLine();
in.close();
JsonElement response = JsonParser.parseString(resp);
if (response.isJsonObject() && response.getAsJsonObject().has("success") && response.getAsJsonObject().get("success").getAsBoolean()) {
// s'all good, man
} else {
return "Failed to authenticate";
}
} else {
return "Failed to authenticate: " + Integer.toString(responseCode);
}
} catch (Exception e) {
return "Error with external authentication. Please try again later.";
}
}
// create new user instance (auth or anon)
boolean isReconnection = false;

View file

@ -69,4 +69,8 @@ public interface ConfigSettings {
List<Plugin> getDraftCubes();
List<Plugin> getDeckTypes();
boolean isHttpAuth();
String getAuthUrl();
}

View file

@ -44,6 +44,7 @@ public enum UserStatsRepository {
TableUtils.createTableIfNotExists(connectionSource, UserStats.class);
statsDao = DaoManager.createDao(connectionSource, UserStats.class);
statsDao.executeRaw("PRAGMA journal_mode=WAL;");
} catch (SQLException ex) {
Logger.getLogger(UserStatsRepository.class).error("Error creating user_stats repository - ", ex);
}

View file

@ -19,18 +19,21 @@
<xs:attribute name="serverAddress" type="xs:string" use="required"/>
<xs:attribute name="serverName" type="xs:string" use="required"/>
<xs:attribute name="port" type="xs:positiveInteger" use="required"/>
<xs:attribute name="secondaryBindPort" type="xs:integer" use="required"/>
<xs:attribute name="backlogSize" type="xs:positiveInteger" use="required"/>
<xs:attribute name="numAcceptThreads" type="xs:positiveInteger" use="required"/>
<xs:attribute name="maxPoolSize" type="xs:positiveInteger" use="required"/>
<xs:attribute name="leasePeriod" type="xs:positiveInteger" use="required"/>
<xs:attribute name="secondaryBindPort" type="xs:integer" use="required"/>
<xs:attribute name="backlogSize" type="xs:positiveInteger" use="required"/>
<xs:attribute name="numAcceptThreads" type="xs:positiveInteger" use="required"/>
<xs:attribute name="maxPoolSize" type="xs:positiveInteger" use="required"/>
<xs:attribute name="leasePeriod" type="xs:positiveInteger" use="required"/>
<xs:attribute name="maxGameThreads" type="xs:positiveInteger" use="required"/>
<xs:attribute name="maxSecondsIdle" type="xs:positiveInteger" use="required"/>
<xs:attribute name="minUserNameLength" type="xs:positiveInteger" use="required"/>
<xs:attribute name="maxUserNameLength" type="xs:positiveInteger" use="required"/>
<xs:attribute name="userNamePattern" type="xs:string" use="required"/>
<xs:attribute name="maxAiOpponents" type="xs:string" use="optional"/>
<xs:attribute name="saveGameActivated" type="xs:boolean" use="optional"/>
<xs:attribute name="minUserNameLength" type="xs:positiveInteger" use="required"/>
<xs:attribute name="maxUserNameLength" type="xs:positiveInteger" use="required"/>
<xs:attribute name="userNamePattern" type="xs:string" use="required"/>
<xs:attribute name="maxAiOpponents" type="xs:string" use="optional"/>
<xs:attribute name="saveGameActivated" type="xs:boolean" use="optional"/>
<xs:attribute name="httpAuth" type="xs:boolean" use="optional" />
<xs:attribute name="authUrl" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>

View file

@ -142,5 +142,13 @@ public class ConfigWrapper implements ConfigSettings {
public List<Plugin> getDeckTypes() {
return config.getDeckTypes().getDeckType();
}
public boolean isHttpAuth() {
return config.getServer().isHttpAuth();
}
public String getAuthUrl() {
return config.getServer().getAuthUrl();
}
}