Commit c98c2534 authored by Tobias Assmann's avatar Tobias Assmann
Browse files

session starting done, add session timing params to config, start working on tctoken function now

parent 88352731
...@@ -15,7 +15,7 @@ import javax.json.bind.annotation.JsonbProperty; ...@@ -15,7 +15,7 @@ import javax.json.bind.annotation.JsonbProperty;
* *
* @author Neil Crossley * @author Neil Crossley
*/ */
public class InitProcessRequest { public class InitRequest {
@JsonbProperty("sig-alg") @JsonbProperty("sig-alg")
public String signatureAlgorithm; public String signatureAlgorithm;
......
...@@ -15,7 +15,7 @@ import javax.json.bind.annotation.JsonbProperty; ...@@ -15,7 +15,7 @@ import javax.json.bind.annotation.JsonbProperty;
* *
* @author Neil Crossley * @author Neil Crossley
*/ */
public class InitProcessResponse { public class InitResponse {
@JsonbProperty("tc-token-url") @JsonbProperty("tc-token-url")
public String tcTokenUrl; public String tcTokenUrl;
......
...@@ -9,35 +9,41 @@ ...@@ -9,35 +9,41 @@
***************************************************************************/ ***************************************************************************/
package reqesidta.ssa.api; package reqesidta.ssa.api;
import java.util.Optional;
import javax.inject.Inject; import javax.inject.Inject;
import javax.json.bind.Jsonb; import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder; import javax.json.bind.JsonbBuilder;
import javax.json.bind.JsonbConfig; import javax.json.bind.JsonbConfig;
import javax.json.bind.config.BinaryDataStrategy; import javax.json.bind.config.BinaryDataStrategy;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST; import javax.ws.rs.POST;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import reqesidta.ssa.sa.CertificateAuthorityClient; import reqesidta.ssa.sa.CertificateAuthorityClient;
import reqesidta.ssa.server.config.SSAConfig; import reqesidta.ssa.server.config.SSAConfig;
import reqesidta.ssa.session.SessionStore; import reqesidta.ssa.session.SessionStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reqesidta.ssa.session.Session;
/** /**
* *
* @author Neil Crossley * @author Neil Crossley, Tobias Assmann
*/ */
@Path("/") @Path("/")
public class SsaService { public class SsaService {
Jsonb jsonb; private static final Logger log = LoggerFactory.getLogger(SsaService.class);
@Inject SSAConfig config; private Jsonb jsonb;
@Inject private SSAConfig config;
@Inject CertificateAuthorityClient caClient; @Inject private CertificateAuthorityClient caClient;
@Inject private SessionStore sessionStore;
@Inject SessionStore sessionStore;
public SsaService() { public SsaService() {
JsonbConfig config = new JsonbConfig() JsonbConfig config = new JsonbConfig()
...@@ -47,27 +53,48 @@ public class SsaService { ...@@ -47,27 +53,48 @@ public class SsaService {
} }
@POST @POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/init") @Path("/init")
public Response init(String json) { public Response init(String reqAsJson) {
var req = jsonb.fromJson(json, InitProcessRequest.class); log.info("got request:"+reqAsJson);
InitProcessResponse response = new InitProcessResponse(); var req = jsonb.fromJson(reqAsJson, InitRequest.class);
response.tcTokenUrl = "123456" + req.signatureAlgorithm; var session = sessionStore.getNewSession();
session.set(Session.KEY_SIGNATURE_ALGORITHM, req.signatureAlgorithm);
String jsonString = jsonb.toJson(response); session.set(Session.KEY_DOCUMENT_HASH, req.documentHash);
InitResponse response = new InitResponse();
response.tcTokenUrl = "/tctoken/" + session.getId();
String respAsJson = jsonb.toJson(response);
log.info("send response:"+respAsJson);
return Response.ok(respAsJson).build();
}
return Response.ok(jsonString).build(); @GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/tctoken/{sessionId}")
public Response tcToken(@PathParam("sessionId") String sessionId) {
log.info("got sessionId:"+sessionId);
Optional<Session> session = sessionStore.getSession(sessionId);
if (session.isEmpty()) {
throw new NotFoundException();
}
//InitResponse response = new InitResponse();
//response.tcTokenUrl = "/createtoken/" + session.getId();
//String respAsJson = jsonb.toJson(response);
return Response.ok("{foo:bar}").build();
} }
@POST @POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/cert") @Path("/cert")
public Response certs(CertificateRequest req) { public Response certs(CertificateRequest req) {
InitProcessResponse response = new InitProcessResponse(); InitResponse response = new InitResponse();
response.tcTokenUrl = "123456"; response.tcTokenUrl = "123456";
String jsonString = jsonb.toJson(response); String jsonString = jsonb.toJson(response);
...@@ -79,9 +106,9 @@ public class SsaService { ...@@ -79,9 +106,9 @@ public class SsaService {
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/sign") @Path("/sign")
public Response sign(InitProcessRequest req) { public Response sign(InitRequest req) {
InitProcessResponse response = new InitProcessResponse(); InitResponse response = new InitResponse();
response.tcTokenUrl = "123456"; response.tcTokenUrl = "123456";
String jsonString = jsonb.toJson(response); String jsonString = jsonb.toJson(response);
......
...@@ -28,28 +28,28 @@ import org.slf4j.LoggerFactory; ...@@ -28,28 +28,28 @@ import org.slf4j.LoggerFactory;
@ApplicationScoped @ApplicationScoped
public class ConfigLoader { public class ConfigLoader {
private static final Logger LOG = LoggerFactory.getLogger(ConfigLoader.class); private static final Logger log = LoggerFactory.getLogger(ConfigLoader.class);
private final SSAConfig configBean; private final SSAConfig configBean;
public ConfigLoader() throws IOException, URISyntaxException, GeneralSecurityException {
// load config from $HOME/ssa-server.conf and merge with bundled reference.conf
String homeDir = System.getProperty("user.home");
File path = new File(homeDir, "ssa-server.conf");
// set property to load external file
if (path.exists()) {
LOG.debug("Loading config {}", path.getAbsolutePath());
System.setProperty("config.url", path.toURI().toString());
}
ConfigFactory.invalidateCaches();
Config rawCfg = ConfigFactory.load(); public ConfigLoader() throws IOException, URISyntaxException, GeneralSecurityException {
// load config from $HOME/ssa-server.conf and merge with bundled reference.conf
String homeDir = System.getProperty("user.home");
File path = new File(homeDir, "ssa-server.conf");
// set property to load external file
if (path.exists()) {
log.debug("Loading config {}", path.getAbsolutePath());
System.setProperty("config.url", path.toURI().toString());
}
ConfigFactory.invalidateCaches();
this.configBean = ConfigBeanFactory.create(rawCfg.getConfig("ssa-config"), SSAConfig.class); Config rawCfg = ConfigFactory.load();
}
@Produces this.configBean = ConfigBeanFactory.create(rawCfg.getConfig("ssa-config"), SSAConfig.class);
public SSAConfig getConfig() { }
return this.configBean;
} @Produces
public SSAConfig getConfig() {
return this.configBean;
}
} }
...@@ -15,17 +15,35 @@ package reqesidta.ssa.server.config; ...@@ -15,17 +15,35 @@ package reqesidta.ssa.server.config;
*/ */
public class SSAConfig { public class SSAConfig {
private int testInt; private int sessionMaxAge;
private int sessionCheckAgeInterval;
// private String eidBaseUrl;
private CertificateAuthorityConfig caConfig; private CertificateAuthorityConfig caConfig;
public int getTestInt() { public int getSessionMaxAge() {
return testInt; return sessionMaxAge;
} }
public void setTestInt(int testInt) { public void setSessionMaxAge(int sessionMaxAge) {
this.testInt = testInt; this.sessionMaxAge = sessionMaxAge;
} }
public int getSessionCheckAgeInterval() {
return sessionCheckAgeInterval;
}
public void setSessionCheckAgeInterval(int sessionCheckAgeInterval) {
this.sessionCheckAgeInterval = sessionCheckAgeInterval;
}
// public String getEidBaseUrl() {
// return this.eidBaseUrl;
// }
//
// public void setEidBaseUrl(String eidBaseUrl) {
// this.eidBaseUrl = eidBaseUrl;
// }
public CertificateAuthorityConfig getCaConfig() { public CertificateAuthorityConfig getCaConfig() {
return caConfig; return caConfig;
} }
......
package reqesidta.ssa.session;
import java.time.Instant;
import java.util.HashMap;
import java.util.Optional;
/**
* @author Tobias Assmann <tobias.assmann@ecsec.de>
*/
public class Session {
private final String ID;
private Instant lastAccess = Instant.now();
private final HashMap<String, Object> map;
public final static String KEY_SIGNATURE_ALGORITHM = "sig-alg";
public final static String KEY_DOCUMENT_HASH = "doc-hash";
Session(String ID) {
this.ID = ID;
this.map = new HashMap<>();
}
Instant getLastAccess() {
return lastAccess;
}
public String getId() {
lastAccess = Instant.now();
return this.ID;
}
public void set(String key, Object value) {
lastAccess = Instant.now();
this.map.put(key, value);
}
public Optional<Object> get(String key) {
lastAccess = Instant.now();
return Optional.ofNullable(this.map.get(key));
}
// public <T> Optional<T> get(String key, Class<T> type) {
// lastAccess = Instant.now();
// Object get = this.map.get(key);
//
// if (get != null && get.getClass().isAssignableFrom(type)) {
// return Optional.of(type.cast(get));
// }
//
// return Optional.empty();
// }
}
...@@ -10,28 +10,28 @@ import java.util.UUID; ...@@ -10,28 +10,28 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentNavigableMap; import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListMap;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import org.jboss.logging.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* Taken from remote_eac branch of Renè
* @author Tobias Assmann <tobias.assmann@ecsec.de> * @author Tobias Assmann <tobias.assmann@ecsec.de>
*/ */
public class SessionStore { public class SessionStore {
private final static Logger LOG = Logger.getLogger(SessionStore.class); private static final Logger log = LoggerFactory.getLogger(SessionStore.class);
private final Duration maxAge; private final Duration maxAge;
private final Duration checkAgeIntervall; private final Duration checkAgeInterval;
private final Timer sessionLifeTime = new Timer("SessionExpireChecker", true); private final Timer sessionLifeTime = new Timer("SessionExpireChecker", true);
private final ConcurrentNavigableMap<String, Session> storage; private final ConcurrentNavigableMap<String, Session> storage;
public SessionStore(Duration timeout) { public SessionStore(Duration timeout, Duration checkAgeInterval) {
this.storage = new ConcurrentSkipListMap<>(); this.storage = new ConcurrentSkipListMap<>();
this.maxAge = timeout; this.maxAge = timeout;
this.checkAgeIntervall = Duration.ofMinutes(30); this.checkAgeInterval = checkAgeInterval;
LOG.debug("Setting up SessionStore ... starting Timer 'SessionExpireChecker'"); log.debug("Setting up SessionStore ... starting Timer 'SessionExpireChecker'");
this.startTimer(); this.startTimer();
} }
...@@ -64,7 +64,7 @@ public class SessionStore { ...@@ -64,7 +64,7 @@ public class SessionStore {
public void run() { public void run() {
removeExpired(); removeExpired();
} }
}, 0, checkAgeIntervall.toMillis()); }, 0, checkAgeInterval.toMillis());
} }
private void stopTimer() { private void stopTimer() {
......
...@@ -3,19 +3,24 @@ package reqesidta.ssa.session; ...@@ -3,19 +3,24 @@ package reqesidta.ssa.session;
import java.time.Duration; import java.time.Duration;
import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces; import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import reqesidta.ssa.server.config.SSAConfig;
/** /**
* *
* Taken from remote_eac branch of Renè
* @author tobias assmann * @author tobias assmann
*/ */
@ApplicationScoped @ApplicationScoped
public class SessionStoreProvider { public class SessionStoreProvider {
private final SessionStore store; private SessionStore store;
public SessionStoreProvider() { @Inject
this.store = new SessionStore(Duration.ofHours(1)); public SessionStoreProvider(SSAConfig config) {
this.store = new SessionStore(
Duration.ofMinutes((long)config.getSessionMaxAge()),
Duration.ofMinutes((long)config.getSessionCheckAgeInterval())
);
} }
@Produces @Produces
......
ssa-config { ssa-config {
test-int: 1, sessionMaxAge: 60,
ca-config: { sessionCheckAgeInterval: 30,
ca-config: {
caName: 'dummy-caName', caName: 'dummy-caName',
cmpAlias: 'dummy-cmp-alias', cmpAlias: 'dummy-cmp-alias',
cmpPassword: 'dummy-cmp-password', cmpPassword: 'dummy-cmp-password',
baseUrl: 'dummy-baseUrl', baseUrl: 'dummy-baseUrl',
certUserCn: 'dummy-certUserCn', certUserCn: 'dummy-certUserCn',
certPrefixCn: 'dummy-certPrefixCn' certPrefixCn: 'dummy-certPrefixCn'
} }
} }
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment