Config changes + cleanup
This commit is contained in:
parent
f4b59cf9b3
commit
db0b173f15
@ -1,23 +0,0 @@
|
|||||||
mongo.address=158.69.26.208
|
|
||||||
mongo.port=27027
|
|
||||||
mongo.database=MineHQDev
|
|
||||||
mongo.username=
|
|
||||||
mongo.password=
|
|
||||||
|
|
||||||
redis.address=209.222.96.50
|
|
||||||
redis.port=6379
|
|
||||||
|
|
||||||
http.port=80
|
|
||||||
http.keystoreFile=
|
|
||||||
http.keystorePassword=
|
|
||||||
|
|
||||||
mandrill.apiKey=0OYtwymqJP6oqvszeJu0vQ
|
|
||||||
mandrill.fromEmail=no-reply@minehq.com
|
|
||||||
mandrill.fromName=MineHQ Network
|
|
||||||
|
|
||||||
maxMind.userId=66817
|
|
||||||
maxMind.licenseKey=8Aw9NsOUeOp7
|
|
||||||
|
|
||||||
zang.accountSid=ACf18890845596403e330944d98886440c
|
|
||||||
zang.authToken=dc70bbd1fbd8411ba133fa93813a461b
|
|
||||||
zang.fromNumber=339-337-5300
|
|
35
application.yml
Normal file
35
application.yml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
mongoUri: mongodb://158.69.26.208:27027/MineHQ
|
||||||
|
redisUri: redis://209.222.96.50:6379
|
||||||
|
|
||||||
|
http:
|
||||||
|
port: 80
|
||||||
|
keystoreFile:
|
||||||
|
keystorePassword:
|
||||||
|
|
||||||
|
disposableLoginToken:
|
||||||
|
tokenLifetimeSeconds: 300
|
||||||
|
|
||||||
|
ipHashing:
|
||||||
|
salt: J$gMsq6#!sWTK^JvB!px
|
||||||
|
|
||||||
|
userSession:
|
||||||
|
sessionExpirationTimeDays: 30
|
||||||
|
|
||||||
|
totp:
|
||||||
|
windowSize: 10
|
||||||
|
recentlyUsedPeriodSeconds: 300
|
||||||
|
ipAuthorizationDays: 5
|
||||||
|
|
||||||
|
maxMind:
|
||||||
|
userId: 66817
|
||||||
|
licenseKey: 8Aw9NsOUeOp7
|
||||||
|
|
||||||
|
mandrill:
|
||||||
|
apiKey: 0OYtwymqJP6oqvszeJu0vQ
|
||||||
|
fromEmail: no-reply@minehq.com
|
||||||
|
fromName: MineHQ Network
|
||||||
|
|
||||||
|
zang:
|
||||||
|
accountSid: ACf18890845596403e330944d98886440c
|
||||||
|
authToken: dc70bbd1fbd8411ba133fa93813a461b
|
||||||
|
fromNumber: 339-337-5300
|
@ -3,6 +3,7 @@ package net.frozenorb.apiv3;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
@ -14,6 +15,7 @@ import io.vertx.core.Vertx;
|
|||||||
class Main {
|
class Main {
|
||||||
|
|
||||||
@Autowired private APIv3 verticle;
|
@Autowired private APIv3 verticle;
|
||||||
|
@Autowired private Environment environment;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.setProperty("vertx.logger-delegate-factory-class-name", "io.vertx.core.logging.SLF4JLogDelegateFactory");
|
System.setProperty("vertx.logger-delegate-factory-class-name", "io.vertx.core.logging.SLF4JLogDelegateFactory");
|
||||||
|
@ -8,13 +8,16 @@ import com.fasterxml.jackson.annotation.PropertyAccessor;
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||||
import com.mongodb.ConnectionString;
|
import com.mongodb.ConnectionString;
|
||||||
import com.mongodb.MongoCredential;
|
|
||||||
import com.mongodb.async.client.MongoClient;
|
import com.mongodb.async.client.MongoClient;
|
||||||
import com.mongodb.async.client.MongoClientSettings;
|
import com.mongodb.async.client.MongoClientSettings;
|
||||||
import com.mongodb.async.client.MongoClients;
|
import com.mongodb.async.client.MongoClients;
|
||||||
import com.mongodb.async.client.MongoDatabase;
|
import com.mongodb.async.client.MongoDatabase;
|
||||||
import com.mongodb.client.model.IndexModel;
|
import com.mongodb.client.model.IndexModel;
|
||||||
import com.mongodb.connection.ClusterSettings;
|
import com.mongodb.connection.ClusterSettings;
|
||||||
|
import com.mongodb.connection.ConnectionPoolSettings;
|
||||||
|
import com.mongodb.connection.ServerSettings;
|
||||||
|
import com.mongodb.connection.SocketSettings;
|
||||||
|
import com.mongodb.connection.SslSettings;
|
||||||
|
|
||||||
import net.frozenorb.apiv3.serialization.jackson.InstantJsonDeserializer;
|
import net.frozenorb.apiv3.serialization.jackson.InstantJsonDeserializer;
|
||||||
import net.frozenorb.apiv3.serialization.jackson.InstantJsonSerializer;
|
import net.frozenorb.apiv3.serialization.jackson.InstantJsonSerializer;
|
||||||
@ -32,7 +35,6 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import fr.javatic.mongo.jacksonCodec.JacksonCodecProvider;
|
import fr.javatic.mongo.jacksonCodec.JacksonCodecProvider;
|
||||||
@ -42,82 +44,68 @@ import fr.javatic.mongo.jacksonCodec.ObjectMapperFactory;
|
|||||||
public class MongoConfig {
|
public class MongoConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public MongoDatabase mongoDatabase(
|
public MongoDatabase mongoDatabase(@Value("${mongoUri}") String mongoUri) {
|
||||||
@Value("${mongo.username}") String username,
|
ConnectionString connStr = new ConnectionString(mongoUri);
|
||||||
@Value("${mongo.database}") String database,
|
|
||||||
@Value("${mongo.password}") String password,
|
|
||||||
@Value("${mongo.address}") String address,
|
|
||||||
@Value("${mongo.port}") int port
|
|
||||||
) {
|
|
||||||
List<MongoCredential> credentials = ImmutableList.of();
|
|
||||||
|
|
||||||
if (!username.isEmpty()) {
|
// all of these lines except for .codecRegistry are copied from MongoClients#create(ConnectionString)
|
||||||
credentials = ImmutableList.of(
|
MongoClient mongoClient = MongoClients.create(MongoClientSettings.builder()
|
||||||
MongoCredential.createCredential(username, database, password.toCharArray())
|
.clusterSettings(ClusterSettings.builder().applyConnectionString(connStr).build())
|
||||||
);
|
.connectionPoolSettings(ConnectionPoolSettings.builder().applyConnectionString(connStr).build())
|
||||||
}
|
.serverSettings(ServerSettings.builder().build()).credentialList(connStr.getCredentialList())
|
||||||
|
.sslSettings(SslSettings.builder().applyConnectionString(connStr).build())
|
||||||
ConnectionString connectionString = new ConnectionString("mongodb://" + address + ":" + port);
|
.socketSettings(SocketSettings.builder().applyConnectionString(connStr).build())
|
||||||
|
.codecRegistry(CodecRegistries.fromProviders(ImmutableList.of(
|
||||||
MongoClient mongoClient = MongoClients.create(MongoClientSettings
|
new UuidCodecProvider(), // MHQ, fixes uuid serialization
|
||||||
.builder()
|
new ValueCodecProvider(),
|
||||||
.codecRegistry(CodecRegistries.fromProviders(ImmutableList.of(
|
new DocumentCodecProvider(),
|
||||||
new UuidCodecProvider(), // MHQ, fixes uuid serialization
|
new BsonValueCodecProvider(),
|
||||||
new ValueCodecProvider(),
|
new JacksonCodecProvider(createMongoJacksonMapper()) // Jackson codec, provides serialization/deserialization
|
||||||
new DocumentCodecProvider(),
|
)))
|
||||||
new BsonValueCodecProvider(),
|
.build()
|
||||||
new JacksonCodecProvider(createMongoJacksonMapper()) // Jackson codec, provides serialization/deserialization
|
|
||||||
)))
|
|
||||||
.credentialList(credentials)
|
|
||||||
.clusterSettings(ClusterSettings.builder()
|
|
||||||
.applyConnectionString(connectionString)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
MongoDatabase db = mongoClient.getDatabase(database);
|
MongoDatabase database = mongoClient.getDatabase(connStr.getDatabase());
|
||||||
|
|
||||||
db.getCollection("auditLog").createIndexes(ImmutableList.of(
|
database.getCollection("auditLog").createIndexes(ImmutableList.of(
|
||||||
new IndexModel(new Document("user", 1)),
|
new IndexModel(new Document("user", 1)),
|
||||||
new IndexModel(new Document("performedAt", 1)),
|
new IndexModel(new Document("performedAt", 1)),
|
||||||
new IndexModel(new Document("type", 1))
|
new IndexModel(new Document("type", 1))
|
||||||
), (a, b) -> {});
|
), (a, b) -> {});
|
||||||
db.getCollection("grants").createIndexes(ImmutableList.of(
|
database.getCollection("grants").createIndexes(ImmutableList.of(
|
||||||
new IndexModel(new Document("user", 1)),
|
new IndexModel(new Document("user", 1)),
|
||||||
new IndexModel(new Document("rank", 1)),
|
new IndexModel(new Document("rank", 1)),
|
||||||
new IndexModel(new Document("addedAt", 1))
|
new IndexModel(new Document("addedAt", 1))
|
||||||
), (a, b) -> {});
|
), (a, b) -> {});
|
||||||
db.getCollection("ipLog").createIndexes(ImmutableList.of(
|
database.getCollection("ipLog").createIndexes(ImmutableList.of(
|
||||||
new IndexModel(new Document("user", 1)),
|
new IndexModel(new Document("user", 1)),
|
||||||
new IndexModel(new Document("user", 1).append("userIp", 1)),
|
new IndexModel(new Document("user", 1).append("userIp", 1)),
|
||||||
new IndexModel(new Document("hashedUserIp", 1))
|
new IndexModel(new Document("hashedUserIp", 1))
|
||||||
), (a, b) -> {});
|
), (a, b) -> {});
|
||||||
db.getCollection("ipBans").createIndexes(ImmutableList.of(
|
database.getCollection("ipBans").createIndexes(ImmutableList.of(
|
||||||
new IndexModel(new Document("userIp", 1))
|
new IndexModel(new Document("userIp", 1))
|
||||||
), (a, b) -> {});
|
), (a, b) -> {});
|
||||||
db.getCollection("ipIntel").createIndexes(ImmutableList.of(
|
database.getCollection("ipIntel").createIndexes(ImmutableList.of(
|
||||||
new IndexModel(new Document("hashedIp", 1)),
|
new IndexModel(new Document("hashedIp", 1)),
|
||||||
new IndexModel(new Document("location", "2dsphere"))
|
new IndexModel(new Document("location", "2dsphere"))
|
||||||
), (a, b) -> {});
|
), (a, b) -> {});
|
||||||
db.getCollection("punishments").createIndexes(ImmutableList.of(
|
database.getCollection("punishments").createIndexes(ImmutableList.of(
|
||||||
new IndexModel(new Document("user", 1)),
|
new IndexModel(new Document("user", 1)),
|
||||||
new IndexModel(new Document("type", 1)),
|
new IndexModel(new Document("type", 1)),
|
||||||
new IndexModel(new Document("addedAt", 1)),
|
new IndexModel(new Document("addedAt", 1)),
|
||||||
new IndexModel(new Document("addedBy", 1)),
|
new IndexModel(new Document("addedBy", 1)),
|
||||||
new IndexModel(new Document("linkedIpBanId", 1))
|
new IndexModel(new Document("linkedIpBanId", 1))
|
||||||
), (a, b) -> {});
|
), (a, b) -> {});
|
||||||
db.getCollection("users").createIndexes(ImmutableList.of(
|
database.getCollection("users").createIndexes(ImmutableList.of(
|
||||||
new IndexModel(new Document("lastUsername", 1)),
|
new IndexModel(new Document("lastUsername", 1)),
|
||||||
new IndexModel(new Document("lastUsernameLower", 1)),
|
new IndexModel(new Document("lastUsernameLower", 1)),
|
||||||
new IndexModel(new Document("emailToken", 1)),
|
new IndexModel(new Document("emailToken", 1)),
|
||||||
new IndexModel(new Document("totpSecret", 1))
|
new IndexModel(new Document("totpSecret", 1))
|
||||||
), (a, b) -> {});
|
), (a, b) -> {});
|
||||||
db.getCollection("userMeta").createIndexes(ImmutableList.of(
|
database.getCollection("userMeta").createIndexes(ImmutableList.of(
|
||||||
new IndexModel(new Document("user", 1).append("serverGroup", 1))
|
new IndexModel(new Document("user", 1).append("serverGroup", 1))
|
||||||
), (a, b) -> {});
|
), (a, b) -> {});
|
||||||
|
|
||||||
return db;
|
return database;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectMapper createMongoJacksonMapper() {
|
private ObjectMapper createMongoJacksonMapper() {
|
||||||
|
@ -4,6 +4,8 @@ import org.springframework.beans.factory.annotation.Value;
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
import io.vertx.core.Vertx;
|
import io.vertx.core.Vertx;
|
||||||
import io.vertx.redis.RedisClient;
|
import io.vertx.redis.RedisClient;
|
||||||
import io.vertx.redis.RedisOptions;
|
import io.vertx.redis.RedisOptions;
|
||||||
@ -17,11 +19,10 @@ public class RedisConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public RedisOptions redisOptions(
|
public RedisOptions redisOptions(@Value("${redisUri}") URI redisUri) {
|
||||||
@Value("${redis.address}") String address,
|
return new RedisOptions()
|
||||||
@Value("${redis.port}") int port
|
.setAddress(redisUri.getHost())
|
||||||
) {
|
.setPort(redisUri.getPort());
|
||||||
return new RedisOptions().setAddress(address).setPort(port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -5,10 +5,10 @@ import com.mongodb.async.SingleResultCallback;
|
|||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import io.vertx.redis.RedisClient;
|
import io.vertx.redis.RedisClient;
|
||||||
|
|
||||||
@ -16,6 +16,7 @@ import io.vertx.redis.RedisClient;
|
|||||||
public final class RedisDisposableLoginTokenService implements DisposableLoginTokenService {
|
public final class RedisDisposableLoginTokenService implements DisposableLoginTokenService {
|
||||||
|
|
||||||
@Autowired private RedisClient redisClient;
|
@Autowired private RedisClient redisClient;
|
||||||
|
@Value("${disposableLoginToken.tokenLifetimeSeconds}") private int tokenLifetimeSeconds;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void attemptLogin(String token, String userIp, SingleResultCallback<User> callback) {
|
public void attemptLogin(String token, String userIp, SingleResultCallback<User> callback) {
|
||||||
@ -56,7 +57,7 @@ public final class RedisDisposableLoginTokenService implements DisposableLoginTo
|
|||||||
public void createToken(UUID user, String userIp, SingleResultCallback<String> callback) {
|
public void createToken(UUID user, String userIp, SingleResultCallback<String> callback) {
|
||||||
String token = UUID.randomUUID().toString().replaceAll("-", "");
|
String token = UUID.randomUUID().toString().replaceAll("-", "");
|
||||||
|
|
||||||
redisClient.setex("apiv3:disposableLoginTokens:" + userIp + ":" + token, TimeUnit.MINUTES.toSeconds(5), user.toString(), (result) -> {
|
redisClient.setex("apiv3:disposableLoginTokens:" + userIp + ":" + token, tokenLifetimeSeconds, user.toString(), (result) -> {
|
||||||
if (result.succeeded()) {
|
if (result.succeeded()) {
|
||||||
callback.onResult(token, null);
|
callback.onResult(token, null);
|
||||||
} else {
|
} else {
|
||||||
|
@ -47,7 +47,6 @@ import java.util.Random;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import fr.javatic.mongo.jacksonCodec.Entity;
|
import fr.javatic.mongo.jacksonCodec.Entity;
|
||||||
import fr.javatic.mongo.jacksonCodec.objectId.Id;
|
import fr.javatic.mongo.jacksonCodec.objectId.Id;
|
||||||
@ -585,7 +584,7 @@ public final class User {
|
|||||||
Future<Void> markPreAuthFuture = Future.future();
|
Future<Void> markPreAuthFuture = Future.future();
|
||||||
Future<Void> markRecentlyUsedFuture = Future.future();
|
Future<Void> markRecentlyUsedFuture = Future.future();
|
||||||
|
|
||||||
totpService.markPreAuthorized(this, ip, 3, TimeUnit.DAYS, new MongoToVertxCallback<>(markPreAuthFuture));
|
totpService.markPreAuthorized(this, ip, new MongoToVertxCallback<>(markPreAuthFuture));
|
||||||
totpService.markRecentlyUsed(this, code, new MongoToVertxCallback<>(markRecentlyUsedFuture));
|
totpService.markRecentlyUsed(this, code, new MongoToVertxCallback<>(markRecentlyUsedFuture));
|
||||||
|
|
||||||
CompositeFuture.all(markPreAuthFuture, markRecentlyUsedFuture).setHandler((result) -> {
|
CompositeFuture.all(markPreAuthFuture, markRecentlyUsedFuture).setHandler((result) -> {
|
||||||
|
@ -8,17 +8,34 @@ import net.frozenorb.apiv3.model.User;
|
|||||||
import net.frozenorb.apiv3.util.IpUtils;
|
import net.frozenorb.apiv3.util.IpUtils;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
import io.vertx.redis.RedisClient;
|
import io.vertx.redis.RedisClient;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public final class RedisTotpService implements TotpService {
|
public final class RedisTotpService implements TotpService {
|
||||||
|
|
||||||
private final GoogleAuthenticator googleAuthenticator = new GoogleAuthenticator(new GoogleAuthenticatorConfig.GoogleAuthenticatorConfigBuilder().setWindowSize(10).build());
|
|
||||||
@Autowired private RedisClient redisClient;
|
@Autowired private RedisClient redisClient;
|
||||||
|
@Value("${totp.windowSize}") int windowSize;
|
||||||
|
@Value("${totp.recentlyUsedPeriodSeconds}") int recentlyUsedPeriodSeconds;
|
||||||
|
@Value("${totp.ipAuthorizationDays}") int ipAuthorizationDays;
|
||||||
|
private GoogleAuthenticator googleAuthenticator;
|
||||||
|
|
||||||
|
// has to be ran after construction (or else windowSize won't be defined when we go to
|
||||||
|
// create this object)
|
||||||
|
@PostConstruct
|
||||||
|
private void setupGoogleAuth() {
|
||||||
|
googleAuthenticator = new GoogleAuthenticator(
|
||||||
|
new GoogleAuthenticatorConfig.GoogleAuthenticatorConfigBuilder()
|
||||||
|
.setWindowSize(windowSize)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean authorizeUser(String secret, int code) {
|
public boolean authorizeUser(String secret, int code) {
|
||||||
@ -42,7 +59,7 @@ public final class RedisTotpService implements TotpService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markPreAuthorized(User user, String ip, long duration, TimeUnit unit, SingleResultCallback<Void> callback) {
|
public void markPreAuthorized(User user, String ip, SingleResultCallback<Void> callback) {
|
||||||
if (!IpUtils.isValidIp(ip)) {
|
if (!IpUtils.isValidIp(ip)) {
|
||||||
callback.onResult(null, null);
|
callback.onResult(null, null);
|
||||||
return;
|
return;
|
||||||
@ -50,7 +67,7 @@ public final class RedisTotpService implements TotpService {
|
|||||||
|
|
||||||
String key = user.getId() + ":preAuthorizedIp:" + ip.toLowerCase();
|
String key = user.getId() + ":preAuthorizedIp:" + ip.toLowerCase();
|
||||||
|
|
||||||
redisClient.setex(key, unit.toSeconds(duration), "", (result) -> {
|
redisClient.setex(key, TimeUnit.DAYS.toSeconds(ipAuthorizationDays), "", (result) -> {
|
||||||
if (result.succeeded()) {
|
if (result.succeeded()) {
|
||||||
callback.onResult(null, null);
|
callback.onResult(null, null);
|
||||||
} else {
|
} else {
|
||||||
@ -74,7 +91,7 @@ public final class RedisTotpService implements TotpService {
|
|||||||
public void markRecentlyUsed(User user, int code, SingleResultCallback<Void> callback) {
|
public void markRecentlyUsed(User user, int code, SingleResultCallback<Void> callback) {
|
||||||
String key = user.getId() + ":recentTotpCodes:" + code;
|
String key = user.getId() + ":recentTotpCodes:" + code;
|
||||||
|
|
||||||
redisClient.setex(key, TimeUnit.MINUTES.toSeconds(5), "", (result) -> {
|
redisClient.setex(key, recentlyUsedPeriodSeconds, "", (result) -> {
|
||||||
if (result.succeeded()) {
|
if (result.succeeded()) {
|
||||||
callback.onResult(null, null);
|
callback.onResult(null, null);
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,8 +6,6 @@ import net.frozenorb.apiv3.model.User;
|
|||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public interface TotpService {
|
public interface TotpService {
|
||||||
|
|
||||||
@ -15,7 +13,7 @@ public interface TotpService {
|
|||||||
|
|
||||||
void isPreAuthorized(User user, String ip, SingleResultCallback<Boolean> callback);
|
void isPreAuthorized(User user, String ip, SingleResultCallback<Boolean> callback);
|
||||||
|
|
||||||
void markPreAuthorized(User user, String ip, long duration, TimeUnit unit, SingleResultCallback<Void> callback);
|
void markPreAuthorized(User user, String ip, SingleResultCallback<Void> callback);
|
||||||
|
|
||||||
void wasRecentlyUsed(User user, int code, SingleResultCallback<Boolean> callback);
|
void wasRecentlyUsed(User user, int code, SingleResultCallback<Boolean> callback);
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package net.frozenorb.apiv3.usersession;
|
|||||||
import com.mongodb.async.SingleResultCallback;
|
import com.mongodb.async.SingleResultCallback;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -15,6 +16,7 @@ import io.vertx.redis.RedisClient;
|
|||||||
public final class RedisUserSessionService implements UserSessionService {
|
public final class RedisUserSessionService implements UserSessionService {
|
||||||
|
|
||||||
@Autowired private RedisClient redisClient;
|
@Autowired private RedisClient redisClient;
|
||||||
|
@Value("${userSession.sessionExpirationTimeDays}") private int sessionExpirationTimeDays;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sessionExists(String userIp, String userSession, SingleResultCallback<Boolean> callback) {
|
public void sessionExists(String userIp, String userSession, SingleResultCallback<Boolean> callback) {
|
||||||
@ -37,7 +39,7 @@ public final class RedisUserSessionService implements UserSessionService {
|
|||||||
String userSession = UUID.randomUUID().toString().replaceAll("-", "");
|
String userSession = UUID.randomUUID().toString().replaceAll("-", "");
|
||||||
String key = "apiv3:sessions:" + userIp + ":" + userSession;
|
String key = "apiv3:sessions:" + userIp + ":" + userSession;
|
||||||
|
|
||||||
redisClient.setex(key, TimeUnit.DAYS.toSeconds(30), "", (result) -> {
|
redisClient.setex(key, TimeUnit.DAYS.toSeconds(sessionExpirationTimeDays), "", (result) -> {
|
||||||
if (result.succeeded()) {
|
if (result.succeeded()) {
|
||||||
redisClient.sadd("apiv3:sessions:" + user, key, (result2) -> {
|
redisClient.sadd("apiv3:sessions:" + user, key, (result2) -> {
|
||||||
if (result2.succeeded()) {
|
if (result2.succeeded()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user