Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2c460b3
Package model and initial implementation
namedgraph Nov 30, 2025
1a00e2c
Removed `PackageManager`
namedgraph Nov 30, 2025
03019b3
HTTP unit tests for packages
namedgraph Nov 30, 2025
e047ff6
Package implementation and test fixes
namedgraph Dec 1, 2025
fa8e8ea
Import fix
namedgraph Dec 25, 2025
c4d43cd
Ontology import fixes
namedgraph Dec 25, 2025
aee36c4
Package installation fixes
namedgraph Dec 25, 2025
f886033
Renamed script
namedgraph Dec 25, 2025
47aa3ad
Removed `/transform` from publicly allowed endpoints
namedgraph Dec 26, 2025
61377ab
Package test fixes
namedgraph Dec 26, 2025
d8c78c1
Added getter
namedgraph Dec 26, 2025
e3a1855
Refactored `XSLTMasterUpdater`
namedgraph Dec 26, 2025
33b9c0b
Refactored `XSLTMasterUpdater`
namedgraph Dec 26, 2025
0ca28b3
Updated SKOS package ontology
namedgraph Dec 26, 2025
8c7a425
Fixed class filename
namedgraph Dec 26, 2025
a6de66f
Added SKOS import to the SKOS package ontology
namedgraph Dec 27, 2025
cac69b2
Additional install/uninstall tests
namedgraph Dec 27, 2025
c3aef03
Undo `patch` method changes
namedgraph Dec 27, 2025
659788b
Replaced `LinkedDataClient` with `GraphStoreClient`
namedgraph Dec 30, 2025
ee7047b
Core SNAPSHOT bump
namedgraph Jan 1, 2026
3b2dedb
Updated POM
namedgraph Jan 1, 2026
b419f51
`PATCH` update fixes
namedgraph Jan 1, 2026
a4d5b6a
Response closure fixes
namedgraph Jan 1, 2026
2518bc6
Package ontology URI fix
namedgraph Jan 1, 2026
06451cc
Test fix
namedgraph Jan 1, 2026
cbdaf68
Varnish ban fix in `ClearOntology`
namedgraph Jan 2, 2026
6c71581
HTTP test fixes
namedgraph Jan 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
File renamed without changes.
File renamed without changes.
103 changes: 103 additions & 0 deletions bin/admin/packages/install-package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/usr/bin/env bash

print_usage()
{
printf "Installs a LinkedDataHub package.\n"
printf "\n"
printf "Usage: %s options\n" "$0"
printf "\n"
printf "Options:\n"
printf " -b, --base BASE_URL Base URL of the application\n"
printf " -f, --cert-pem-file CERT_FILE .pem file with the WebID certificate of the agent\n"
printf " -p, --cert-password CERT_PASSWORD Password of the WebID certificate\n"
printf " --proxy PROXY_URL The host this request will be proxied through (optional)\n"
printf " --package PACKAGE_URI URI of the package to install (e.g., https://packages.linkeddatahub.com/skos/#this)\n"
printf "\n"
printf "Example:\n"
printf " %s -b https://localhost:4443/ -f ssl/owner/cert.pem -p Password --package https://packages.linkeddatahub.com/skos/#this\n" "$0"
}

hash curl 2>/dev/null || { echo >&2 "curl not on \$PATH. Aborting."; exit 1; }

unknown=()
while [[ $# -gt 0 ]]
do
key="$1"

case $key in
-b|--base)
base="$2"
shift # past argument
shift # past value
;;
-f|--cert-pem-file)
cert_pem_file="$2"
shift # past argument
shift # past value
;;
-p|--cert-password)
cert_password="$2"
shift # past argument
shift # past value
;;
--proxy)
proxy="$2"
shift # past argument
shift # past value
;;
--package)
package_uri="$2"
shift # past argument
shift # past value
;;
*) # unknown option
unknown+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
set -- "${unknown[@]}" # restore args

if [ -z "$base" ] ; then
print_usage
exit 1
fi
if [ -z "$cert_pem_file" ] ; then
print_usage
exit 1
fi
if [ -z "$cert_password" ] ; then
print_usage
exit 1
fi
if [ -z "$package_uri" ] ; then
print_usage
exit 1
fi

# Convert base URL to admin base URL
admin_uri() {
local uri="$1"
echo "$uri" | sed 's|://|://admin.|'
}

admin_base=$(admin_uri "$base")
target_url="${admin_base}packages/install"

if [ -n "$proxy" ]; then
admin_proxy=$(admin_uri "$proxy")
# rewrite target hostname to proxy hostname
url_host=$(echo "$target_url" | cut -d '/' -f 1,2,3)
proxy_host=$(echo "$admin_proxy" | cut -d '/' -f 1,2,3)
final_url="${target_url/$url_host/$proxy_host}"
else
final_url="$target_url"
fi

# POST to packages/install endpoint
curl -k -w "%{http_code}\n" -E "${cert_pem_file}":"${cert_password}" \
-X POST \
-H "Accept: text/turtle" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "package-uri=${package_uri}" \
"${final_url}"
3 changes: 2 additions & 1 deletion config/system.trig
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
lapp:origin <https://admin.localhost:4443> ;
ldt:ontology <https://w3id.org/atomgraph/linkeddatahub/admin#> ;
ldt:service <urn:linkeddatahub:services/admin> ;
ac:stylesheet <static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/admin/layout.xsl> ;
ac:stylesheet <static/xsl/admin/layout.xsl> ;
lapp:endUserApplication <urn:linkeddatahub:apps/end-user> ;
lapp:frontendProxy <http://varnish-frontend:6060/> .

Expand All @@ -41,6 +41,7 @@
lapp:origin <https://localhost:4443> ;
ldt:ontology <https://localhost:4443/ns#> ;
ldt:service <urn:linkeddatahub:services/end-user> ;
ac:stylesheet <static/xsl/layout.xsl> ;
lapp:adminApplication <urn:linkeddatahub:apps/admin> ;
lapp:frontendProxy <http://varnish-frontend:6060/> ;
lapp:public true .
Expand Down
16 changes: 16 additions & 0 deletions http-tests/admin/packages/install-package-400.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -euo pipefail

initialize_dataset "$END_USER_BASE_URL" "$TMP_END_USER_DATASET" "$END_USER_ENDPOINT_URL"
initialize_dataset "$ADMIN_BASE_URL" "$TMP_ADMIN_DATASET" "$ADMIN_ENDPOINT_URL"
purge_cache "$END_USER_VARNISH_SERVICE"
purge_cache "$ADMIN_VARNISH_SERVICE"
purge_cache "$FRONTEND_VARNISH_SERVICE"

# Missing package-uri parameter should return 400 Bad Request
curl -k -w "%{http_code}\n" -o /dev/null -s \
-E "$OWNER_CERT_FILE":"$OWNER_CERT_PWD" \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
"${ADMIN_BASE_URL}packages/install" \
| grep -q "$STATUS_BAD_REQUEST"
16 changes: 16 additions & 0 deletions http-tests/admin/packages/install-package-403.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -euo pipefail

initialize_dataset "$END_USER_BASE_URL" "$TMP_END_USER_DATASET" "$END_USER_ENDPOINT_URL"
initialize_dataset "$ADMIN_BASE_URL" "$TMP_ADMIN_DATASET" "$ADMIN_ENDPOINT_URL"
purge_cache "$END_USER_VARNISH_SERVICE"
purge_cache "$ADMIN_VARNISH_SERVICE"
purge_cache "$FRONTEND_VARNISH_SERVICE"

# Unauthorized access (without certificate) should return 403 Forbidden
curl -k -w "%{http_code}\n" -o /dev/null -s \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "package-uri=https://packages.linkeddatahub.com/skos/#this" \
"${ADMIN_BASE_URL}packages/install" \
| grep -q "$STATUS_FORBIDDEN"
18 changes: 18 additions & 0 deletions http-tests/admin/packages/install-package-422.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -euo pipefail

initialize_dataset "$END_USER_BASE_URL" "$TMP_END_USER_DATASET" "$END_USER_ENDPOINT_URL"
initialize_dataset "$ADMIN_BASE_URL" "$TMP_ADMIN_DATASET" "$ADMIN_ENDPOINT_URL"
purge_cache "$END_USER_VARNISH_SERVICE"
purge_cache "$ADMIN_VARNISH_SERVICE"
purge_cache "$FRONTEND_VARNISH_SERVICE"

# Invalid/non-existent package URI should return 422 Unprocessable Entity
# (package loading failed)
curl -k -w "%{http_code}\n" -o /dev/null -s \
-E "$OWNER_CERT_FILE":"$OWNER_CERT_PWD" \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "package-uri=https://packages.linkeddatahub.com/nonexistent/#package" \
"${ADMIN_BASE_URL}packages/install" \
| grep -q "$STATUS_UNPROCESSABLE_ENTITY"
35 changes: 35 additions & 0 deletions http-tests/admin/packages/install-package-ontology.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bash
set -euo pipefail

initialize_dataset "$END_USER_BASE_URL" "$TMP_END_USER_DATASET" "$END_USER_ENDPOINT_URL"
initialize_dataset "$ADMIN_BASE_URL" "$TMP_ADMIN_DATASET" "$ADMIN_ENDPOINT_URL"
purge_cache "$END_USER_VARNISH_SERVICE"
purge_cache "$ADMIN_VARNISH_SERVICE"
purge_cache "$FRONTEND_VARNISH_SERVICE"

# test package URI (SKOS package)
package_uri="https://packages.linkeddatahub.com/skos/#this"
package_ontology_uri="https://raw.githubusercontent.com/AtomGraph/LinkedDataHub-Apps/refs/heads/develop/packages/skos/ns.ttl#"
namespace_ontology_uri="${END_USER_BASE_URL}ns#"

# install package via POST to packages/install endpoint
curl -k -w "%{http_code}\n" -o /dev/null -f -s \
-E "$OWNER_CERT_FILE":"$OWNER_CERT_PWD" \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "package-uri=$package_uri" \
"${ADMIN_BASE_URL}packages/install" \
| grep -q "$STATUS_SEE_OTHER"

# verify owl:imports triple was added to namespace graph
curl -k -s \
-H "Accept: application/n-triples" \
"${END_USER_BASE_URL}ns" \
| grep -q "<${namespace_ontology_uri}> <http://www.w3.org/2002/07/owl#imports> <${package_ontology_uri}>"

# verify package ontology document was created (hash of package ontology URI)
package_ontology_hash=$(echo -n "$package_ontology_uri" | shasum -a 1 | cut -d' ' -f1)
curl -k -w "%{http_code}\n" -o /dev/null -s \
-E "$OWNER_CERT_FILE":"$OWNER_CERT_PWD" \
"${ADMIN_BASE_URL}ontologies/${package_ontology_hash}/" \
| grep -qE "^($STATUS_OK|$STATUS_NOT_MODIFIED)$"
28 changes: 28 additions & 0 deletions http-tests/admin/packages/install-package-stylesheet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
set -euo pipefail

initialize_dataset "$END_USER_BASE_URL" "$TMP_END_USER_DATASET" "$END_USER_ENDPOINT_URL"
initialize_dataset "$ADMIN_BASE_URL" "$TMP_ADMIN_DATASET" "$ADMIN_ENDPOINT_URL"
purge_cache "$END_USER_VARNISH_SERVICE"
purge_cache "$ADMIN_VARNISH_SERVICE"
purge_cache "$FRONTEND_VARNISH_SERVICE"

# test package URI (SKOS package)
package_uri="https://packages.linkeddatahub.com/skos/#this"

# install package via POST to packages/install endpoint
curl -k -w "%{http_code}\n" -o /dev/null -f -s \
-E "$OWNER_CERT_FILE":"$OWNER_CERT_PWD" \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "package-uri=$package_uri" \
"${ADMIN_BASE_URL}packages/install" \
| grep -q "$STATUS_SEE_OTHER"

# verify package stylesheet was installed (should return 200)
curl -k -f -s -o /dev/null \
"$END_USER_BASE_URL"static/com/linkeddatahub/packages/skos/layout.xsl

# verify master stylesheet was regenerated and includes package import
curl -k -s "${END_USER_BASE_URL}static/xsl/layout.xsl" \
| grep -q "com/linkeddatahub/packages/skos/layout.xsl"
53 changes: 53 additions & 0 deletions http-tests/admin/packages/install-uninstall-package-ontology.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env bash
set -euo pipefail

initialize_dataset "$END_USER_BASE_URL" "$TMP_END_USER_DATASET" "$END_USER_ENDPOINT_URL"
initialize_dataset "$ADMIN_BASE_URL" "$TMP_ADMIN_DATASET" "$ADMIN_ENDPOINT_URL"
purge_cache "$END_USER_VARNISH_SERVICE"
purge_cache "$ADMIN_VARNISH_SERVICE"
purge_cache "$FRONTEND_VARNISH_SERVICE"

# test package URI (SKOS package)
package_uri="https://packages.linkeddatahub.com/skos/#this"
package_ontology_uri="https://raw.githubusercontent.com/AtomGraph/LinkedDataHub-Apps/refs/heads/develop/packages/skos/ns.ttl#"
namespace_ontology_uri="${END_USER_BASE_URL}ns#"

# install package
curl -k -w "%{http_code}\n" -o /dev/null -f -s \
-E "$OWNER_CERT_FILE":"$OWNER_CERT_PWD" \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "package-uri=$package_uri" \
"$ADMIN_BASE_URL"packages/install \
| grep -q "$STATUS_SEE_OTHER"

# verify owl:imports triple was added
curl -k -s \
-H "Accept: application/n-triples" \
"${END_USER_BASE_URL}ns" \
| grep -q "<${namespace_ontology_uri}> <http://www.w3.org/2002/07/owl#imports> <${package_ontology_uri}>"

# verify package ontology document exists
package_ontology_hash=$(echo -n "$package_ontology_uri" | shasum -a 1 | cut -d' ' -f1)
curl -k -f -s -o /dev/null \
"${ADMIN_BASE_URL}ontologies/${package_ontology_hash}/"

# uninstall package
curl -k -w "%{http_code}\n" -o /dev/null -f -s \
-E "$OWNER_CERT_FILE":"$OWNER_CERT_PWD" \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "package-uri=$package_uri" \
"$ADMIN_BASE_URL"packages/uninstall \
| grep -q "$STATUS_SEE_OTHER"

# verify owl:imports triple was removed
ns_after=$(curl -k -s -H "Accept: application/n-triples" "${END_USER_BASE_URL}ns")
if echo "$ns_after" | grep -q "<${namespace_ontology_uri}> <http://www.w3.org/2002/07/owl#imports> <${package_ontology_uri}>"; then
exit 1
fi

# verify package ontology document was deleted
curl -k -w "%{http_code}\n" -o /dev/null -s \
"${ADMIN_BASE_URL}ontologies/${package_ontology_hash}/" \
| grep -q "$STATUS_FORBIDDEN"
48 changes: 48 additions & 0 deletions http-tests/admin/packages/install-uninstall-package-stylesheet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env bash
set -euo pipefail

initialize_dataset "$END_USER_BASE_URL" "$TMP_END_USER_DATASET" "$END_USER_ENDPOINT_URL"
initialize_dataset "$ADMIN_BASE_URL" "$TMP_ADMIN_DATASET" "$ADMIN_ENDPOINT_URL"
purge_cache "$END_USER_VARNISH_SERVICE"
purge_cache "$ADMIN_VARNISH_SERVICE"
purge_cache "$FRONTEND_VARNISH_SERVICE"

# test package URI (SKOS package)
package_uri="https://packages.linkeddatahub.com/skos/#this"

# install package
curl -k -w "%{http_code}\n" -o /dev/null -f -s \
-E "$OWNER_CERT_FILE":"$OWNER_CERT_PWD" \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "package-uri=$package_uri" \
"$ADMIN_BASE_URL"packages/install \
| grep -q "$STATUS_SEE_OTHER"

# verify package stylesheet was installed (should return 200)
curl -k -f -s -o /dev/null \
"${END_USER_BASE_URL}static/com/linkeddatahub/packages/skos/layout.xsl"

# verify master stylesheet includes package
curl -k -s "$END_USER_BASE_URL"static/xsl/layout.xsl \
| grep -q "com/linkeddatahub/packages/skos/layout.xsl"

# uninstall package
curl -k -w "%{http_code}\n" -o /dev/null -f -s \
-E "$OWNER_CERT_FILE":"$OWNER_CERT_PWD" \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "package-uri=$package_uri" \
"$ADMIN_BASE_URL"packages/uninstall \
| grep -q "$STATUS_SEE_OTHER"

# verify package stylesheet was deleted (should return 404)
curl -k -w "%{http_code}\n" -o /dev/null -s \
"${END_USER_BASE_URL}static/com/linkeddatahub/packages/skos/layout.xsl" \
| grep -q "$STATUS_NOT_FOUND"

# verify master stylesheet no longer includes package
master_xsl=$(curl -k -s "$END_USER_BASE_URL"static/xsl/layout.xsl)
if echo "$master_xsl" | grep -q "com/linkeddatahub/packages/skos/layout.xsl"; then
exit 1
fi
16 changes: 16 additions & 0 deletions http-tests/admin/packages/uninstall-package-400.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -euo pipefail

initialize_dataset "$END_USER_BASE_URL" "$TMP_END_USER_DATASET" "$END_USER_ENDPOINT_URL"
initialize_dataset "$ADMIN_BASE_URL" "$TMP_ADMIN_DATASET" "$ADMIN_ENDPOINT_URL"
purge_cache "$END_USER_VARNISH_SERVICE"
purge_cache "$ADMIN_VARNISH_SERVICE"
purge_cache "$FRONTEND_VARNISH_SERVICE"

# Missing package-uri parameter should return 400 Bad Request
curl -k -w "%{http_code}\n" -o /dev/null -s \
-E "$OWNER_CERT_FILE":"$OWNER_CERT_PWD" \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
"${ADMIN_BASE_URL}packages/uninstall" \
| grep -q "$STATUS_BAD_REQUEST"
Loading
Loading