From 491e5cf812c0a5d3727e4e25e39032c15bb236ac Mon Sep 17 00:00:00 2001 From: Erich Bremer Date: Tue, 7 Mar 2023 12:05:03 -0500 Subject: [PATCH 1/4] set next version 0.1.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 272a0617..e91eef22 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.ebremer Halcyon - 0.0.0 + 0.1.0 jar Halcyon A whole slide image annotation, management, and visualization system From 724424e04cfaf6a581e56a2450386ac2e5e0298d Mon Sep 17 00:00:00 2001 From: Erich Bremer Date: Wed, 8 Mar 2023 17:03:17 -0500 Subject: [PATCH 2/4] fix X2OA progs --- dependency-reduced-pom.xml | 72 +++++++++---------- .../ebremer/halcyon/converters/Engine.java | 24 +++++-- .../halcyon/converters/HeatMap2OA.java | 10 +-- .../com/ebremer/halcyon/converters/NS2OA.java | 2 +- 4 files changed, 59 insertions(+), 49 deletions(-) diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index 6b84da0d..1965c286 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -10,7 +10,7 @@ com.ebremer Halcyon Halcyon - 0.0.0 + 0.1.0 A whole slide image annotation, management, and visualization system github @@ -342,7 +342,6 @@ maven-shade-plugin - 3.2.4 package @@ -368,43 +367,9 @@ com.ebremer.halcyon.converters.NS2OA - true - true - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - org.springframework.boot - spring-boot-maven-plugin - 2.6.13 - compile - - - - true - true - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - @@ -455,6 +420,7 @@ maven-shade-plugin + 3.2.4 package @@ -480,9 +446,43 @@ com.ebremer.halcyon.converters.Ingest + true + true + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.6.13 + compile + + + + true + true + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + diff --git a/src/main/java/com/ebremer/halcyon/converters/Engine.java b/src/main/java/com/ebremer/halcyon/converters/Engine.java index b6529ca9..f924cf4d 100644 --- a/src/main/java/com/ebremer/halcyon/converters/Engine.java +++ b/src/main/java/com/ebremer/halcyon/converters/Engine.java @@ -40,6 +40,7 @@ import org.apache.jena.rdf.model.Property; import org.apache.jena.rdf.model.Resource; import org.apache.jena.riot.Lang; +import org.apache.jena.riot.RDFDataMgr; import org.apache.jena.riot.RDFParserBuilder; import org.apache.jena.riot.RDFWriter; import org.apache.jena.riot.RIOT; @@ -239,7 +240,7 @@ public void HilbertPhase(BeakWriter bw) { list.forEach(f->{ if (f.isDone()) { try { - System.out.println("Adding : "+(engine.getQueue().size()+engine.getActiveCount())); + //System.out.println("Adding : "+(engine.getQueue().size()+engine.getActiveCount())); bw.Add(f.get()); list.remove(f); } catch (InterruptedException ex) { @@ -428,7 +429,7 @@ public static Model getMeta(Model m, Resource r) { """ construct where { ?roc - a hal:HalcyonROCrate; + a so:Dataset; hal:hasCreateAction ?ca; ?rocp ?roco . ?ca @@ -437,13 +438,15 @@ public static Model getMeta(Model m, Resource r) { } """, Standard.getStandardPrefixes()); pss.setIri("newroc", r.getURI()); - //System.out.println("================== META 1 ==============================="); - //System.out.println(pss.toString()); + pss.setNsPrefix("hal", HAL.NS); + pss.setNsPrefix("so", SchemaDO.NS); + System.out.println("================== META 1 ==============================="); + System.out.println(pss.toString()); QueryExecution qe = QueryExecutionFactory.create(pss.toString(),m); Model k = qe.execConstruct(); - //System.out.println("================== META 1 dump ==============================="); - //RDFDataMgr.write(System.out, k, Lang.TURTLE); - //System.out.println("================== META 1 dump end ==============================="); + System.out.println("================== META 1 dump ==============================="); + RDFDataMgr.write(System.out, k, Lang.TURTLE); + System.out.println("================== META 1 dump end ==============================="); UpdateRequest update = UpdateFactory.create(); pss = new ParameterizedSparqlString( """ @@ -471,11 +474,18 @@ public static Model getMeta(Model m, Resource r) { } """, Standard.getStandardPrefixes()); pss.setIri("newroc", r.getURI()); + pss.setNsPrefix("hal", HAL.NS); + pss.setNsPrefix("so", SchemaDO.NS); update.add(pss.toString()); pss = new ParameterizedSparqlString("delete where {?roc a hal:HalcyonROCrate}", Standard.getStandardPrefixes()); pss.setIri("newroc", r.getURI()); + pss.setNsPrefix("hal", HAL.NS); + pss.setNsPrefix("so", SchemaDO.NS); update.add(pss.toString()); UpdateAction.execute(update, k); + System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + RDFDataMgr.write(System.out, k, Lang.TURTLE); + System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); return k; } diff --git a/src/main/java/com/ebremer/halcyon/converters/HeatMap2OA.java b/src/main/java/com/ebremer/halcyon/converters/HeatMap2OA.java index 225ae848..5f4dc56a 100644 --- a/src/main/java/com/ebremer/halcyon/converters/HeatMap2OA.java +++ b/src/main/java/com/ebremer/halcyon/converters/HeatMap2OA.java @@ -196,13 +196,13 @@ public void AddPolygons(Model m) { //body.addProperty(HAL.assertedClass, classuri) Float yay = (Float)p.neovalue; int clazz = yay.intValue(); - Resource blah = m.createResource("urn:gmm:"+clazz); + //Resource blah = m.createResource("urn:gmm:"+clazz); //Resource blah = m.createResource("urn:kmeans:"+clazz); - //body.addProperty(HAL.assertedClass, classuri) - body.addProperty(HAL.assertedClass, blah) + body.addProperty(HAL.assertedClass, classuri) + //body.addProperty(HAL.assertedClass, blah) .addProperty(RDF.type, HAL.ProbabilityBody) - //.addLiteral(HAL.hasCertainty, (Float) p.neovalue); - .addLiteral(HAL.hasCertainty, (Float) 1.0f); + .addLiteral(HAL.hasCertainty, (Float) p.neovalue); + //.addLiteral(HAL.hasCertainty, (Float) 1.0f); }); } catch (IOException ex) { Logger.getLogger(HeatMap2OA.class.getName()).log(Level.SEVERE, null, ex); diff --git a/src/main/java/com/ebremer/halcyon/converters/NS2OA.java b/src/main/java/com/ebremer/halcyon/converters/NS2OA.java index d936d36d..2fa3c674 100644 --- a/src/main/java/com/ebremer/halcyon/converters/NS2OA.java +++ b/src/main/java/com/ebremer/halcyon/converters/NS2OA.java @@ -132,7 +132,7 @@ class FileProcessor implements Callable { so:license ; so:name "cnn-nuclear-segmentations-2019"; hal:hasCreateAction ; - a hal:HalcyonROCrate; + a so:Dataset, hal:HalcyonROCrate; so:publisher , . a so:CreateAction; From d5580f6e8ff172614b485dce3c134dead8feb915 Mon Sep 17 00:00:00 2001 From: Erich Bremer Date: Sun, 12 Mar 2023 19:29:12 -0400 Subject: [PATCH 3/4] Add user-security access to SPARQL endpoint with JWT Implement Shiro classes to support JWT --- pom.xml | 119 ++++++++++++-- .../com/ebremer/halcyon/FL/FLPoolFactory.java | 2 - .../com/ebremer/halcyon/HalcyonDefaults.java | 13 -- .../com/ebremer/halcyon/HalcyonSettings.java | 13 +- .../ebremer/halcyon/converters/Ingest.java | 4 +- .../halcyon/datum/AddParamsToHeader.java | 63 ++++++++ .../datum/CustomShiroConfigurator.java | 31 ++++ .../com/ebremer/halcyon/datum/DataCore.java | 35 +---- .../com/ebremer/halcyon/datum/HalSec.java | 4 - .../halcyon/datum/HalcyonPrincipal.java | 25 ++- .../com/ebremer/halcyon/datum/Patterns.java | 9 +- .../ebremer/halcyon/datum/SecureCoreTest.java | 54 ------- .../halcyon/datum/SecuredDatasetGraph.java | 1 + .../halcyon/datum/SessionsManager.java | 30 ++++ .../halcyon/datum/WACSecurityEvaluator.java | 25 +-- .../filesystem/DirectoryProcessor.java | 55 ++----- .../halcyon/filesystem/FileManager.java | 53 +++++++ .../halcyon/filesystem/FileMetaExtractor.java | 30 ++-- .../halcyon/fuseki/HalcyonProxyServlet.java | 34 ++++ .../fuseki/HalcyonSecurityHandler.java | 49 ++++++ .../halcyon/fuseki/SPARQLEndPoint.java | 148 ++++++++++++++++++ .../halcyon/fuseki/jwt/GetPublicKey.java | 62 ++++++++ .../fuseki/jwt/JwtAuthenticatingFilter.java | 23 +++ .../ebremer/halcyon/fuseki/jwt/JwtRealm.java | 73 +++++++++ .../ebremer/halcyon/fuseki/jwt/JwtToken.java | 32 ++++ .../halcyon/fuseki/jwt/JwtVerifier.java | 30 ++++ .../fuseki/jwt/KeycloakPublicKeyFetcher.java | 85 ++++++++++ .../com/ebremer/halcyon/fuseki/jwt/Test.java | 30 ++++ .../ebremer/halcyon/gui/CollectionPanel.java | 9 +- .../halcyon/gui/HalcyonApplication.java | 29 +++- .../ebremer/halcyon/gui/HalcyonSession.java | 114 ++++++++------ .../com/ebremer/halcyon/gui/HomePage.html | 11 +- .../java/com/ebremer/halcyon/gui/Public.html | 62 ++++++++ .../java/com/ebremer/halcyon/gui/Public.java | 14 ++ .../halcyon/imagebox/ImageReaderPool.java | 9 +- .../imagebox/ImageReaderPoolFactory.java | 4 +- .../halcyon/imagebox/JwtInterceptor.java | 42 +++++ .../com/ebremer/halcyon/imagebox/Main.java | 86 ++++++---- .../ebremer/halcyon/imagebox/NeoTiler.java | 77 +++++---- .../experimental/MinimalTiffReader.java | 4 - .../imagebox/experimental/TiffParser.java | 4 - .../imagebox/experimental/TiffReader.java | 4 - .../ebremer/halcyon/imagebox/iboxServlet.java | 10 +- .../keycloak/HALInMemorySessionIdMapper.java | 16 ++ .../HALKeycloakOIDCFilter.java | 62 ++++++-- .../keycloak/KeycloakOIDCFilterConfig.java | 51 ++++++ .../KeycloakTokenFilter.java | 6 +- .../com/ebremer/halcyon/sparql/Sparql.html | 14 +- .../com/ebremer/halcyon/sparql/Sparql.java | 54 ++++++- .../halcyon/wicket/FeatureManager.java | 14 +- .../ebremer/halcyon/wicket/ListFeatures.java | 6 +- .../ebremer/halcyon/wicket/ListImages.java | 29 +--- .../com/ebremer/halycon/shiro/JWTGuard.java | 16 ++ .../halycon/shiro/JWTVerifyingFilter.java | 54 +++++++ src/main/java/com/ebremer/ns/HAL.java | 3 +- src/main/resources/keycloak.json | 2 +- src/main/resources/shiro.ini | 15 ++ 57 files changed, 1532 insertions(+), 421 deletions(-) delete mode 100644 src/main/java/com/ebremer/halcyon/HalcyonDefaults.java create mode 100644 src/main/java/com/ebremer/halcyon/datum/AddParamsToHeader.java create mode 100644 src/main/java/com/ebremer/halcyon/datum/CustomShiroConfigurator.java delete mode 100644 src/main/java/com/ebremer/halcyon/datum/SecureCoreTest.java create mode 100644 src/main/java/com/ebremer/halcyon/datum/SessionsManager.java create mode 100644 src/main/java/com/ebremer/halcyon/fuseki/HalcyonProxyServlet.java create mode 100644 src/main/java/com/ebremer/halcyon/fuseki/HalcyonSecurityHandler.java create mode 100644 src/main/java/com/ebremer/halcyon/fuseki/SPARQLEndPoint.java create mode 100644 src/main/java/com/ebremer/halcyon/fuseki/jwt/GetPublicKey.java create mode 100644 src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtAuthenticatingFilter.java create mode 100644 src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtRealm.java create mode 100644 src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtToken.java create mode 100644 src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtVerifier.java create mode 100644 src/main/java/com/ebremer/halcyon/fuseki/jwt/KeycloakPublicKeyFetcher.java create mode 100644 src/main/java/com/ebremer/halcyon/fuseki/jwt/Test.java create mode 100644 src/main/java/com/ebremer/halcyon/gui/Public.html create mode 100644 src/main/java/com/ebremer/halcyon/gui/Public.java create mode 100644 src/main/java/com/ebremer/halcyon/imagebox/JwtInterceptor.java create mode 100644 src/main/java/com/ebremer/halcyon/keycloak/HALInMemorySessionIdMapper.java rename src/main/java/com/ebremer/halcyon/{imagebox => keycloak}/HALKeycloakOIDCFilter.java (63%) create mode 100644 src/main/java/com/ebremer/halcyon/keycloak/KeycloakOIDCFilterConfig.java rename src/main/java/com/ebremer/halcyon/{gui => keycloak}/KeycloakTokenFilter.java (80%) create mode 100644 src/main/java/com/ebremer/halycon/shiro/JWTGuard.java create mode 100644 src/main/java/com/ebremer/halycon/shiro/JWTVerifyingFilter.java create mode 100644 src/main/resources/shiro.ini diff --git a/pom.xml b/pom.xml index e91eef22..1b1ff4b8 100644 --- a/pom.xml +++ b/pom.xml @@ -73,7 +73,7 @@ 2.11.1 2.0.1 1.3.0 - 5.29.1 + 5.29.2 4.7.4.Final 13.0.12.Final 4.2.21.Final @@ -232,7 +232,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.1.0 + 3.2.1 @@ -284,7 +284,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.1.0 + 3.2.1 @@ -292,7 +292,7 @@ org.springframework.experimental spring-aot-maven-plugin - 0.12.1 + 0.12.2 generate @@ -305,7 +305,7 @@ org.graalvm.buildtools native-maven-plugin - 0.9.13 + 0.9.20 true @@ -375,7 +375,7 @@ org.springframework.experimental spring-native - 0.12.1 + 0.12.2 @@ -386,7 +386,7 @@ org.graalvm.buildtools native-maven-plugin - 0.9.19 + 0.9.20 true @@ -661,13 +661,12 @@ ${jena.ver} jar - + org.apache.jena jena-permissions @@ -685,6 +684,12 @@ jena-fuseki-main ${jena.ver} + com.github.davidmoten @@ -759,6 +764,102 @@ BeakGraph 0.0.0 + + + + org.apache.shiro + shiro-core + 1.11.0 + + + org.apache.shiro + shiro-web + 1.11.0 + + + + com.jcabi + jcabi-aspects + 0.24.1 + jar + + + org.apache.jena + jena-tdb + ${jena.ver} + jar + + + io.jsonwebtoken + jjwt-api + 0.11.5 + jar + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + + + org.projectlombok + lombok + 1.18.26 + jar + diff --git a/src/main/java/com/ebremer/halcyon/FL/FLPoolFactory.java b/src/main/java/com/ebremer/halcyon/FL/FLPoolFactory.java index bbb9f627..35681d36 100644 --- a/src/main/java/com/ebremer/halcyon/FL/FLPoolFactory.java +++ b/src/main/java/com/ebremer/halcyon/FL/FLPoolFactory.java @@ -17,7 +17,6 @@ public class FLPoolFactory extends BaseKeyedPooledObjectFactory { private final String base; public FLPoolFactory(String base) { - System.out.println("Building FL Factory X..."); this.base = base; } @@ -32,7 +31,6 @@ public FL create(URI uri) throws Exception { @Override public PooledObject wrap(FL value) { - //System.out.println("wrap FL..."); return new DefaultPooledObject<>(value); } diff --git a/src/main/java/com/ebremer/halcyon/HalcyonDefaults.java b/src/main/java/com/ebremer/halcyon/HalcyonDefaults.java deleted file mode 100644 index 6822aab4..00000000 --- a/src/main/java/com/ebremer/halcyon/HalcyonDefaults.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ -package com.ebremer.halcyon; - -/** - * - * @author erich - */ -public class HalcyonDefaults { - public static String VERSION = "0.0.0"; -} diff --git a/src/main/java/com/ebremer/halcyon/HalcyonSettings.java b/src/main/java/com/ebremer/halcyon/HalcyonSettings.java index 15dfcf91..cca21548 100644 --- a/src/main/java/com/ebremer/halcyon/HalcyonSettings.java +++ b/src/main/java/com/ebremer/halcyon/HalcyonSettings.java @@ -27,6 +27,7 @@ import org.apache.jena.rdf.model.Property; import org.apache.jena.rdf.model.ResIterator; import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.ResourceFactory; import org.apache.jena.riot.Lang; import org.apache.jena.riot.RDFDataMgr; import org.apache.jena.vocabulary.RDF; @@ -47,15 +48,17 @@ public class HalcyonSettings { private Property RDFStoreLocation = null; private Property RDFSecurityStoreLocation = null; private Model m; - public static String realm = "master"; + public static final String realm = "master"; private final Property urlpathprefix; private static final int DEFAULTSPARQLPORT = 8887; private final Property SPARQLPORT; private final Property MULTIVIEWERLOCATION; - private final String Version = "0.0.0"; + public static final String VERSION = "0.1.0"; + public static Resource HALCYONAGENT = ResourceFactory.createResource(HAL.NS+"/VERSION/"+VERSION); private static final String MasterSettingsLocation = "settings.ttl"; private Resource Master; private final HashMap mappings; + private final String Realm = "master"; private HalcyonSettings() { File f = new File(MasterSettingsLocation); @@ -84,7 +87,11 @@ public String getwebfiles() { } public String getVersion() { - return Version; + return VERSION; + } + + public String getRealm() { + return Realm; } public String getHostName() { diff --git a/src/main/java/com/ebremer/halcyon/converters/Ingest.java b/src/main/java/com/ebremer/halcyon/converters/Ingest.java index 4072fe3d..449e456d 100644 --- a/src/main/java/com/ebremer/halcyon/converters/Ingest.java +++ b/src/main/java/com/ebremer/halcyon/converters/Ingest.java @@ -1,7 +1,7 @@ package com.ebremer.halcyon.converters; import com.ebremer.beakgraph.rdf.BeakWriter; -import com.ebremer.halcyon.HalcyonDefaults; +import com.ebremer.halcyon.HalcyonSettings; import com.ebremer.ns.EXIF; import com.ebremer.ns.HAL; import com.ebremer.rocrate4j.ROCrate; @@ -107,7 +107,7 @@ public static void main(String[] args) throws FileNotFoundException, IOException new Ingest().Process(src, optimize, dest); } else { System.out.println("Halcyon ----------------------------------------------------"); - System.out.println("ingest - version : "+HalcyonDefaults.VERSION); + System.out.println("ingest - version : "+HalcyonSettings.VERSION); System.out.println(""" Usage: ingest (heatmap|segmentation) diff --git a/src/main/java/com/ebremer/halcyon/datum/AddParamsToHeader.java b/src/main/java/com/ebremer/halcyon/datum/AddParamsToHeader.java new file mode 100644 index 00000000..ae551a8d --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/datum/AddParamsToHeader.java @@ -0,0 +1,63 @@ +package com.ebremer.halcyon.datum; + +import com.ebremer.halcyon.gui.HalcyonSession; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +/** + * + * @author erich + */ +public class AddParamsToHeader extends HttpServletRequestWrapper { + public static final String HID = "HALCYONPRINCIPAL"; + + public AddParamsToHeader(HttpServletRequest request) { + super(request); + } + + public AddParamsToHeader(HttpServletRequest request, HashMap list) { + super(request); + //this.list = list; + } + + @Override + public String getHeader(String name) { + if (HID.equals(name)) { + return HalcyonSession.get().getHalcyonPrincipal().getURNUUID(); + } + /* + if (list.containsKey(name)) { + return list.get(name); + }*/ + String header = super.getHeader(name); + return (header != null) ? header : super.getParameter(name); + } + + @Override + public Enumeration getHeaderNames() { + List names = Collections.list(super.getHeaderNames()); + names.add(HID); + /* + list.keySet().forEach(i->{ + names.add(i); + }); +*/ + names.addAll(Collections.list(super.getParameterNames())); + return Collections.enumeration(names); + } + + @Override + public Enumeration getHeaders(String name) { + if (HID.equals(name)) { + List values = new ArrayList<>(1); + values.add(HalcyonSession.get().getHalcyonPrincipal().getURNUUID()); + return Collections.enumeration(values); + } + return super.getHeaders(name); + } +} diff --git a/src/main/java/com/ebremer/halcyon/datum/CustomShiroConfigurator.java b/src/main/java/com/ebremer/halcyon/datum/CustomShiroConfigurator.java new file mode 100644 index 00000000..543109c0 --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/datum/CustomShiroConfigurator.java @@ -0,0 +1,31 @@ +package com.ebremer.halcyon.datum; + +import org.apache.shiro.config.ConfigurationException; +import org.apache.shiro.config.Ini; +import org.apache.shiro.mgt.DefaultSecurityManager; +import org.apache.shiro.mgt.SecurityManager; +import org.apache.shiro.realm.text.IniRealm; + +public class CustomShiroConfigurator { + + private final SecurityManager securityManager; + + public CustomShiroConfigurator(Ini ini) { + try { + IniRealm iniRealm = new IniRealm(ini); + securityManager = createDefaultSecurityManager(iniRealm); + } catch (ConfigurationException e) { + throw new RuntimeException("Failed to configure Shiro", e); + } + } + + private SecurityManager createDefaultSecurityManager(IniRealm iniRealm) { + DefaultSecurityManager dsm = new DefaultSecurityManager(); + dsm.setRealm(iniRealm); + return securityManager; + } + + public SecurityManager getSecurityManager() { + return securityManager; + } +} diff --git a/src/main/java/com/ebremer/halcyon/datum/DataCore.java b/src/main/java/com/ebremer/halcyon/datum/DataCore.java index b66b2c49..7fbd18dd 100644 --- a/src/main/java/com/ebremer/halcyon/datum/DataCore.java +++ b/src/main/java/com/ebremer/halcyon/datum/DataCore.java @@ -1,9 +1,8 @@ package com.ebremer.halcyon.datum; +import com.ebremer.halcyon.fuseki.SPARQLEndPoint; import com.ebremer.halcyon.HalcyonSettings; import com.ebremer.halcyon.filesystem.FileManager; -import com.ebremer.halcyon.gui.HalcyonSession; -import org.apache.jena.fuseki.main.FusekiServer; import org.apache.jena.query.Dataset; import org.apache.jena.query.DatasetFactory; import org.apache.jena.query.Query; @@ -25,23 +24,11 @@ public class DataCore { private static DataCore core = null; private static Dataset ds = null; private static HalcyonSettings hs = null; - private FusekiServer server = null; - private final FileManager fm; - + private DataCore() { hs = HalcyonSettings.getSettings(); System.out.println("Starting TDB2..."); ds = TDB2Factory.connectDataset(hs.getRDFStoreLocation()); - - System.out.println("Starting Fuseki..."); - server = FusekiServer.create() - .add("/rdf", ds) - .enableCors(true) - .port(HalcyonSettings.getSettings().GetSPARQLPort()) - .build(); - server.start(); - System.out.println("Starting File Manager..."); - fm = FileManager.getInstance(); } public synchronized static DataCore getInstance() { @@ -52,22 +39,14 @@ public synchronized static DataCore getInstance() { } public synchronized void shutdown() { + FileManager.getInstance().pause(); + SPARQLEndPoint.getSPARQLEndPoint().shutdown(); ds.close(); - if (server!=null) { - server.stop(); - } } + - //public synchronized Dataset getSecuredDataset(String uuid) { -// WACSecurityEvaluator evaluator = new WACSecurityEvaluator(); -// evaluator.setPrincipal(uuid); -// return DatasetFactory.wrap(new SecuredDatasetGraph(getDataset().asDatasetGraph(),evaluator)); -// } - - public synchronized Dataset getSecuredDataset() { - WACSecurityEvaluator evaluator = new WACSecurityEvaluator(); - evaluator.setPrincipal(HalcyonSession.get().getHalcyonPrincipal()); - return DatasetFactory.wrap(new SecuredDatasetGraph(getDataset().asDatasetGraph(),evaluator)); + public Dataset getSecuredDataset() { + return DatasetFactory.wrap(new SecuredDatasetGraph(getDataset().asDatasetGraph(), new WACSecurityEvaluator())); } public void replaceNamedGraph(Resource k, Model m) { diff --git a/src/main/java/com/ebremer/halcyon/datum/HalSec.java b/src/main/java/com/ebremer/halcyon/datum/HalSec.java index a745d52c..234a9575 100644 --- a/src/main/java/com/ebremer/halcyon/datum/HalSec.java +++ b/src/main/java/com/ebremer/halcyon/datum/HalSec.java @@ -1,7 +1,3 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ package com.ebremer.halcyon.datum; import com.ebremer.halcyon.wicket.DatabaseLocator; diff --git a/src/main/java/com/ebremer/halcyon/datum/HalcyonPrincipal.java b/src/main/java/com/ebremer/halcyon/datum/HalcyonPrincipal.java index 240ce29c..419b68f4 100644 --- a/src/main/java/com/ebremer/halcyon/datum/HalcyonPrincipal.java +++ b/src/main/java/com/ebremer/halcyon/datum/HalcyonPrincipal.java @@ -1,5 +1,6 @@ package com.ebremer.halcyon.datum; +import io.jsonwebtoken.Claims; import java.io.Serializable; import java.security.Principal; @@ -10,22 +11,36 @@ public class HalcyonPrincipal implements Principal, Serializable { private final String uuid; private String webid; + private boolean anonymous; - public HalcyonPrincipal(String uuid) { - System.out.println("CREATING HalcyonPrincipal : "+uuid); + public HalcyonPrincipal(String uuid, boolean anonymous) { this.uuid = uuid; + this.anonymous = anonymous; + } + + public HalcyonPrincipal(Claims claims) { + uuid = "urn:uuid:"+claims.getId(); + this.anonymous = false; } public String getURNUUID() { return uuid; - } + } + + public boolean isAnon() { + return anonymous; + } + + public void setAnonymous(boolean anonymous) { + this.anonymous = anonymous; + } public String getWebID2() { return webid; - } + } @Override public String getName() { - throw new UnsupportedOperationException("Not supported yet."); + return "Erich Bremer"; } } diff --git a/src/main/java/com/ebremer/halcyon/datum/Patterns.java b/src/main/java/com/ebremer/halcyon/datum/Patterns.java index 194cb121..986eb775 100644 --- a/src/main/java/com/ebremer/halcyon/datum/Patterns.java +++ b/src/main/java/com/ebremer/halcyon/datum/Patterns.java @@ -1,7 +1,6 @@ package com.ebremer.halcyon.datum; import com.ebremer.ethereal.MakeList; -//import com.ebremer.halcyon.utils.StopWatch; import com.ebremer.ns.HAL; import java.util.List; import org.apache.jena.graph.Node; @@ -21,7 +20,6 @@ public class Patterns { public static List getCollectionList() { - //StopWatch w = new StopWatch(true); ParameterizedSparqlString pss = new ParameterizedSparqlString( """ select ?s ?name where {graph ?s {?s a so:Collection; so:name ?name}} @@ -34,12 +32,10 @@ public static List getCollectionList() { ResultSet rs = qe.execSelect(); List list = MakeList.Of(rs, "s"); ds.end(); - //w.getTime("time to get getCollectionList()"); return list; } public static List getCollectionList(Model m) { - //StopWatch w = new StopWatch(true); ParameterizedSparqlString pss = new ParameterizedSparqlString( """ select ?s ?name where {?s a so:Collection; so:name ?name} @@ -52,7 +48,6 @@ public static List getCollectionList(Model m) { ResultSet rs = qe.execSelect(); List list = MakeList.Of(rs, "s"); ds.end(); - //w.getTime("getCollectionList(Model m)"); return list; } @@ -72,19 +67,17 @@ public static List getCollectionList(Dataset ds) { } public static Model getCollectionRDF() { - //StopWatch w = new StopWatch(true); ParameterizedSparqlString pss = new ParameterizedSparqlString( """ construct {?s a so:Collection; so:name ?name} where {graph ?s {?s a so:Collection; so:name ?name}} """); pss.setNsPrefix("hal", HAL.NS); pss.setNsPrefix("so", SchemaDO.NS); - Dataset ds = DataCore.getInstance().getDataset(); + Dataset ds = DataCore.getInstance().getSecuredDataset(); QueryExecution qe = QueryExecutionFactory.create(pss.toString(), ds); ds.begin(ReadWrite.READ); Model m = qe.execConstruct(); ds.end(); - //w.getTime("getCollectionRDF()"); return m; } } diff --git a/src/main/java/com/ebremer/halcyon/datum/SecureCoreTest.java b/src/main/java/com/ebremer/halcyon/datum/SecureCoreTest.java deleted file mode 100644 index 0af4a7fd..00000000 --- a/src/main/java/com/ebremer/halcyon/datum/SecureCoreTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.ebremer.halcyon.datum; - -import com.ebremer.ns.EXIF; -import com.ebremer.ns.HAL; -import java.util.List; -import org.apache.jena.graph.Node; -import org.apache.jena.query.Dataset; -import org.apache.jena.query.ParameterizedSparqlString; -import org.apache.jena.query.QueryExecutionFactory; -import org.apache.jena.query.ReadWrite; -import org.apache.jena.query.ResultSet; -import org.apache.jena.query.ResultSetFormatter; -import org.apache.jena.vocabulary.OWL; -import org.apache.jena.vocabulary.SchemaDO; -import org.apache.jena.vocabulary.WAC; - -/** - * - * @author erich - */ -public class SecureCoreTest { - - public static void main(String[] args) { - loci.common.DebugTools.setRootLevel("WARN"); - DataCore datacore = DataCore.getInstance(); - // Dataset ds = datacore.getSecuredDataset("urn:uuid:48c07c4e-c092-4180-b67b-b57b6ec60d3d"); - //Dataset ds = datacore.getDataset(); - /* - DataCore datacore = DataCore.getInstance(); - Dataset ds = datacore.getSecuredDataset("urn:uuid:48c07c4e-c092-4180-b67b-b57b6ec60d3d"); - ds.begin(ReadWrite.READ); - ParameterizedSparqlString pss = new ParameterizedSparqlString( - """ - select * - where {graph ?g {?s ?p ?o}} - """); - pss.setNsPrefix("acl", WAC.NS); - pss.setNsPrefix("owl", OWL.NS); - pss.setNsPrefix("hal", HAL.NS); - pss.setNsPrefix("so", SchemaDO.NS); - pss.setNsPrefix("exif", EXIF.NS); - pss.setIri("g", HAL.SecurityGraph.getURI()); - ResultSet results = QueryExecutionFactory.create(pss.toString(), ds).execSelect(); - ResultSetFormatter.out(System.out,results); - ds.end(); - ds.close(); - datacore.shutdown();*/ - //List list = Patterns.getCollectionList(ds); - // System.out.println("DUMP COLLECTIONS..."); - //list.forEach(f->{ -// System.out.println(f); -// }); - } -} diff --git a/src/main/java/com/ebremer/halcyon/datum/SecuredDatasetGraph.java b/src/main/java/com/ebremer/halcyon/datum/SecuredDatasetGraph.java index 7a9e096d..79469fc2 100644 --- a/src/main/java/com/ebremer/halcyon/datum/SecuredDatasetGraph.java +++ b/src/main/java/com/ebremer/halcyon/datum/SecuredDatasetGraph.java @@ -46,6 +46,7 @@ private List getBaseGraphNodes() { private boolean hasReadAccess(Node node) { return securityEvaluator.evaluate(securityEvaluator.getPrincipal(), SecurityEvaluator.Action.Read, node); + //return securityEvaluator.evaluate(securityEvaluator.getPrincipal(), SecurityEvaluator.Action.Read, node); } @Override diff --git a/src/main/java/com/ebremer/halcyon/datum/SessionsManager.java b/src/main/java/com/ebremer/halcyon/datum/SessionsManager.java new file mode 100644 index 00000000..51b76b70 --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/datum/SessionsManager.java @@ -0,0 +1,30 @@ +package com.ebremer.halcyon.datum; + +import com.ebremer.halcyon.keycloak.HALInMemorySessionIdMapper; +import org.keycloak.adapters.spi.SessionIdMapper; + +/** + * + * @author erich + */ +public class SessionsManager { + private static SessionsManager sm = null; + private static SessionIdMapper idMapper = null; + + private SessionsManager() { + + } + + public SessionIdMapper getSessionIdMapper() { + getSessionsManager(); + return idMapper; + } + + public static SessionsManager getSessionsManager() { + if (sm==null) { + sm = new SessionsManager(); + idMapper = new HALInMemorySessionIdMapper(); + } + return sm; + } +} diff --git a/src/main/java/com/ebremer/halcyon/datum/WACSecurityEvaluator.java b/src/main/java/com/ebremer/halcyon/datum/WACSecurityEvaluator.java index d5dd04f5..4b9f091a 100644 --- a/src/main/java/com/ebremer/halcyon/datum/WACSecurityEvaluator.java +++ b/src/main/java/com/ebremer/halcyon/datum/WACSecurityEvaluator.java @@ -1,6 +1,8 @@ package com.ebremer.halcyon.datum; +import com.ebremer.halcyon.gui.HalcyonSession; import com.ebremer.ns.HAL; +import io.jsonwebtoken.Claims; import java.security.Principal; import java.util.HashMap; import java.util.Set; @@ -14,15 +16,17 @@ import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.shared.AuthenticationRequiredException; +import org.apache.jena.vocabulary.RDF; import org.apache.jena.vocabulary.SchemaDO; import org.apache.jena.vocabulary.WAC; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; /** * * @author erich */ public class WACSecurityEvaluator implements SecurityEvaluator { - private HalcyonPrincipal principal; private final Model secm; private final HashMap cache; @@ -38,29 +42,21 @@ public WACSecurityEvaluator() { ds.end(); } - public void setPrincipal( HalcyonPrincipal principal ) { - this.principal = principal; - } - public Model getSecurityModel() { return secm; } @Override public boolean evaluate(Object principal, Action action, Node graphIRI) { - return true; - /* HalcyonPrincipal hp = (HalcyonPrincipal) principal; if (graphIRI.matches(HAL.CollectionsAndResources.asNode())) { return true; } if (cache.containsKey(graphIRI)) { if (cache.get(graphIRI).containsKey(action)) { - //System.out.println("CACHE HIT!!!"); return true; } } - //System.out.println("CACHE MISS!!!"); HashMap set = new HashMap<>(); cache.put(graphIRI, set); ParameterizedSparqlString pss = new ParameterizedSparqlString(""" @@ -78,7 +74,7 @@ public boolean evaluate(Object principal, Action action, Node graphIRI) { pss.setIri("member", hp.getURNUUID()); boolean ha = QueryExecutionFactory.create(pss.toString(), secm).execAsk(); set.put(action, ha); - return ha;*/ + return ha; } private boolean evaluate( Object principal, Triple triple ) { @@ -121,7 +117,14 @@ public boolean evaluateUpdate(Object principal, Node graphIRI, Triple from, Trip @Override public Principal getPrincipal() { - return principal; + try { + Claims dc = (Claims) SecurityUtils.getSubject().getPrincipal(); + // System.out.println(dc.getId()); + return new HalcyonPrincipal(dc); + } catch (org.apache.shiro.UnavailableSecurityManagerException ex) { + //System.out.println(ex.toString()); + } + return HalcyonSession.get().getHalcyonPrincipal(); } @Override diff --git a/src/main/java/com/ebremer/halcyon/filesystem/DirectoryProcessor.java b/src/main/java/com/ebremer/halcyon/filesystem/DirectoryProcessor.java index 2803794e..e31c3a92 100644 --- a/src/main/java/com/ebremer/halcyon/filesystem/DirectoryProcessor.java +++ b/src/main/java/com/ebremer/halcyon/filesystem/DirectoryProcessor.java @@ -4,6 +4,7 @@ import com.ebremer.halcyon.datum.EB; import com.ebremer.halcyon.datum.Scan; import com.ebremer.ns.HAL; +import java.io.FileNotFoundException; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -43,19 +44,14 @@ public class DirectoryProcessor { public static final int TIF = 6; public static final int NDPI = 7; public static final int DFIX = 1701; - public int cores = 5; + public final int cores; private final Dataset buffer; private CopyOnWriteArrayList list = null; public DirectoryProcessor(Dataset buffer) { this.buffer = buffer; list = GetExisting(); - } - - public DirectoryProcessor(Dataset buffer, int numcores) { - this.buffer = buffer; - cores = numcores; - list = GetExisting(); + cores = 4; } public Model PathInfo(String s) { @@ -85,8 +81,7 @@ public void Traverse(Path src, String[] ext, int ftype) { Stream yay = Files.walk(src); ForkJoinPool fjp = null; try { - //fjp = new ForkJoinPool(cores); - fjp = new ForkJoinPool(1); + fjp = new ForkJoinPool(cores); fjp.submit(()->yay.collect(toList()).parallelStream() .filter(Objects::nonNull) .filter(fff -> { @@ -108,19 +103,14 @@ public void Traverse(Path src, String[] ext, int ftype) { System.out.println("Processing : "+xxx); FileMetaExtractor fe = new FileMetaExtractor(e.toFile()); Model m = fe.getDataset().getNamedModel(xxx); - //System.out.println("SIZE : "+m.size()); - - if (m!=null) { - buffer.begin(ReadWrite.WRITE); - buffer.getDefaultModel().add(fe.getCoreMeta()); - Model pathinfo = PathInfo(xxx); - buffer.addNamedModel(HAL.CollectionsAndResources, pathinfo); - buffer.addNamedModel(xxx, m); - buffer.commit(); - buffer.end(); - } else { - System.out.println("NULLLLLLLLLLLLLLLLL"); - } + m.createResource(xxx).addProperty(RDF.type, HAL.FileManagerArtifact); + buffer.begin(ReadWrite.WRITE); + buffer.getDefaultModel().add(fe.getCoreMeta()); + Model pathinfo = PathInfo(xxx); + buffer.addNamedModel(HAL.CollectionsAndResources, pathinfo); + buffer.addNamedModel(xxx, m); + buffer.commit(); + buffer.end(); }) ).get(); } catch (InterruptedException | ExecutionException ex) { @@ -160,27 +150,8 @@ public final CopyOnWriteArrayList GetExisting() { while (results.hasNext()) { QuerySolution sol = results.nextSolution(); cur.add(sol.get("g").toString()); - //System.out.println("existing : "+sol.get("g").toString()); } ds.end(); return cur; } - - /* - - public static void main(String[] args) throws FileNotFoundException { - ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger)(org.slf4j.Logger)LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); - root.setLevel(ch.qos.logback.classic.Level.OFF); - String[] tmp = {"D:\\HalcyonStorage", "D:\\legacy\\images.nq"}; - args = tmp; - Dataset ds = DatasetFactory.createTxnMem(); - DirectoryProcessor dp = new DirectoryProcessor(ds); - dp.Traverse(Path.of(args[0]), GetExtensions(DirectoryProcessor.ZIP), DirectoryProcessor.ZIP); - FileOutputStream fos = new FileOutputStream(new File(args[1])); - ds.begin(); - RDFDataMgr.write(fos, ds, RDFFormat.TRIG_PRETTY); - ds.end(); - //dc.shutdown(); - System.out.println("DONE."); - }*/ -} \ No newline at end of file +} diff --git a/src/main/java/com/ebremer/halcyon/filesystem/FileManager.java b/src/main/java/com/ebremer/halcyon/filesystem/FileManager.java index e4501752..da464ff2 100644 --- a/src/main/java/com/ebremer/halcyon/filesystem/FileManager.java +++ b/src/main/java/com/ebremer/halcyon/filesystem/FileManager.java @@ -3,12 +3,25 @@ import com.ebremer.halcyon.HalcyonSettings; import com.ebremer.halcyon.datum.DataCore; import static com.ebremer.halcyon.filesystem.DirectoryProcessor.GetExtensions; +import java.io.FileNotFoundException; +import java.net.URI; +import java.net.URISyntaxException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Iterator; import java.util.Timer; import java.util.TimerTask; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.jena.query.Dataset; +import org.apache.jena.query.ParameterizedSparqlString; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryExecutionFactory; +import org.apache.jena.query.ReadWrite; +import org.apache.jena.query.ResultSet; +import org.apache.jena.update.UpdateAction; +import org.apache.jena.update.UpdateFactory; +import org.apache.jena.update.UpdateRequest; /** * @@ -46,6 +59,7 @@ public void run() { dp.Traverse(p, GetExtensions(DirectoryProcessor.TIF), DirectoryProcessor.TIF); dp.Traverse(p, GetExtensions(DirectoryProcessor.NDPI), DirectoryProcessor.NDPI); } + ValidateData(); resume(); } }; @@ -55,6 +69,7 @@ public void run() { public synchronized static FileManager getInstance() { if (fm==null) { + System.out.println("Starting File Manager..."); fm = new FileManager(); } return fm; @@ -67,4 +82,42 @@ public void ListStorageAreas() { Path p = i.next().path; } } + + public void ValidateData() { + Dataset ds = DataCore.getInstance().getDataset(); + ds.begin(ReadWrite.READ); + QueryExecution qe = QueryExecutionFactory.create("select distinct ?g where {graph ?g {?g ?p ?o}}", ds); + ResultSet results = qe.execSelect().materialise(); + ds.end(); + results.forEachRemaining(qs->{ + String r = qs.get("g").toString(); + if (r.startsWith("file:/")) { + try { + URI uri = new URI(r); + Path path = Path.of(uri); + if (!path.toFile().exists()) { + UpdateRequest request = UpdateFactory.create(); + ParameterizedSparqlString pss = new ParameterizedSparqlString("delete where {graph ?g {?s ?p ?o}}"); + pss.setIri("g", r); + request.add(pss.toString()); + ds.begin(ReadWrite.WRITE); + UpdateAction.execute(request, ds); + ds.commit(); + ds.end(); + System.out.println("DELETED : "+r); + } + } catch (URISyntaxException ex) { + System.out.println("NG --> "+r); + Logger.getLogger(FileManager.class.getName()).log(Level.SEVERE, null, ex); + } + } + }); + } + + public static void main(String[] args) throws FileNotFoundException { + loci.common.DebugTools.setRootLevel("WARN"); + DataCore dc = DataCore.getInstance(); + //while (true) {} + //FileManager fm = FileManager.getInstance(); + } } \ No newline at end of file diff --git a/src/main/java/com/ebremer/halcyon/filesystem/FileMetaExtractor.java b/src/main/java/com/ebremer/halcyon/filesystem/FileMetaExtractor.java index ba3fe54e..e894ab52 100644 --- a/src/main/java/com/ebremer/halcyon/filesystem/FileMetaExtractor.java +++ b/src/main/java/com/ebremer/halcyon/filesystem/FileMetaExtractor.java @@ -1,5 +1,6 @@ package com.ebremer.halcyon.filesystem; +import com.ebremer.halcyon.HalcyonSettings; import com.ebremer.halcyon.datum.EB; import com.ebremer.ns.HAL; import com.ebremer.ns.LOC; @@ -82,10 +83,10 @@ private void Process() { ROCrateReader roc = new ROCrateReader(file.toURI()); //z = roc.getManifest(fixe); z = roc.getManifest(); - System.out.println("LOADED : "+z.size()); - System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); - RDFDataMgr.write(System.out, z, RDFFormat.TURTLE_PRETTY); - System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + //System.out.println("LOADED : "+z.size()); + //System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); + //RDFDataMgr.write(System.out, z, RDFFormat.TURTLE_PRETTY); + //System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); UpdateRequest update = UpdateFactory.create(); ParameterizedSparqlString pss = new ParameterizedSparqlString(""" delete {?s ?p ?o} @@ -109,9 +110,9 @@ private void Process() { update.add(pss.toString()); UpdateAction.execute(update, z); m.add(z); - System.out.println("Extracted ========================================================\n"); - RDFDataMgr.write(System.out, m, Lang.TURTLE); - System.out.println("Extracted END END END ============================================"); + //System.out.println("Extracted ========================================================\n"); + //RDFDataMgr.write(System.out, m, Lang.TURTLE); + //System.out.println("Extracted END END END ============================================"); // roc.close(); } catch (IOException ex) { Logger.getLogger(FileMetaExtractor.class.getName()).log(Level.SEVERE, null, ex); @@ -130,9 +131,10 @@ private void Process() { System.out.println("Unknown file type : "+extension); } ZonedDateTime dateTime = ZonedDateTime.now(); - m.addLiteral(s, HAL.dateRegistered, dateTime.format(formatter)); + m.addLiteral(s, SchemaDO.datePublished, dateTime.format(formatter)); m.add(s, SchemaDO.name, s.getLocalName()); m.addLiteral(s,SchemaDO.contentSize,file.length()); + s.addProperty(SchemaDO.instrument, HalcyonSettings.HALCYONAGENT); } public void CalculateMD5() { @@ -161,18 +163,10 @@ public Model ImageFileExtractor() { m.add(ss,RDF.type,SchemaDO.ImageObject); m.addLiteral(ss,EXIF.width,reader.getSizeX()); m.addLiteral(ss,EXIF.height,reader.getSizeY()); + reader.close(); } catch (FormatException | IOException ex) { } return m; } - - /* - public static void main(String[] args) { - DebugTools.setRootLevel("WARN"); - File f = new File("D:\\HalcyonStorage\\demo2\\coad_CM-5348\\Cdysplasia_heatmap_TCGA-CM-5348-01Z-00-DX1.2ad0b8f6-684a-41a7-b568-26e97675cce9.zip"); - FileMetaExtractor fe = new FileMetaExtractor(f); - RDFDataMgr.write(System.out, fe.getDataset(), RDFFormat.TRIG_PRETTY); - } -*/ -} \ No newline at end of file +} diff --git a/src/main/java/com/ebremer/halcyon/fuseki/HalcyonProxyServlet.java b/src/main/java/com/ebremer/halcyon/fuseki/HalcyonProxyServlet.java new file mode 100644 index 00000000..97c75278 --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/fuseki/HalcyonProxyServlet.java @@ -0,0 +1,34 @@ +package com.ebremer.halcyon.fuseki; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.keycloak.KeycloakSecurityContext; +import org.mitre.dsmiley.httpproxy.ProxyServlet; + +/** + * + * @author erich + */ +public class HalcyonProxyServlet extends ProxyServlet { + + private KeycloakSecurityContext getKeycloakSecurityContext(HttpServletRequest request) { + return (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName()); + } + + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + super.service(request, response); + /* + KeycloakSecurityContext securityContext = getKeycloakSecurityContext(request); + String token = securityContext.getIdTokenString(); + HashMap list = new HashMap<>(); + list.put("token", token); + System.out.println("======================================================================"); + System.out.println(token); + System.out.println("======================================================================"); +*/ + //super.service(new AddParamsToHeader(request), response); + } +} diff --git a/src/main/java/com/ebremer/halcyon/fuseki/HalcyonSecurityHandler.java b/src/main/java/com/ebremer/halcyon/fuseki/HalcyonSecurityHandler.java new file mode 100644 index 00000000..4d1939ad --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/fuseki/HalcyonSecurityHandler.java @@ -0,0 +1,49 @@ +package com.ebremer.halcyon.fuseki; + +import com.ebremer.halcyon.datum.AddParamsToHeader; +import java.io.IOException; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; +import org.eclipse.jetty.security.RoleInfo; +import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.UserIdentity; + +/** + * + * @author erich + */ +public class HalcyonSecurityHandler extends SecurityHandler { + + public HalcyonSecurityHandler() { + + } + + @Override + protected RoleInfo prepareConstraintInfo(String string, Request rqst) { + System.out.println("prepareConstraintInfo"); + RoleInfo ri = new RoleInfo(); + return ri; + } + + @Override + protected boolean checkUserDataPermissions(String string, Request rqst, Response rspns, RoleInfo ri) throws IOException { + System.out.println("checkUserDataPermissions"); + System.out.println("YES!!!!! ---> "+rqst.getHeader(AddParamsToHeader.HID)); + Subject s = SecurityUtils.getSubject(); + return true; + } + + @Override + protected boolean isAuthMandatory(Request rqst, Response rspns, Object o) { + System.out.println("isAuthMandatory"); + return false; + } + + @Override + protected boolean checkWebResourcePermissions(String string, Request rqst, Response rspns, Object o, UserIdentity ui) throws IOException { + System.out.println("checkWebResourcePermissions"); + return true; + } +} diff --git a/src/main/java/com/ebremer/halcyon/fuseki/SPARQLEndPoint.java b/src/main/java/com/ebremer/halcyon/fuseki/SPARQLEndPoint.java new file mode 100644 index 00000000..5d8f4a6d --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/fuseki/SPARQLEndPoint.java @@ -0,0 +1,148 @@ +package com.ebremer.halcyon.fuseki; + +import com.ebremer.halcyon.HalcyonSettings; +import com.ebremer.halcyon.datum.DataCore; +import com.ebremer.halcyon.datum.SessionsManager; +import com.ebremer.halcyon.keycloak.HALKeycloakOIDCFilter; +import com.ebremer.halcyon.keycloak.KeycloakOIDCFilterConfig; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; +import javax.servlet.DispatcherType; +import org.apache.jena.fuseki.main.FusekiServer; +import org.keycloak.adapters.servlet.KeycloakOIDCFilter; +import org.apache.shiro.web.env.EnvironmentLoaderListener; +import org.apache.shiro.web.servlet.ShiroFilter; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.SessionIdManager; +import org.eclipse.jetty.server.session.DefaultSessionIdManager; +import org.eclipse.jetty.server.session.SessionHandler; +import org.eclipse.jetty.servlet.FilterHolder; +import org.eclipse.jetty.servlet.FilterMapping; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHandler; + +/** + * + * @author erich + */ +public class SPARQLEndPoint { + private static SPARQLEndPoint sep = null; + private static FusekiServer server = null; + + private SPARQLEndPoint() { + System.out.println("Starting Fuseki..."); + KeycloakOIDCFilterConfig config = new KeycloakOIDCFilterConfig("keycloak"); + config.setInitParameter(KeycloakOIDCFilter.CONFIG_FILE_PARAM, "keycloak.json"); + HALKeycloakOIDCFilter filter = new HALKeycloakOIDCFilter(); + filter.setSessionIdMapper(SessionsManager.getSessionsManager().getSessionIdMapper()); + filter.setConfig(config); + server = FusekiServer.create() + .add("/rdf", DataCore.getInstance().getSecuredDataset()) + // .loopback(true) + // .securityHandler(new HalcyonSecurityHandler()) + + .enableCors(true) + .port(HalcyonSettings.getSettings().GetSPARQLPort()) + // .addFilter("/*", filter) + .build(); + config.setContext(server.getServletContext()); + //SessionHandler sessionHandler = new SessionHandler(); + //DefaultSessionCache sessionCache = new DefaultSessionCache(sessionHandler); + //DefaultSessionIdManager sim = new DefaultSessionIdManager(server.getJettyServer()); + //server.getJettyServer().setSessionIdManager(sim); + + Server jettyServer = server.getJettyServer(); + ServletContextHandler servletContextHandler = (ServletContextHandler) jettyServer.getHandler(); + + ServletHandler servletHandler = servletContextHandler.getServletHandler(); + + EnvironmentLoaderListener ell = new EnvironmentLoaderListener(); + servletContextHandler.addEventListener(ell); + + List mappings = new ArrayList<>(Arrays.asList(servletHandler.getFilterMappings())); + List holders = new ArrayList<>(Arrays.asList(servletHandler.getFilters())); + { + FilterHolder holder1 = new FilterHolder(); + holder1.setName("halcyonfusekifilter"); + + FilterHolder keycloakholder1 = new FilterHolder(); + keycloakholder1.setName("halcyonkeycloakfilter"); + + holder1.setFilter(new ShiroFilter()); + keycloakholder1.setFilter(filter); + + FilterMapping mapping1 = new FilterMapping(); + mapping1.setFilterName(holder1.getName()); + mapping1.setPathSpec("/*"); + mapping1.setDispatcherTypes(EnumSet.allOf(DispatcherType.class)); + + FilterMapping keycloakmapping1 = new FilterMapping(); + keycloakmapping1.setFilterName(keycloakholder1.getName()); + keycloakmapping1.setPathSpec("/rdf"); + keycloakmapping1.setDispatcherTypes(EnumSet.allOf(DispatcherType.class)); + + + mappings.add(0, mapping1); + holders.add(0, holder1); + + //mappings.add(0, keycloakmapping1); + //holders.add(0, keycloakholder1); + } + + FilterMapping[] mappings3 = new FilterMapping[mappings.size()]; + mappings3 = mappings.toArray(mappings3); + FilterHolder[] holders3 = new FilterHolder[holders.size()]; + holders3 = holders.toArray(holders3); + servletHandler.setFilters(holders3); + servletHandler.setFilterMappings(mappings3); + + SessionIdManager idmanager = new DefaultSessionIdManager(jettyServer); + jettyServer.setSessionIdManager(idmanager); + + SessionHandler sessionsHandler = new SessionHandler(); + //sessionsHandler.setUsingCookies(false); + servletHandler.setHandler(sessionsHandler); + sessionsHandler.getSessionCookieConfig().setName("JETTYFUSEKISESSION"); + + server.start(); + } + + public static FusekiServer getFusekiServer() { + return server; + } + + /* + + private static void configureShiro() { + String iniConfig = + """ + [users] + admin=admin,administrator + user=user,user + [roles] + administrator=admin:*,read:*,write:*,execute:*,create:*,delete:* + user=read:*,write:*,execute:* + """; + InputStream input = new ByteArrayInputStream(iniConfig.getBytes()); + Ini ini = new Ini(); + ini.load(input); + CustomShiroConfigurator shiroConfigurator = new CustomShiroConfigurator(ini); + SecurityManager securityManager = shiroConfigurator.getSecurityManager(); + SecurityUtils.setSecurityManager(securityManager); + }*/ + + public static SPARQLEndPoint getSPARQLEndPoint() { + if (sep==null) { + sep = new SPARQLEndPoint(); + } + return sep; + } + + public void shutdown() { + if (server!=null) { + server.stop(); + } + } +} diff --git a/src/main/java/com/ebremer/halcyon/fuseki/jwt/GetPublicKey.java b/src/main/java/com/ebremer/halcyon/fuseki/jwt/GetPublicKey.java new file mode 100644 index 00000000..deacac8e --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/fuseki/jwt/GetPublicKey.java @@ -0,0 +1,62 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + */ +package com.ebremer.halcyon.fuseki.jwt; + +import com.ebremer.halcyon.HalcyonSettings; +import jakarta.json.Json; +import jakarta.json.JsonObject; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +/** + * + * @author erich + */ +public class GetPublicKey { + private String oidcConfigurationUrl = "http://localhost:"+HalcyonSettings.getSettings().GetHostPort() + "/auth/realms/master/.well-known/openid-configuration"; + private PublicKey publicKey; + + public GetPublicKey() { + try { + publicKey = fetchPublicKeyFromKeycloak(); + } catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) { + throw new RuntimeException("Error fetching public key from Keycloak server", e); + } + } + + public PublicKey getPublicKey() { + return publicKey; + } + + private PublicKey fetchPublicKeyFromKeycloak() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { + InputStream inputStream = new URL(oidcConfigurationUrl).openStream(); + String oidcConfiguration = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + JsonObject configJson = Json.createReader(new StringReader(oidcConfiguration)).readObject(); + + String jwksUrl = configJson.getString("jwks_uri"); + inputStream = new URL(jwksUrl).openStream(); + String jwksJson = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + JsonObject jwks = Json.createReader(new StringReader(jwksJson)).readObject(); + + String publicKeyPem = jwks.getJsonArray("keys").getJsonObject(0).getJsonArray("x5c").getString(0); + String publicKeyDer = "-----BEGIN CERTIFICATE-----\n" + publicKeyPem + "\n-----END CERTIFICATE-----"; + publicKeyDer = publicKeyDer.replace("-----BEGIN CERTIFICATE-----\n", "").replace("\n-----END CERTIFICATE-----", ""); + byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyDer); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePublic(keySpec); + } + +} diff --git a/src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtAuthenticatingFilter.java b/src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtAuthenticatingFilter.java new file mode 100644 index 00000000..65a685a2 --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtAuthenticatingFilter.java @@ -0,0 +1,23 @@ +package com.ebremer.halcyon.fuseki.jwt; + +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.web.filter.authc.AuthenticatingFilter; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + +public class JwtAuthenticatingFilter extends AuthenticatingFilter { + private static final String TOKEN_HEADER = "token"; + + @Override + protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception { + HttpServletRequest httpRequest = (HttpServletRequest) request; + String jwt = httpRequest.getHeader(TOKEN_HEADER); + return new JwtToken(jwt); + } + + @Override + protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { + return executeLogin(request, response); + } +} diff --git a/src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtRealm.java b/src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtRealm.java new file mode 100644 index 00000000..693509c8 --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtRealm.java @@ -0,0 +1,73 @@ +package com.ebremer.halcyon.fuseki.jwt; + +import io.jsonwebtoken.Claims; +import org.apache.shiro.authc.AuthenticationInfo; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.authc.SimpleAuthenticationInfo; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.realm.AuthorizingRealm; +import org.apache.shiro.subject.PrincipalCollection; +import org.apache.shiro.subject.SimplePrincipalCollection; + +public class JwtRealm extends AuthorizingRealm { + + public JwtRealm() { + + } + + @Override + public boolean supports(AuthenticationToken token) { + return token instanceof JwtToken; + } + + @Override + protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { + System.out.println("Implement your authorization logic here based on the user's roles and permissions."); + return null; + } + + @Override + protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) { + JwtToken jwtToken = (JwtToken) token; + Claims claims = jwtToken.getClaims(); + SimplePrincipalCollection principalCollection = new SimplePrincipalCollection(claims, getName()); + return new SimpleAuthenticationInfo(principalCollection, token.getCredentials()); + } +} + + +/* +public class JwtRealm extends AuthenticatingRealm { + private PublicKey publicKey = null; + + public JwtRealm() { + System.out.println("JWT Realm initialized..."); + } + + @Override + public boolean supports(AuthenticationToken token) { + return token instanceof JwtToken; + } + + @Override + protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { + System.out.println("doGetAuthenticationInfo(AuthenticationToken token) "+publicKey); + if (publicKey==null) { + GetPublicKey gpk = new GetPublicKey(); + publicKey = gpk.getPublicKey(); + } + JwtToken jwtToken = (JwtToken) token; + String jwt = jwtToken.getToken(); + try { + Jws jws = Jwts.parserBuilder() + .setSigningKey(publicKey) + .build() + .parseClaimsJws(jwt); + String subject = jws.getBody().getSubject(); + return new SimpleAuthenticationInfo(subject, jwt, getName()); + } catch (JwtException e) { + throw new AuthenticationException("Invalid JWT", e); + } + } +} +*/ \ No newline at end of file diff --git a/src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtToken.java b/src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtToken.java new file mode 100644 index 00000000..2256f37e --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtToken.java @@ -0,0 +1,32 @@ +package com.ebremer.halcyon.fuseki.jwt; + +import io.jsonwebtoken.Claims; +import java.security.PublicKey; +import org.apache.shiro.authc.AuthenticationToken; + +public class JwtToken implements AuthenticationToken { + + private final String token; + private final Claims claims; + + public JwtToken(String token) { + this.token = token; + PublicKey publicKey = KeycloakPublicKeyFetcher.getKeycloakPublicKeyFetcher().getPublicKey(); + this.claims = new JwtVerifier(publicKey).verify(token); + } + + @Override + public Object getPrincipal() { + return getClaims().getSubject(); + } + + @Override + public Object getCredentials() { + return token; + } + + public Claims getClaims() { + return claims; + } +} + diff --git a/src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtVerifier.java b/src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtVerifier.java new file mode 100644 index 00000000..b80cb7fd --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/fuseki/jwt/JwtVerifier.java @@ -0,0 +1,30 @@ +package com.ebremer.halcyon.fuseki.jwt; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; +import io.jsonwebtoken.JwtParserBuilder; +import io.jsonwebtoken.Jwts; +import java.security.PublicKey; + +public class JwtVerifier { + private final PublicKey publicKey; + + public JwtVerifier(PublicKey publicKey) { + this.publicKey = publicKey; + } + + public Claims verify(String token) { + JwtParserBuilder b = Jwts.parserBuilder(); + Jws claimx; + try { + claimx = b + .setAllowedClockSkewSeconds(86400) + .setSigningKey(publicKey) + .build().parseClaimsJws(token); + return claimx.getBody(); + } catch (io.jsonwebtoken.ExpiredJwtException ex) { + System.out.println("ARRRGGGG JWT expired!!!!"); + } + return null; + } +} diff --git a/src/main/java/com/ebremer/halcyon/fuseki/jwt/KeycloakPublicKeyFetcher.java b/src/main/java/com/ebremer/halcyon/fuseki/jwt/KeycloakPublicKeyFetcher.java new file mode 100644 index 00000000..2a52909b --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/fuseki/jwt/KeycloakPublicKeyFetcher.java @@ -0,0 +1,85 @@ +package com.ebremer.halcyon.fuseki.jwt; + +import com.ebremer.halcyon.HalcyonSettings; +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.math.BigInteger; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.RSAPublicKeySpec; +import java.util.Base64; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class KeycloakPublicKeyFetcher { + private static KeycloakPublicKeyFetcher kpkf = null; + private final String oidcConfigurationUrl = "http://localhost:"+HalcyonSettings.getSettings().GetHostPort() + "/auth/realms/master/protocol/openid-connect/certs"; + private static PublicKey publicKey = null; + + private KeycloakPublicKeyFetcher() { + + } + + public PublicKey getPublicKey() { + return publicKey; + } + + public static KeycloakPublicKeyFetcher getKeycloakPublicKeyFetcher() { + if (kpkf==null) { + kpkf = new KeycloakPublicKeyFetcher(); + try { + publicKey = kpkf.fetchPublicKey(); + } catch (IOException ex) { + Logger.getLogger(KeycloakPublicKeyFetcher.class.getName()).log(Level.SEVERE, null, ex); + } catch (NoSuchAlgorithmException ex) { + Logger.getLogger(KeycloakPublicKeyFetcher.class.getName()).log(Level.SEVERE, null, ex); + } catch (InvalidKeySpecException ex) { + Logger.getLogger(KeycloakPublicKeyFetcher.class.getName()).log(Level.SEVERE, null, ex); + } + } + return kpkf; + } + + private PublicKey fetchPublicKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { + URL url = new URL(oidcConfigurationUrl); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setRequestProperty("Accept", "application/json"); + + if (connection.getResponseCode() != 200) { + throw new IOException("Failed to fetch public key from Keycloak: " + connection.getResponseMessage()); + } + + try (InputStream inputStream = connection.getInputStream()) { + String oidcConfiguration = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + JsonObject configJson = Json.createReader(new StringReader(oidcConfiguration)).readObject(); + JsonArray keysArray = configJson.getJsonArray("keys"); + if (!keysArray.isEmpty()) { + JsonObject keyObject = keysArray.getJsonObject(0); + String modulusBase64 = keyObject.getString("n"); + String exponentBase64 = keyObject.getString("e"); + + BigInteger modulus = new BigInteger(1, Base64.getUrlDecoder().decode(modulusBase64)); + BigInteger publicExponent = new BigInteger(1, Base64.getUrlDecoder().decode(exponentBase64)); + + RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus, publicExponent); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePublic(rsaPublicKeySpec); + } else { + throw new IllegalArgumentException("No public keys found in the provided JSON."); + } + } finally { + connection.disconnect(); + } + } +} diff --git a/src/main/java/com/ebremer/halcyon/fuseki/jwt/Test.java b/src/main/java/com/ebremer/halcyon/fuseki/jwt/Test.java new file mode 100644 index 00000000..a105b229 --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/fuseki/jwt/Test.java @@ -0,0 +1,30 @@ +package com.ebremer.halcyon.fuseki.jwt; + +import io.jsonwebtoken.Jwts; +import java.security.PublicKey; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; + +/** + * + * @author erich + */ +public class Test { + public static void main(String[] args) { + try { + Subject subject = SecurityUtils.getSubject(); + } catch (org.apache.shiro.UnavailableSecurityManagerException ex) { + System.out.println(ex.toString()); + } + //String jwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJVNk1TS0gyZmxSS3ZPVGs0OUtFeUVmZmVlNG5Oc2l3YUVZUTZDNmhNS1c0In0.eyJleHAiOjE2ODAzNzQ2NDIsImlhdCI6MTY4MDM3NDU4MiwiYXV0aF90aW1lIjoxNjgwMzc0NTgyLCJqdGkiOiI5NGFhZjQ2NS1lMWU3LTQ0YzgtYmE5Ny1hZDE1ZmFmMDgxOTMiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODgvYXV0aC9yZWFsbXMvbWFzdGVyIiwiYXVkIjoibWFzdGVyLXJlYWxtIiwic3ViIjoiYTQ2NGNmMmQtNjJjMy00MzkzLTk0NzctNDU1NjZhM2NmYmU1IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYWNjb3VudCIsInNlc3Npb25fc3RhdGUiOiI3NDQxM2RkZi1jNzc3LTRiZDItYThiZS1iOGZlMGNiMTczYmUiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiY3JlYXRlLXJlYWxtIiwiYWRtaW4iXX0sInJlc291cmNlX2FjY2VzcyI6eyJtYXN0ZXItcmVhbG0iOnsicm9sZXMiOlsidmlldy1yZWFsbSIsInZpZXctaWRlbnRpdHktcHJvdmlkZXJzIiwibWFuYWdlLWlkZW50aXR5LXByb3ZpZGVycyIsImltcGVyc29uYXRpb24iLCJjcmVhdGUtY2xpZW50IiwibWFuYWdlLXVzZXJzIiwicXVlcnktcmVhbG1zIiwidmlldy1hdXRob3JpemF0aW9uIiwicXVlcnktY2xpZW50cyIsInF1ZXJ5LXVzZXJzIiwibWFuYWdlLWV2ZW50cyIsIm1hbmFnZS1yZWFsbSIsInZpZXctZXZlbnRzIiwidmlldy11c2VycyIsInZpZXctY2xpZW50cyIsIm1hbmFnZS1hdXRob3JpemF0aW9uIiwibWFuYWdlLWNsaWVudHMiLCJxdWVyeS1ncm91cHMiXX19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIiwic2lkIjoiNzQ0MTNkZGYtYzc3Ny00YmQyLWE4YmUtYjhmZTBjYjE3M2JlIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiTWlzdGVyIFNwb2NrIiwiZ3JvdXBzIjpbImNyZWF0ZS1yZWFsbSIsImFkbWluIl0sIkhhbGN5b25Hcm91cHMiOlsiL2FkbWluIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZ2l2ZW5fbmFtZSI6Ik1pc3RlciIsImZhbWlseV9uYW1lIjoiU3BvY2sifQ.Jv8uM9jnNkh2r7wVWcReVorxowZHaHfSVgP3gRKLlV8e2vPBf7HE2OpTGffGiXVuJXxFVaY8ExbJ469g7jSIVhPgqZvPqw9sR2YrbhoUIXNuTNWTgK7HfbI8xxiaNzXkxc2G__prltOEGURtHK_Q2XwQjsdct_X8peSTWq6AZnFTqEf3cuVyOBOXQlvUGVr_1vhe8qZ_1QSAOins1Pc4zA7KBrOAWRQHn20qmMkR0Et4K6a62iZoIx36sSuwssegS2iM4RRgrtdKlB7p8B0Lrbj4PPU02QVhfSas900QgQ4Sm2Zx6r9COzXKdEevJr6-NduB9uWWDGbfdTqj7XtJmA"; + //String jwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJVNk1TS0gyZmxSS3ZPVGs0OUtFeUVmZmVlNG5Oc2l3YUVZUTZDNmhNS1c0In0.eyJleHAiOjE2ODA1NDYyMDQsImlhdCI6MTY4MDU0NjE0NCwiYXV0aF90aW1lIjoxNjgwNTQ2MTQ0LCJqdGkiOiJiZWMxMTRkMi1lMzFjLTRjYTUtOGI2ZC01YjczYmNkN2RlNmQiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODgvYXV0aC9yZWFsbXMvbWFzdGVyIiwiYXVkIjoibWFzdGVyLXJlYWxtIiwic3ViIjoiYTQ2NGNmMmQtNjJjMy00MzkzLTk0NzctNDU1NjZhM2NmYmU1IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYWNjb3VudCIsInNlc3Npb25fc3RhdGUiOiI3YWZlNmI1Yi03Y2JiLTQxOWQtOThiMy04NDZmMGFhMDhkNzciLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiY3JlYXRlLXJlYWxtIiwiYWRtaW4iXX0sInJlc291cmNlX2FjY2VzcyI6eyJtYXN0ZXItcmVhbG0iOnsicm9sZXMiOlsidmlldy1yZWFsbSIsInZpZXctaWRlbnRpdHktcHJvdmlkZXJzIiwibWFuYWdlLWlkZW50aXR5LXByb3ZpZGVycyIsImltcGVyc29uYXRpb24iLCJjcmVhdGUtY2xpZW50IiwibWFuYWdlLXVzZXJzIiwicXVlcnktcmVhbG1zIiwidmlldy1hdXRob3JpemF0aW9uIiwicXVlcnktY2xpZW50cyIsInF1ZXJ5LXVzZXJzIiwibWFuYWdlLWV2ZW50cyIsIm1hbmFnZS1yZWFsbSIsInZpZXctZXZlbnRzIiwidmlldy11c2VycyIsInZpZXctY2xpZW50cyIsIm1hbmFnZS1hdXRob3JpemF0aW9uIiwibWFuYWdlLWNsaWVudHMiLCJxdWVyeS1ncm91cHMiXX19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIiwic2lkIjoiN2FmZTZiNWItN2NiYi00MTlkLTk4YjMtODQ2ZjBhYTA4ZDc3IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiTWlzdGVyIFNwb2NrIiwiZ3JvdXBzIjpbImNyZWF0ZS1yZWFsbSIsImFkbWluIl0sIkhhbGN5b25Hcm91cHMiOlsiL2FkbWluIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZ2l2ZW5fbmFtZSI6Ik1pc3RlciIsImZhbWlseV9uYW1lIjoiU3BvY2sifQ.GnT3eqDnIeQJtx7vAptoXoVSJ__7FfiWZN9bROheZB5_7zLalZdYuBgeMqNZ5eCVuYTTzEdK_cpHtxmcb0Tmidel5CzJdudoycHDHlTpzylMgta7740qS0kPLQV9dOPEt3xoRDmUA4D9NhvoKWH6pTdXvyql22eHUAIoJ-POgCuuEmZ6x80HmQRHntRXtUma391asqiDWfkMbyBpyE3ASvzYsmIVww0AvhfWsWIfoSunm2aDGGMwAXyzJMPsCxFac63UtqxQ0qvFSpqzvz9GIV46UleziRZ_63MBfqxBiKG6QCfl3GsRY45qIe5iF_i_Be4_y8HHk1WEesq-k4YNTA"; + String jwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJVNk1TS0gyZmxSS3ZPVGs0OUtFeUVmZmVlNG5Oc2l3YUVZUTZDNmhNS1c0In0.eyJleHAiOjE2ODA1NDYyMDQsImlhdCI6MTY4MDU0NjE0NCwiYXV0aF90aW1lIjoxNjgwNTQ2MTQ0LCJqdGkiOiJiZWMxMTRkMi1lMzFjLTRjYTUtOGI2ZC01YjczYmNkN2RlNmQiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODgvYXV0aC9yZWFsbXMvbWFzdGVyIiwiYXVkIjoibWFzdGVyLXJlYWxtIiwic3ViIjoiYTQ2NGNmMmQtNjJjMy00MzkzLTk0NzctNDU1NjZhM2NmYmU1IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYWNjb3VudCIsInNlc3Npb25fc3RhdGUiOiI3YWZlNmI1Yi03Y2JiLTQxOWQtOThiMy04NDZmMGFhMDhkNzciLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiY3JlYXRlLXJlYWxtIiwiYWRtaW4iXX0sInJlc291cmNlX2FjY2VzcyI6eyJtYXN0ZXItcmVhbG0iOnsicm9sZXMiOlsidmlldy1yZWFsbSIsInZpZXctaWRlbnRpdHktcHJvdmlkZXJzIiwibWFuYWdlLWlkZW50aXR5LXByb3ZpZGVycyIsImltcGVyc29uYXRpb24iLCJjcmVhdGUtY2xpZW50IiwibWFuYWdlLXVzZXJzIiwicXVlcnktcmVhbG1zIiwidmlldy1hdXRob3JpemF0aW9uIiwicXVlcnktY2xpZW50cyIsInF1ZXJ5LXVzZXJzIiwibWFuYWdlLWV2ZW50cyIsIm1hbmFnZS1yZWFsbSIsInZpZXctZXZlbnRzIiwidmlldy11c2VycyIsInZpZXctY2xpZW50cyIsIm1hbmFnZS1hdXRob3JpemF0aW9uIiwibWFuYWdlLWNsaWVudHMiLCJxdWVyeS1ncm91cHMiXX19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIiwic2lkIjoiN2FmZTZiNWItN2NiYi00MTlkLTk4YjMtODQ2ZjBhYTA4ZDc3IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiTWlzdGVyIFNwb2NrIiwiZ3JvdXBzIjpbImNyZWF0ZS1yZWFsbSIsImFkbWluIl0sIkhhbGN5b25Hcm91cHMiOlsiL2FkbWluIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZ2l2ZW5fbmFtZSI6Ik1pc3RlciIsImZhbWlseV9uYW1lIjoiU3BvY2sifQ.GnT3eqDnIeQJtx7vAptoXoVSJ__7FfiWZN9bROheZB5_7zLalZdYuBgeMqNZ5eCVuYTTzEdK_cpHtxmcb0Tmidel5CzJdudoycHDHlTpzylMgta7740qS0kPLQV9dOPEt3xoRDmUA4D9NhvoKWH6pTdXvyql22eHUAIoJ-POgCuuEmZ6x80HmQRHntRXtUma391asqiDWfkMbyBpyE3ASvzYsmIVww0AvhfWsWIfoSunm2aDGGMwAXyzJMPsCxFac63UtqxQ0qvFSpqzvz9GIV46UleziRZ_63MBfqxBiKG6QCfl3GsRY45qIe5iF_i_Be4_y8HHk1WEesq-k4YNTA"; + PublicKey pk = KeycloakPublicKeyFetcher.getKeycloakPublicKeyFetcher().getPublicKey(); + Jwts.parserBuilder() + .setSigningKey(pk) + .setAllowedClockSkewSeconds(600) + .build() + .parseClaimsJws(jwt); + } + +} diff --git a/src/main/java/com/ebremer/halcyon/gui/CollectionPanel.java b/src/main/java/com/ebremer/halcyon/gui/CollectionPanel.java index 9e6fddde..0508d374 100644 --- a/src/main/java/com/ebremer/halcyon/gui/CollectionPanel.java +++ b/src/main/java/com/ebremer/halcyon/gui/CollectionPanel.java @@ -1,16 +1,12 @@ package com.ebremer.halcyon.gui; import com.ebremer.ethereal.LDModel; -import com.ebremer.ns.HAL; import com.ebremer.halcyon.wicket.DatabaseLocator; import com.ebremer.ethereal.RDFTextField; -import org.apache.jena.graph.Triple; import org.apache.jena.query.Dataset; import org.apache.jena.query.ReadWrite; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.Resource; -import org.apache.jena.riot.RDFDataMgr; -import org.apache.jena.riot.RDFFormat; import org.apache.jena.vocabulary.RDFS; import org.apache.wicket.markup.html.form.Button; import org.apache.wicket.markup.html.form.Form; @@ -23,11 +19,10 @@ public class CollectionPanel extends Form { public CollectionPanel(String name, LDModel mo) { super(name, new LDModel<>(mo)); - Model m = (Model) mo.getInnermostModelOrObject(); + //Model m = (Model) mo.getInnermostModelOrObject(); Resource s = null; // Resource s = m.createResource(mo.GetIRI()); // Triple wow = m.getRequiredProperty(s, RDFS.label).asTriple(); - System.out.println("Number of triples #### : "+m.size()); add(new RDFTextField("CollectionName", s, RDFS.label)); add(new Button("saveButton")); add(new Button("resetButton") { @@ -43,7 +38,7 @@ public void onSubmit() { System.out.println("SAVING!"); Dataset ds = DatabaseLocator.getDatabase().getSecuredDataset(); ds.begin(ReadWrite.READ); - RDFDataMgr.write(System.out, ds.getNamedModel(HAL.Collections.getURI()), RDFFormat.TURTLE_PRETTY); + //RDFDataMgr.write(System.out, ds.getNamedModel(HAL.Collections.getURI()), RDFFormat.TURTLE_PRETTY); ds.end(); } } \ No newline at end of file diff --git a/src/main/java/com/ebremer/halcyon/gui/HalcyonApplication.java b/src/main/java/com/ebremer/halcyon/gui/HalcyonApplication.java index ae7df637..16a27ece 100644 --- a/src/main/java/com/ebremer/halcyon/gui/HalcyonApplication.java +++ b/src/main/java/com/ebremer/halcyon/gui/HalcyonApplication.java @@ -4,12 +4,16 @@ import com.ebremer.halcyon.wicket.ListImages; import com.ebremer.halcyon.HalcyonSettings; import com.ebremer.halcyon.datum.DataCore; +import com.ebremer.halcyon.fuseki.SPARQLEndPoint; +import com.ebremer.halcyon.filesystem.FileManager; import com.ebremer.halcyon.wicket.AccountPage; import com.ebremer.halcyon.wicket.AdminPage; import com.ebremer.halcyon.wicket.BasePage; import com.ebremer.halcyon.wicket.ethereal.Graph3D; import com.ebremer.halcyon.wicket.ethereal.Zephyr; import com.ebremer.multiviewer.MultiViewer; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; import org.apache.wicket.RuntimeConfigurationType; import org.apache.wicket.Session; import org.apache.wicket.devutils.stateless.StatelessChecker; @@ -17,10 +21,19 @@ import org.apache.wicket.protocol.http.WebApplication; import org.apache.wicket.request.Request; import org.apache.wicket.request.Response; +import org.apache.wicket.request.cycle.RequestCycle; public class HalcyonApplication extends WebApplication { private static final HalcyonSettings settings = HalcyonSettings.getSettings(); - private final DataCore datacore = DataCore.getInstance(); + private final DataCore datacore; + private final FileManager fm; + private final SPARQLEndPoint sep; + + public HalcyonApplication() { + datacore = DataCore.getInstance(); + fm = FileManager.getInstance(); + sep = SPARQLEndPoint.getSPARQLEndPoint(); + } public HalcyonSettings getSettings() { return settings; @@ -37,8 +50,13 @@ public Class getHomePage() { @Override public Session newSession(Request request, Response response) { - System.out.println("NEW SESSION CREATED!!!!!!!"); - return new HalcyonSession(request); + HalcyonSession hs = new HalcyonSession(request); + HttpServletRequest req = (HttpServletRequest) request.getContainerRequest(); + Cookie[] cookies = req.getCookies(); + for (Cookie cookie: cookies) { + System.out.println("NR : "+cookie.getName()+" ==== "+cookie.getValue()); + } + return hs; } @Override @@ -50,10 +68,6 @@ public void init() { jena.setLevel(ch.qos.logback.classic.Level.ERROR); ch.qos.logback.classic.Logger XX = (ch.qos.logback.classic.Logger) org.slf4j.LoggerFactory.getLogger(org.apache.wicket.util.thread.Task.class); XX.setLevel(ch.qos.logback.classic.Level.ERROR); - - //System.setProperty("arrow.memory.debug.allocator", "true"); - //ch.qos.logback.classic.Logger arrow = (ch.qos.logback.classic.Logger) org.slf4j.LoggerFactory.getLogger("org.apache.arrow"); - //arrow.setLevel(ch.qos.logback.classic.Level.TRACE); this.getRequestLoggerSettings().setRequestLoggerEnabled(true); this.getRequestLoggerSettings().setRecordSessionSize(true); @@ -74,6 +88,7 @@ public void init() { mountPage("/gui/about", About.class); mountPage("/gui/threed", Graph3D.class); mountPage("/gui/zephyr", Zephyr.class); + mountPage("/gui/public", Public.class); //mountPage("/gui/dicom", DICOM.class); //mountPage("/gui/dicom2", DCM.class); } diff --git a/src/main/java/com/ebremer/halcyon/gui/HalcyonSession.java b/src/main/java/com/ebremer/halcyon/gui/HalcyonSession.java index b1831ea7..f4e84837 100644 --- a/src/main/java/com/ebremer/halcyon/gui/HalcyonSession.java +++ b/src/main/java/com/ebremer/halcyon/gui/HalcyonSession.java @@ -1,5 +1,6 @@ package com.ebremer.halcyon.gui; +import com.ebremer.halcyon.keycloak.KeycloakTokenFilter; import com.ebremer.halcyon.HalcyonSettings; import com.ebremer.halcyon.datum.DataCore; import com.ebremer.halcyon.datum.HalcyonPrincipal; @@ -10,7 +11,7 @@ import jakarta.json.JsonReader; import java.io.StringReader; import java.util.Locale; -import java.util.Map; +import java.util.UUID; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Invocation; import javax.ws.rs.core.Response; @@ -20,6 +21,8 @@ import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.rdf.model.Resource; +import org.apache.jena.riot.RDFDataMgr; +import org.apache.jena.riot.RDFFormat; import org.apache.jena.vocabulary.RDF; import org.apache.jena.vocabulary.SchemaDO; import org.apache.wicket.Session; @@ -45,61 +48,70 @@ public HalcyonSession(Request request) { setLocale(Locale.ENGLISH); ServletWebRequest req = (ServletWebRequest) request; KeycloakSecurityContext securityContext = (KeycloakSecurityContext) req.getContainerRequest().getAttribute(KeycloakSecurityContext.class.getName()); - AccessToken token2 = securityContext.getToken(); - this.token = securityContext.getTokenString(); - //realm = securityContext.getRealm(); - //uid = token2.getSubject(); - //name = token2.getName(); - //email = token2.getEmail(); - uuid = "urn:uuid:"+token2.getSubject(); - principal = new HalcyonPrincipal(uuid); - //Map other = token2.getOtherClaims(); - //webid = (String) other.get("webid"); - ResteasyClientBuilder builder = (ResteasyClientBuilder) ClientBuilder.newBuilder(); - builder.disableTrustManager(); - ResteasyClient client = builder.build(); - client.register(KeycloakTokenFilter.class); - String cmd = s.getProxyHostName()+"/auth/admin/realms/"+HalcyonSettings.realm+"/users"; - ResteasyWebTarget target = client.target(cmd); - Invocation.Builder zam = target.request(); - Response r = zam.get(); - Model da = ModelFactory.createDefaultModel(); - if (r.getStatus()==200) { - String json = r.readEntity(String.class); - da.add(ParseUsers(json)); + if (securityContext==null) { + uuid = "urn:uuid:"+UUID.randomUUID().toString(); + token = null; + principal = new HalcyonPrincipal(uuid, true); } else { - System.out.println("not able to update/Parse users..."); + AccessToken token2 = securityContext.getToken(); + this.token = securityContext.getTokenString(); + uuid = "urn:uuid:"+token2.getSubject(); + principal = new HalcyonPrincipal(uuid, false); } - r = client.target(s.getProxyHostName()+"/auth/admin/realms/"+HalcyonSettings.realm+"/groups").request().get(); - if (r.getStatus()==200) { - String json = r.readEntity(String.class); - da.add(ParseGroups(json)); - ParameterizedSparqlString pss = new ParameterizedSparqlString("select distinct ?s where {?s a so:Organization}"); - pss.setNsPrefix("so", SchemaDO.NS); - ResultSet rs = QueryExecutionFactory.create(pss.toString(),da).execSelect(); - rs.forEachRemaining(qs ->{ - Resource gg = qs.getResource("s"); - Response rr = client.target(s.getProxyHostName()+"/auth/admin/realms/"+HalcyonSettings.realm+"/groups/"+gg.getURI().substring(9)+"/members").request().get(); - if (rr.getStatus()==200) { - String json2 = rr.readEntity(String.class); - JsonReader jr = Json.createReader(new StringReader(json2)); - JsonArray ja = jr.readArray(); - ja.forEach(p->{ - Resource pp = da.createResource("urn:uuid:"+p.asJsonObject().getString("id")); - da.add(gg,SchemaDO.member,pp); - da.add(pp,SchemaDO.memberOf,gg); - }); + + if (securityContext!=null) { + ResteasyClientBuilder builder = (ResteasyClientBuilder) ClientBuilder.newBuilder(); + builder.disableTrustManager(); + ResteasyClient client = builder.build(); + client.register(KeycloakTokenFilter.class); + String cmd = s.getProxyHostName()+"/auth/admin/realms/"+HalcyonSettings.realm+"/users"; + ResteasyWebTarget target = client.target(cmd); + Invocation.Builder zam = target.request(); + Response r = zam.get(); + Model da = ModelFactory.createDefaultModel(); + if (r.getStatus()==200) { + String json = r.readEntity(String.class); + da.add(ParseUsers(json)); + } else { + System.out.println("not able to update/Parse users..."); + } + r = client.target(s.getProxyHostName()+"/auth/admin/realms/"+HalcyonSettings.realm+"/groups").request().get(); + if (r.getStatus()==200) { + String json = r.readEntity(String.class); + da.add(ParseGroups(json)); + ParameterizedSparqlString pss = new ParameterizedSparqlString("select distinct ?s where {?s a so:Organization}"); + pss.setNsPrefix("so", SchemaDO.NS); + ResultSet rs = QueryExecutionFactory.create(pss.toString(),da).execSelect(); + rs.forEachRemaining(qs ->{ + Resource gg = qs.getResource("s"); + Response rr = client.target(s.getProxyHostName()+"/auth/admin/realms/"+HalcyonSettings.realm+"/groups/"+gg.getURI().substring(9)+"/members").request().get(); + if (rr.getStatus()==200) { + String json2 = rr.readEntity(String.class); + JsonReader jr = Json.createReader(new StringReader(json2)); + JsonArray ja = jr.readArray(); + ja.forEach(p->{ + Resource pp = da.createResource("urn:uuid:"+p.asJsonObject().getString("id")); + da.add(gg,SchemaDO.member,pp); + da.add(pp,SchemaDO.memberOf,gg); + }); + } + }); + da.createResource(HAL.Anonymous.toString()) + .addProperty(RDF.type, SchemaDO.Organization) + .addProperty(SchemaDO.name, "Anonymous Sessions"); + System.out.println("================================"); + RDFDataMgr.write(System.out, da, RDFFormat.TURTLE_PRETTY); + System.out.println("================================"); + DataCore dc = DataCore.getInstance(); + if (dc.getDataset()!=null) { + System.out.println("DataCore online....\nUpdating Groups and Users..."); + DataCore.getInstance().replaceNamedGraph(HAL.GroupsAndUsers, da); + } else { + System.out.println("DataCore NOT online...."); } - }); - DataCore dc = DataCore.getInstance(); - if (dc.getDataset()!=null) { - System.out.println("DataCore online....\nUpdating Groups and Users..."); - DataCore.getInstance().replaceNamedGraph(HAL.GroupsAndUsers, da); } else { - System.out.println("DataCore NOT online...."); + System.out.println("not able to update/Parse groups..."); } - } else { - System.out.println("not able to update/Parse groups..."); } } diff --git a/src/main/java/com/ebremer/halcyon/gui/HomePage.html b/src/main/java/com/ebremer/halcyon/gui/HomePage.html index e4ce6b60..15e291a9 100644 --- a/src/main/java/com/ebremer/halcyon/gui/HomePage.html +++ b/src/main/java/com/ebremer/halcyon/gui/HomePage.html @@ -20,12 +20,19 @@

Halcyon

Version 0.0.0



-

Version 0.0.0

+

Version 0.1.0

??/??/????
+
    +
  • +
+
+

Version 0.0.0

+ 03/07/2023

diff --git a/src/main/java/com/ebremer/halcyon/gui/Public.html b/src/main/java/com/ebremer/halcyon/gui/Public.html new file mode 100644 index 00000000..15e291a9 --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/gui/Public.html @@ -0,0 +1,62 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/ebremer/halcyon/gui/Public.java b/src/main/java/com/ebremer/halcyon/gui/Public.java new file mode 100644 index 00000000..236cc8e2 --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/gui/Public.java @@ -0,0 +1,14 @@ +package com.ebremer.halcyon.gui; + +import com.ebremer.halcyon.wicket.BasePage; +import org.apache.wicket.devutils.stateless.StatelessComponent; + +@StatelessComponent +public class Public extends BasePage { + private static final long serialVersionUID = 1L; + + public Public() { + + } + +} \ No newline at end of file diff --git a/src/main/java/com/ebremer/halcyon/imagebox/ImageReaderPool.java b/src/main/java/com/ebremer/halcyon/imagebox/ImageReaderPool.java index cdacbc38..c75d9ec5 100644 --- a/src/main/java/com/ebremer/halcyon/imagebox/ImageReaderPool.java +++ b/src/main/java/com/ebremer/halcyon/imagebox/ImageReaderPool.java @@ -16,13 +16,14 @@ public ImageReaderPool() {} public static synchronized ImageReaderKeyedPool getPool() { if (pool == null) { GenericKeyedObjectPoolConfig config = new GenericKeyedObjectPoolConfig<>(); - config.setMaxTotalPerKey(6); + config.setMaxTotalPerKey(1); config.setMinIdlePerKey(0); - config.setMaxWait(Duration.ofMillis(10000)); + config.setMaxWait(Duration.ofMillis(60000)); config.setBlockWhenExhausted(true); - config.setTimeBetweenEvictionRuns(Duration.ofMillis(10000)); + config.setMinEvictableIdleTime(Duration.ofMillis(60000)); + config.setTimeBetweenEvictionRuns(Duration.ofMillis(60000)); pool = new ImageReaderKeyedPool<>(new ImageReaderPoolFactory(),config); } return pool; } -} \ No newline at end of file +} diff --git a/src/main/java/com/ebremer/halcyon/imagebox/ImageReaderPoolFactory.java b/src/main/java/com/ebremer/halcyon/imagebox/ImageReaderPoolFactory.java index 6321bb9e..ad774acc 100644 --- a/src/main/java/com/ebremer/halcyon/imagebox/ImageReaderPoolFactory.java +++ b/src/main/java/com/ebremer/halcyon/imagebox/ImageReaderPoolFactory.java @@ -23,7 +23,9 @@ public PooledObject wrap(NeoTiler value) { @Override public void destroyObject(String key, PooledObject p, DestroyMode mode) throws Exception { - //System.out.println("Destroying Image Reader "); + System.out.println("Destroying Image Reader ---> "+key); + NeoTiler nt = (NeoTiler) p.getObject(); + nt.close(); super.destroyObject(key, p, mode); } } \ No newline at end of file diff --git a/src/main/java/com/ebremer/halcyon/imagebox/JwtInterceptor.java b/src/main/java/com/ebremer/halcyon/imagebox/JwtInterceptor.java new file mode 100644 index 00000000..3c00ce98 --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/imagebox/JwtInterceptor.java @@ -0,0 +1,42 @@ +package com.ebremer.halcyon.imagebox; + +import java.io.IOException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; + +public class JwtInterceptor implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletResponse httpResponse = (HttpServletResponse) response; + //System.out.println("--------------------> postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) "); + //httpResponse.setHeader("Custom-Header", "Custom-Value"); + + /* + KeycloakSecurityContext securityContext = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName()); + if (securityContext != null) { + System.out.println("ADDING TOKEN!!!"); + String jwtToken = securityContext.getTokenString(); + httpResponse.setHeader("token", jwtToken); + } else { + System.out.println("NOTHING TO ADD!!!"); + } + */ + chain.doFilter(request, response); + } + + @Override + public void destroy() { + } + +} diff --git a/src/main/java/com/ebremer/halcyon/imagebox/Main.java b/src/main/java/com/ebremer/halcyon/imagebox/Main.java index a44d105f..3b8aeb8f 100644 --- a/src/main/java/com/ebremer/halcyon/imagebox/Main.java +++ b/src/main/java/com/ebremer/halcyon/imagebox/Main.java @@ -1,13 +1,22 @@ package com.ebremer.halcyon.imagebox; +import com.ebremer.halcyon.keycloak.HALKeycloakOIDCFilter; import com.ebremer.halcyon.HalcyonSettings; import com.ebremer.halcyon.INIT; +import com.ebremer.halcyon.fuseki.HalcyonProxyServlet; +import com.ebremer.halcyon.datum.SessionsManager; +import com.ebremer.halcyon.fuseki.jwt.GetPublicKey; +import com.ebremer.halcyon.fuseki.jwt.KeycloakPublicKeyFetcher; import com.ebremer.halcyon.gui.HalcyonApplication; import io.undertow.UndertowOptions; +import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; @@ -21,6 +30,7 @@ import org.apache.wicket.protocol.http.ContextParamWebApplicationFactory; import org.apache.wicket.protocol.http.WicketFilter; import org.keycloak.adapters.servlet.KeycloakOIDCFilter; +import org.keycloak.adapters.spi.SessionIdMapper; import org.mitre.dsmiley.httpproxy.ProxyServlet; import org.springframework.boot.Banner.Mode; import org.springframework.boot.SpringApplication; @@ -29,21 +39,32 @@ import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @SpringBootApplication(exclude = LiquibaseAutoConfiguration.class) public class Main { private final HalcyonSettings settings = HalcyonSettings.getSettings(); + private static final SessionIdMapper sessionidmapper = SessionsManager.getSessionsManager().getSessionIdMapper(); + + public static SessionIdMapper getSessionIdMapper() { + return sessionidmapper; + } @Bean + @Order(Ordered.HIGHEST_PRECEDENCE) public ServletRegistrationBean proxyServletRegistrationBean() { - ServletRegistrationBean bean = new ServletRegistrationBean(new ProxyServlet(), "/sparql/*"); + ServletRegistrationBean bean = new ServletRegistrationBean(new HalcyonProxyServlet(), "/sparql/*"); bean.addInitParameter("targetUri", "http://localhost:8887/rdf"); + //bean.addInitParameter("targetUri", "https://e1d0d1f2f7f7ecfb2e5ff7faef143702.m.pipedream.net"); + bean.addInitParameter(ProxyServlet.P_PRESERVECOOKIES, "true"); + bean.addInitParameter(ProxyServlet.P_HANDLEREDIRECTS, "true"); + //bean.addInitParameter(ProxyServlet.P_HANDLECOMPRESSION, "true"); return bean; } @@ -78,7 +99,6 @@ public UndertowServletWebServerFactory embeddedServletContainerFactory() { } @Bean - @Order(Ordered.LOWEST_PRECEDENCE) ServletRegistrationBean iboxServletRegistration () { System.out.println("iboxServletRegistration order: "+Ordered.LOWEST_PRECEDENCE); ServletRegistrationBean srb = new ServletRegistrationBean(); @@ -86,33 +106,34 @@ ServletRegistrationBean iboxServletRegistration () { srb.setUrlMappings(Arrays.asList("/iiif/*")); return srb; } - - @Bean - @Order(20) - ServletRegistrationBean HalcyonServletRegistration () { - ServletRegistrationBean srb = new ServletRegistrationBean(); - srb.setServlet(new HalcyonServlet()); - srb.setUrlMappings(Arrays.asList("/halcyon/*")); - return srb; - } @Bean - @Order(Ordered.HIGHEST_PRECEDENCE) public FilterRegistrationBean KeycloakOIDCFilterFilterRegistration(){ System.out.println("KeycloakOIDCFilterFilterRegistration order: "+Ordered.HIGHEST_PRECEDENCE); + HALKeycloakOIDCFilter filter = new HALKeycloakOIDCFilter(); + //filter.setSessionIdMapper(SessionsManager.getSessionsManager().getSessionIdMapper()); + filter.setSessionIdMapper(getSessionIdMapper()); FilterRegistrationBean registration = new FilterRegistrationBean<>(); - registration.setFilter(new HALKeycloakOIDCFilter()); + registration.setFilter(filter); registration.setName("keycloak"); registration.addUrlPatterns("/*"); + registration.setOrder(0); registration.addInitParameter(KeycloakOIDCFilter.CONFIG_FILE_PARAM, "keycloak.json"); - //registration.addInitParameter(KeycloakOIDCFilter.SKIP_PATTERN_PARAM, "(^/HalcyonStorage/.*svs$|^/gui/vendor/openseadragon/.*|^/auth/.*|^/favicon.ico|^/iiif/.*|^/auth/.*|^/halcyon/.*|^/HalcyonStorage/.*$)"); - registration.addInitParameter(KeycloakOIDCFilter.SKIP_PATTERN_PARAM, "(^/gui/vendor/openseadragon/.*|^/auth/.*|^/favicon.ico|^/auth/.*$)"); + registration.addInitParameter(KeycloakOIDCFilter.SKIP_PATTERN_PARAM, "(^/sparql.*|^/wicket/resource/com.*\\.css|^/gui/public|^/gui/vendor/openseadragon/.*|^/auth/.*|^/favicon.ico|^/auth/.*$)"); registration.setEnabled(true); return registration; } @Bean - @Order(1) + public FilterRegistrationBean headerAddingFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new JwtInterceptor()); + registrationBean.addUrlPatterns("/*"); + registrationBean.setOrder(1); + return registrationBean; + } + + @Bean public FilterRegistrationBean wicketFilterRegistration(){ HalcyonApplication hal = new HalcyonApplication(); hal.setConfigurationType(RuntimeConfigurationType.DEPLOYMENT); @@ -120,15 +141,25 @@ public FilterRegistrationBean wicketFilterRegistration(){ filter.setFilterPath("/"); FilterRegistrationBean registration = new FilterRegistrationBean<>(); registration.setFilter(filter); + registration.setOrder(2); registration.addInitParameter(ContextParamWebApplicationFactory.APP_CLASS_PARAM, HalcyonApplication.class.getName()); registration.addInitParameter(WicketFilter.FILTER_MAPPING_PARAM, "/"); registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.FORWARD); return registration; } - + + @Bean + ServletRegistrationBean HalcyonServletRegistration () { + ServletRegistrationBean srb = new ServletRegistrationBean(); + srb.setServlet(new HalcyonServlet()); + srb.setOrder(20); + srb.setUrlMappings(Arrays.asList("/halcyon/*")); + return srb; + } @Configuration - public class StaticResourceConfiguration extends WebMvcConfigurerAdapter { + public class HalcyonResourceConfiguration implements WebMvcConfigurer { + @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { String mv = settings.getMultiewerLocation(); @@ -183,16 +214,17 @@ private static KeyStore loadKeyStore(final String storeLoc, final String storePw } } - public static void main(String[] args) { - //ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); - //root.setLevel(ch.qos.logback.classic.Level.ALL); - // System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "debug"); - // System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "debug"); - + public static void main(String[] args) throws NoSuchAlgorithmException { INIT i = new INIT(); i.init(); SpringApplication app = new SpringApplication(Main.class); app.setBannerMode(Mode.CONSOLE); - app.run(args); + ApplicationContext yay = app.run(args); + System.out.println("===================== " +app.getWebApplicationType()); + //ApplicationContext ha = (ApplicationContext) yay; + //WebServerApplicationContext webContext = (WebServerApplicationContext) ha; + //System.out.println(webContext.getWebServer()); + //UndertowServletWebServer ut = (UndertowServletWebServer) webContext.getWebServer(); + //SessionManager sm = ut.getDeploymentManager().getDeployment().getSessionManager(); } } diff --git a/src/main/java/com/ebremer/halcyon/imagebox/NeoTiler.java b/src/main/java/com/ebremer/halcyon/imagebox/NeoTiler.java index d4175aa3..ce272b60 100644 --- a/src/main/java/com/ebremer/halcyon/imagebox/NeoTiler.java +++ b/src/main/java/com/ebremer/halcyon/imagebox/NeoTiler.java @@ -41,11 +41,9 @@ import loci.formats.gui.AWTImageTools; import loci.formats.in.NDPIReader; import loci.formats.in.SVSReader; -//import loci.formats.in.TiffReader; import com.ebremer.halcyon.imagebox.experimental.TiffReader; import java.nio.file.Path; import java.util.HashMap; -import java.util.Iterator; import loci.formats.meta.IMetadata; import loci.formats.meta.MetadataStore; import loci.formats.services.OMEXMLService; @@ -88,21 +86,16 @@ public class NeoTiler { private String cookie = null; public NeoTiler(String f) { - //System.out.println("NEOTILER : "+f); DebugTools.enableLogging("ERROR"); - //DebugTools.enableLogging("ALL"); lastaccessed = System.nanoTime(); String getthis; - //HalcyonSession session = HalcyonSession.get(); HalcyonSettings settings = HalcyonSettings.getSettings(); String mainpath = settings.getHostName(); Path x = null; if (f.startsWith(mainpath)) { String cut = f.substring(mainpath.length()); HashMap mappings = settings.getmappings(); - Iterator i = mappings.keySet().iterator(); - while (i.hasNext()) { - String key = i.next(); + for (String key : mappings.keySet()) { if (cut.startsWith(key)) { String chunk = cut.substring(key.length()); x = Path.of(mappings.get(key), chunk); @@ -110,17 +103,13 @@ public NeoTiler(String f) { } } if (x !=null) { - //System.out.println("SUPER LOCAL PROTOCOL ACCESS"); getthis = x.toString(); } else if ((f.startsWith("https://")||f.startsWith("http://"))) { - //System.out.println("WEB PROTOCOL ACCESS : "+f); HTTPIRandomAccess bbb = new HTTPIRandomAccess(f); - //bbb.setCookie(cookie); bbb.init(); getthis = "charm"; Location.mapFile(getthis, bbb); } else { - //System.out.println("LOCAL PROTOCOL ACCESS"); getthis = f; } String fileType = f.substring(f.lastIndexOf('.') + 1); @@ -153,6 +142,7 @@ public NeoTiler(String f) { if (!borked) { newRoot = (OMEXMLMetadataRoot) meta.getRoot(); numi = reader.getSeriesCount(); + // System.out.println("getSeriesCount : "+numi); if (getthis.endsWith(".vsi")) { lowerbound = MaxImage(reader); } @@ -167,9 +157,9 @@ public NeoTiler(String f) { py = new int[numi]; pr = new int[numi]; pi = new int[numi]; - for (int j=0;j>> "+big.sizeX+","+big.sizeY+" aspect ratio : "+(((float) big.sizeX)/((float)big.sizeY))); + // System.out.println(j+" >>> "+big.sizeX+","+big.sizeY+" aspect ratio : "+(((float) big.sizeX)/((float)big.sizeY))); } big = reader.getCoreMetadataList().get(lowerbound); float ratio = ((float) big.sizeX)/((float) big.sizeY); @@ -209,6 +199,27 @@ public NeoTiler(String f) { } } + public void SortImages() { + boolean sorted = false; + while (!sorted) { + sorted = true; + for (int i = 0; i=0;j--) { + for (int j=upperbound;j>=0;j--) { reader.setSeries(j); Resource size = m.createResource(); m.addLiteral(size,IIIF.width,reader.getSizeX()); @@ -347,6 +345,7 @@ public BufferedImage FetchImage(int x, int y, int w, int h, int tx, int ty, Stri jj++; } if (jj>numi) {jj--;} + //System.out.println("selecting series : "+pi[jj]); reader.setSeries(pi[jj]); double rr = ((double) reader.getSizeX())/((double) iWidth); int gx=(int) (x*rr); @@ -369,7 +368,7 @@ public BufferedImage FetchImage(int x, int y, int w, int h, int tx, int ty, Stri } private BufferedImage GrabImage(int xpos, int ypos, int width, int height, String type) { - //System.out.println("grab image : "+xpos+ " "+ypos+" "+width+" "+height+"=== "+type); + //System.out.println("grab image : "+xpos+ " "+ypos+" "+width+" "+height+" === "+type); meta.setRoot(newRoot); meta.setPixelsSizeX(new PositiveInteger(width), 0); meta.setPixelsSizeY(new PositiveInteger(height), 0); @@ -384,4 +383,4 @@ private BufferedImage GrabImage(int xpos, int ypos, int width, int height, Strin } return bb; } -} \ No newline at end of file +} diff --git a/src/main/java/com/ebremer/halcyon/imagebox/experimental/MinimalTiffReader.java b/src/main/java/com/ebremer/halcyon/imagebox/experimental/MinimalTiffReader.java index f6774741..0112e9fe 100644 --- a/src/main/java/com/ebremer/halcyon/imagebox/experimental/MinimalTiffReader.java +++ b/src/main/java/com/ebremer/halcyon/imagebox/experimental/MinimalTiffReader.java @@ -1,7 +1,3 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ package com.ebremer.halcyon.imagebox.experimental; diff --git a/src/main/java/com/ebremer/halcyon/imagebox/experimental/TiffParser.java b/src/main/java/com/ebremer/halcyon/imagebox/experimental/TiffParser.java index bd20c385..e1281f5b 100644 --- a/src/main/java/com/ebremer/halcyon/imagebox/experimental/TiffParser.java +++ b/src/main/java/com/ebremer/halcyon/imagebox/experimental/TiffParser.java @@ -1,7 +1,3 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ package com.ebremer.halcyon.imagebox.experimental; import java.io.Closeable; diff --git a/src/main/java/com/ebremer/halcyon/imagebox/experimental/TiffReader.java b/src/main/java/com/ebremer/halcyon/imagebox/experimental/TiffReader.java index cec426a4..65073852 100644 --- a/src/main/java/com/ebremer/halcyon/imagebox/experimental/TiffReader.java +++ b/src/main/java/com/ebremer/halcyon/imagebox/experimental/TiffReader.java @@ -1,7 +1,3 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ package com.ebremer.halcyon.imagebox.experimental; import java.io.IOException; diff --git a/src/main/java/com/ebremer/halcyon/imagebox/iboxServlet.java b/src/main/java/com/ebremer/halcyon/imagebox/iboxServlet.java index 7097a4d3..847e8072 100644 --- a/src/main/java/com/ebremer/halcyon/imagebox/iboxServlet.java +++ b/src/main/java/com/ebremer/halcyon/imagebox/iboxServlet.java @@ -108,7 +108,7 @@ protected void doGet( HttpServletRequest request, HttpServletResponse response ) JPEGImageWriteParam jpegParams = new JPEGImageWriteParam(null); jpegParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); jpegParams.setCompressionQuality(0.7f); - ImageOutputStream imageOut=ImageIO.createImageOutputStream(baos); + ImageOutputStream imageOut = ImageIO.createImageOutputStream(baos); writer.setOutput(imageOut); writer.write(null,new IIOImage(originalImage,null,null),jpegParams); baos.flush(); @@ -140,10 +140,10 @@ protected void doGet( HttpServletRequest request, HttpServletResponse response ) nt.setURL(settings.getProxyHostName()+request.getRequestURI()+"?"+request.getQueryString()); response.setContentType("application/json"); response.setHeader("Access-Control-Allow-Origin", "*"); - PrintWriter writer = response.getWriter(); - writer.append(nt.GetImageInfo()); - writer.flush(); - writer.close(); + try (PrintWriter writer = response.getWriter()) { + writer.append(nt.GetImageInfo()); + writer.flush(); + } } else { System.out.println("unknown IIIF request"); } diff --git a/src/main/java/com/ebremer/halcyon/keycloak/HALInMemorySessionIdMapper.java b/src/main/java/com/ebremer/halcyon/keycloak/HALInMemorySessionIdMapper.java new file mode 100644 index 00000000..cf211fa8 --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/keycloak/HALInMemorySessionIdMapper.java @@ -0,0 +1,16 @@ +package com.ebremer.halcyon.keycloak; + +import org.keycloak.adapters.spi.InMemorySessionIdMapper; + +/** + * + * @author erich + */ +public class HALInMemorySessionIdMapper extends InMemorySessionIdMapper { + + @Override + public boolean hasSession(String id) { + System.out.println("HASSESSION --> "+id+" "+super.hasSession(id)); + return super.hasSession(id); + } +} diff --git a/src/main/java/com/ebremer/halcyon/imagebox/HALKeycloakOIDCFilter.java b/src/main/java/com/ebremer/halcyon/keycloak/HALKeycloakOIDCFilter.java similarity index 63% rename from src/main/java/com/ebremer/halcyon/imagebox/HALKeycloakOIDCFilter.java rename to src/main/java/com/ebremer/halcyon/keycloak/HALKeycloakOIDCFilter.java index 2fc6b019..ec142020 100644 --- a/src/main/java/com/ebremer/halcyon/imagebox/HALKeycloakOIDCFilter.java +++ b/src/main/java/com/ebremer/halcyon/keycloak/HALKeycloakOIDCFilter.java @@ -1,19 +1,17 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.ebremer.halcyon.imagebox; +package com.ebremer.halcyon.keycloak; import java.io.IOException; import java.util.List; import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.servlet.FilterHolder; +import org.keycloak.KeycloakSecurityContext; import org.keycloak.adapters.AuthenticatedActionsHandler; import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.PreAuthActionsHandler; @@ -23,6 +21,7 @@ import org.keycloak.adapters.servlet.OIDCServletHttpFacade; import org.keycloak.adapters.spi.AuthChallenge; import org.keycloak.adapters.spi.AuthOutcome; +import org.keycloak.adapters.spi.SessionIdMapper; import org.keycloak.adapters.spi.UserSessionManagement; /** @@ -30,7 +29,8 @@ * @author erich */ public class HALKeycloakOIDCFilter extends KeycloakOIDCFilter { - + private KeycloakOIDCFilterConfig config = null; + private boolean shouldSkip(HttpServletRequest request) { if (skipPattern == null) { return false; @@ -39,17 +39,42 @@ private boolean shouldSkip(HttpServletRequest request) { return skipPattern.matcher(requestPath).matches(); } + public void setConfig(KeycloakOIDCFilterConfig config) { + this.config = config; + } + + public void setSessionIdMapper(SessionIdMapper mapper) { + idMapper = mapper; + } + + @Override + public void init(final FilterConfig filterConfig) throws ServletException { + filterConfig.getInitParameterNames().asIterator().forEachRemaining(p->{ + System.out.println("PARAM --> "+p); + }); + + if (!filterConfig.getInitParameterNames().hasMoreElements()) { + super.init(config); + } else { + System.out.println("INIT -------------------> "+filterConfig.getClass().toGenericString()); + if (filterConfig instanceof FilterHolder fh) { + if (fh.getInitParameter(KeycloakOIDCFilter.CONFIG_FILE_PARAM)==null) { + fh.setInitParameter(KeycloakOIDCFilter.CONFIG_FILE_PARAM, "keycloak.json"); + } + } + super.init(filterConfig); + } + } + @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; - + System.out.println("doFilter =======> "+request.getRequestURI()); boolean skipme = shouldSkip(request); if (skipme) { chain.doFilter(req, res); return; - } else { - //System.out.println("SKIPME : "+skipme+" ===> "+request.getRequestURI()); } OIDCServletHttpFacade facade = new OIDCServletHttpFacade(request, response); @@ -69,14 +94,14 @@ public void logoutAll() { @Override public void logoutHttpSessions(List ids) { - //System.err.println("**************** logoutHttpSessions"); + System.err.println("**************** logoutHttpSessions"); for (String id : ids) { idMapper.removeSession(id); } } }, deploymentContext, facade); if (preActions.handleRequest()) { - //System.err.println("**************** preActions.handleRequest happened!"); + System.err.println("**************** preActions.handleRequest happened!"); return; } nodesRegistrationManagement.tryRegister(deployment); @@ -92,6 +117,19 @@ public void logoutHttpSessions(List ids) { if (actions.handledRequest()) { return; } else { + /* + KeycloakSecurityContext securityContext = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName()); + if (securityContext != null) { + + String jwtToken = securityContext.getTokenString(); + System.out.println("ADDING TOKEN!!! "+jwtToken); + HttpServletResponse httpResponse = (HttpServletResponse) response; + httpResponse.setHeader("token", jwtToken); + } else { + System.out.println("NOTHING TO ADD!!!"); + } + */ + HttpServletRequestWrapper wrapper = tokenStore.buildWrapper(); chain.doFilter(wrapper, res); return; diff --git a/src/main/java/com/ebremer/halcyon/keycloak/KeycloakOIDCFilterConfig.java b/src/main/java/com/ebremer/halcyon/keycloak/KeycloakOIDCFilterConfig.java new file mode 100644 index 00000000..b6952d43 --- /dev/null +++ b/src/main/java/com/ebremer/halcyon/keycloak/KeycloakOIDCFilterConfig.java @@ -0,0 +1,51 @@ +package com.ebremer.halcyon.keycloak; + +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; + +/** + * + * @author erich + */ +public class KeycloakOIDCFilterConfig implements FilterConfig { + private final String name; + private final HashMap params; + private ServletContext context; + + public KeycloakOIDCFilterConfig(String name) { + this.name = name; + params = new HashMap<>(); + } + + @Override + public String getFilterName() { + return name; + } + + @Override + public ServletContext getServletContext() { + return context; + } + + public void setContext(ServletContext context) { + this.context = context; + } + + @Override + public String getInitParameter(String name) { + return params.get(name); + } + + public KeycloakOIDCFilterConfig setInitParameter(String name, String value) { + params.put(name, value); + return this; + } + + @Override + public Enumeration getInitParameterNames() { + return Collections.enumeration(params.keySet()); + } +} diff --git a/src/main/java/com/ebremer/halcyon/gui/KeycloakTokenFilter.java b/src/main/java/com/ebremer/halcyon/keycloak/KeycloakTokenFilter.java similarity index 80% rename from src/main/java/com/ebremer/halcyon/gui/KeycloakTokenFilter.java rename to src/main/java/com/ebremer/halcyon/keycloak/KeycloakTokenFilter.java index 145968e2..9e55f468 100644 --- a/src/main/java/com/ebremer/halcyon/gui/KeycloakTokenFilter.java +++ b/src/main/java/com/ebremer/halcyon/keycloak/KeycloakTokenFilter.java @@ -1,8 +1,4 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ -package com.ebremer.halcyon.gui; +package com.ebremer.halcyon.keycloak; import java.io.IOException; import javax.servlet.http.HttpServletRequest; diff --git a/src/main/java/com/ebremer/halcyon/sparql/Sparql.html b/src/main/java/com/ebremer/halcyon/sparql/Sparql.html index 879df738..15e665c4 100644 --- a/src/main/java/com/ebremer/halcyon/sparql/Sparql.html +++ b/src/main/java/com/ebremer/halcyon/sparql/Sparql.html @@ -12,13 +12,13 @@

SPARQL Endpoint