Compare commits

...

19 Commits

Author SHA1 Message Date
wolfez
d46472a090 Release v1.36.0 2025-10-03 09:52:26 +02:00
Sam Van Campenhout
223e30f2f5 Merge pull request #569 from lblod/feature/dashboard-acmidm
[OP-3674]: use acmidm for dashboard
2025-10-02 14:36:18 +02:00
wolfez
1149b9a29c update changelog 2025-10-02 13:47:02 +02:00
wolfez
417922e556 update changelog with deploy instructions 2025-10-02 10:03:54 +02:00
wolfez
ed08b7e117 use frontend-dashboard v1.10.0 2025-10-02 09:47:05 +02:00
wolfez
8f1bbb7047 use english version of dashboard 2025-10-01 14:34:10 +02:00
wolfez
b9590d3289 fix acm/idm config for dashboard 2025-09-26 14:13:11 +02:00
Sam Van Campenhout
b51ebbf8c5 Merge branch 'development' into feature/dashboard-acmidm 2025-09-16 15:31:33 +02:00
felix
832b8ed57c Merge branch 'master' into development 2025-09-16 09:34:08 +02:00
cecemel
7e7b51cf0a Merge pull request #571 from lblod/hotfix/produce-memberships
Hotfix/produce memberships
2025-09-16 09:32:45 +02:00
Claire Lovisa
91abe61cfc Update CHANGELOG.md 2025-09-15 17:38:38 +02:00
Claire Lovisa
0c39f4a0be Produce memberships in organizations and public producers 2025-09-15 17:36:24 +02:00
wolfez
8e7e031576 remove dashboard script 2025-09-10 14:33:00 +02:00
wolfez
2114f1531e update caddyfile to match other apps 2025-09-05 11:08:34 +02:00
wolfez
d67440eac0 Add acmidm for the dashboard 2025-09-04 16:01:43 +02:00
felix
48f982864f Update CHANGELOG.md 2025-08-26 15:25:58 +02:00
wolfez
1e7de4a9a8 bump frontend 2025-08-13 14:25:37 +02:00
Claire Lovisa
48e0c3b3ea Fix province value of addresses in Brussel's area (#568)
* Add municipalities of Brussels and remove province of addresses in Brussel

* Update changelog

* Add missing restart entry in Changelog

* Remove migrations creating municipalities of Brussels
2025-08-08 10:12:41 +02:00
mirdono
8e2dc898f5 chore: release v1.35.0 2025-08-04 18:56:51 +02:00
13 changed files with 205 additions and 139 deletions

View File

@@ -1,7 +1,63 @@
# Changelog
## Unreleased
## v1.35.0-0 (2025-08-04)
## 1.36.0 (2025-10-03)
### Dashboard
- Enable ACM/IDM for the dashboard [OP-3674]
#### QA
Configure the environment variables for the QA ACM/IDM environment:
```yml
frontend-dashboard:
environment:
EMBER_ACMIDM_CLIENT_ID: "03382bf4-4886-4fb6-8602-945ad3080a7a"
EMBER_ACMIDM_BASE_URL: "https://authenticatie-ti.vlaanderen.be/op/v1/auth"
EMBER_ACMIDM_REDIRECT_URL: "https://dashboard.organisaties.abb.lblod.info/authorization/callback"
EMBER_ACMIDM_LOGOUT_URL: "https://authenticatie-ti.vlaanderen.be/op/v1/logout"
EMBER_ACMIDM_SCOPE: "openid vo profile abb_organisatieportaal"
login-dashboard:
environment:
MU_APPLICATION_AUTH_DISCOVERY_URL: "https://authenticatie-ti.vlaanderen.be/op"
MU_APPLICATION_AUTH_CLIENT_ID: "03382bf4-4886-4fb6-8602-945ad3080a7a"
MU_APPLICATION_AUTH_REDIRECT_URI: "https://dashboard.organisaties.abb.lblod.info/authorization/callback"
MU_APPLICATION_AUTH_CLIENT_SECRET: "snip" # see ticket for secret
```
Link the new domain name to QA (and remove from dev)
#### PROD
Configure the environment variables for the PROD ACM/IDM environment once the values are known.
Link the new domain name to PROD + DNS config to the server
#### CLI
```
drc restart migrations
drc restart dispatcher database
drc up -d --remove-orphans
```
### Frontend
- Bump to [v1.34.1](https://github.com/lblod/frontend-organization-portal/releases/tag/v1.34.1) [OP-3638]
- Remove province for addresses in the Brussels area [OP-3638] & [OP-3648]
### Deploy notes
```
drc pull frontend; drc up -d frontend
drc restart migrations-triggering-indexing; drc logs -ft --tail=200 migrations-triggering-indexing
```
## v1.35.1 (2025-09-15)
### Backend
- Produce memberships and their roles in organizations and public producers [OP-3658] & [OP-3661]
### Deploy notes
```
drc restart delta-producer-publication-graph-maintainer
```
## v1.35.0 (2025-08-04)
### Frontend
- Bump to [v1.34.0](https://github.com/lblod/frontend-organization-portal/releases/tag/v1.34.0)
### Backend
@@ -13,6 +69,7 @@
- datafix: cleanup of duplicate memberships [OP-3634]
- Fix KBO organizations' date formats [OP-3560]
### Deploy notes
```
drc pull scope-of-operation; drc up -d scope-of-operation

View File

@@ -185,26 +185,3 @@ To make sure the app can share data, producers need to be set up. There is an in
)
}
```
## Configuring the dashboard
### Accessing the dashboard from your local machine
Since we use dispatcher v2, which dispatches on hostname, we'll have to update `/etc/hosts`.
Add an entry similar to the following. Ensure the first part of the domain starts with `dashboard`.:
```
127.0.0.1 dashboard.localhost
```
### Creating new users
For now, we use specific logins for the dashboard users. Each environment has its own passwords.
To add a user, make sure to have [mu-cli](https://github.com/mu-semtech/mu-cli) installed first.
Then in `docker-compose.override.yml`
```
dashboard-login:
environment:
MU_APPLICATION_SALT: 'a_random_string_with_sufficient_entropy_hence_not_this_one'
```
You can now generate a user by running `mu script project-scripts generate-dashboard-login` and following the steps.
Restart `migrations` and it should insert the new user into the database.

View File

@@ -111,11 +111,9 @@ defmodule Acl.UserGroups.Config do
%AccessByQuery{
vars: [],
query: "PREFIX ext: <http://mu.semte.ch/vocabularies/ext/>
PREFIX mu: <http://mu.semte.ch/vocabularies/core/>
SELECT DISTINCT ?account WHERE {
<SESSION_ID> <http://mu.semte.ch/vocabularies/session/account> ?account.
?account <http://mu.semte.ch/vocabularies/ext/sessionRole> ?session_role.
FILTER( ?session_role = \"dashboard-user\" )
SELECT DISTINCT ?session WHERE {
VALUES ?session { <SESSION_ID> }
?session ext:sessionRole \"LoketLB-AdminDashboardOrganisatiePortaalGebruiker\" .
}"
}
end
@@ -219,10 +217,10 @@ defmodule Acl.UserGroups.Config do
}
]
},
# // dashboard users
# // Dashboard admin
%GroupSpec{
name: "dashboard-users",
useage: [:read],
name: "o-admin-rwf",
useage: [:read, :write, :read_for_write],
access: can_access_dashboard(),
graphs: [
%GraphSpec{

View File

@@ -512,6 +512,32 @@
"properties": [
"http://www.w3.org/2004/02/skos/core#prefLabel"
]
},
{
"type": "http://www.w3.org/ns/org#Membership",
"graphsFilter": [
"http://mu.semte.ch/graphs/worship-service",
"http://mu.semte.ch/graphs/shared",
"http://mu.semte.ch/graphs/administrative-unit"
],
"properties": [
"http://mu.semte.ch/vocabularies/core/uuid",
"http://www.w3.org/ns/org#organization",
"http://www.w3.org/ns/org#member",
"http://www.w3.org/ns/org#role"
]
},
{
"type": "http://www.w3.org/ns/org#Role",
"graphsFilter": [
"http://mu.semte.ch/graphs/public"
],
"properties": [
"http://mu.semte.ch/vocabularies/core/uuid",
"http://www.w3.org/2004/02/skos/core#prefLabel",
"http://www.w3.org/2004/02/skos/core#broader",
"http://www.w3.org/2004/02/skos/core#topConceptOf"
]
}
]
}

View File

@@ -675,6 +675,32 @@
"http://www.w3.org/2004/02/skos/core#prefLabel",
"http://www.w3.org/2000/01/rdf-schema#label"
]
},
{
"type": "http://www.w3.org/ns/org#Membership",
"graphsFilter": [
"http://mu.semte.ch/graphs/worship-service",
"http://mu.semte.ch/graphs/shared",
"http://mu.semte.ch/graphs/administrative-unit"
],
"properties": [
"http://mu.semte.ch/vocabularies/core/uuid",
"http://www.w3.org/ns/org#organization",
"http://www.w3.org/ns/org#member",
"http://www.w3.org/ns/org#role"
]
},
{
"type": "http://www.w3.org/ns/org#Role",
"graphsFilter": [
"http://mu.semte.ch/graphs/public"
],
"properties": [
"http://mu.semte.ch/vocabularies/core/uuid",
"http://www.w3.org/2004/02/skos/core#prefLabel",
"http://www.w3.org/2004/02/skos/core#broader",
"http://www.w3.org/2004/02/skos/core#topConceptOf"
]
}
]
}

View File

@@ -306,7 +306,7 @@ defmodule Dispatcher do
end
match "/sessions/*path", %{ reverse_host: ["dashboard" | _rest] } do
Proxy.forward conn, path, "http://dashboard-login/sessions/"
Proxy.forward conn, path, "http://login-dashboard/sessions/"
end
match "/sessions/*path", %{accept: [:any], layer: :api} do

View File

@@ -0,0 +1,38 @@
DELETE {
GRAPH <http://mu.semte.ch/graphs/worship-service> {
?s <http://www.w3.org/ns/locn#adminUnitL2> ?province ;
<https://data.vlaanderen.be/ns/adres#adresIsGelegenIn> ?werkingsgebied .
}
} WHERE {
GRAPH <http://mu.semte.ch/graphs/worship-service> {
VALUES ?postCode {
"1070"
"1000"
"1020"
"1120"
"1130"
"1050"
"1040"
"1140"
"1083"
"1090"
"1081"
"1160"
"1030"
"1082"
"1060"
"1080"
"1210"
"1200"
"1150"
"1180"
"1190"
"1170"
}
?s a <http://www.w3.org/ns/locn#Address> ;
<http://www.w3.org/ns/locn#postCode> ?postCode ;
<http://www.w3.org/ns/locn#adminUnitL2> ?province ;
<https://data.vlaanderen.be/ns/adres#adresIsGelegenIn> ?werkingsgebied .
}
}

View File

@@ -0,0 +1,17 @@
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ext:<http://mu.semte.ch/vocabularies/ext/>
INSERT {
GRAPH ?g {
?account ext:sessionRole "LoketLB-AdminDashboardOrganisatiePortaalGebruiker" .
}
}
WHERE {
VALUES ?account {
<http://data.lblod.info/id/account/3a91ff60-07c1-4136-ac5e-55cf401e0956>
}
GRAPH ?g {
?account ext:sessionRole ?role .
}
}

View File

@@ -1,4 +1,4 @@
https://{$OP_ADDRESS} {
https://{$APPLICATION_ADDRESS} {
reverse_proxy identifier:80
tls internal
}

View File

@@ -40,6 +40,8 @@ services:
restart: "no"
login:
restart: "no"
login-dashboard:
restart: "no"
accountdetail:
restart: "no"
privacy-unit:
@@ -50,6 +52,10 @@ services:
restart: "no"
frontend:
restart: "no"
frontend-dashboard:
environment:
EMBER_LOGIN_ROUTE: "mock-login"
restart: "no"
uri-info:
restart: "no"
delta-producer-background-jobs-initiator:

View File

@@ -122,7 +122,7 @@ services:
restart: always
logging: *default-logging
sink:
image: nginx:1.15.2
image: nginx:1.25.1
volumes:
- ./config/sink/sink.conf:/etc/nginx/conf.d/default.conf
labels:
@@ -130,7 +130,7 @@ services:
restart: always
logging: *default-logging
login:
image: lblod/acmidm-login-service:0.9.2
image: lblod/acmidm-login-service:0.12.0
environment:
MU_APPLICATION_AUTH_USERID_CLAIM: "vo_id"
MU_APPLICATION_GRAPH: "http://mu.semte.ch/graphs/contacthub/accounts"
@@ -145,14 +145,22 @@ services:
logging: *default-logging
links:
- db:database
dashboard-login:
image: semtech/mu-login-service:3.0.0
links:
- db:database
login-dashboard:
image: lblod/acmidm-login-service:0.12.0
environment:
LOG_SINK_URL: "http://sink"
MU_APPLICATION_AUTH_ROLE_CLAIM: "abb_organisatieportaal_rol_2d"
MU_APPLICATION_AUTH_USERID_CLAIM: "vo_id"
MU_APPLICATION_AUTH_DISCOVERY_URL: "<ACM_IDM_AUTH_DISCOVERY_URL>"
MU_APPLICATION_AUTH_CLIENT_ID: "<ACM_IDM_AUTH_CLIENT_ID>"
MU_APPLICATION_AUTH_REDIRECT_URI: "<ACMIDM_AUTH_REDIRECT_URI>"
MU_APPLICATION_AUTH_CLIENT_SECRET: "<ACMIDM_AUTH_CLIENT_SECRET>"
labels:
- "logging=true"
restart: always
logging: *default-logging
links:
- db:database
accountdetail:
image: lblod/account-detail-service:0.1.0
labels:
@@ -194,7 +202,7 @@ services:
restart: always
logging: *default-logging
frontend:
image: lblod/frontend-organization-portal:1.34.0
image: lblod/frontend-organization-portal:1.34.1
volumes:
- ./config/frontend/add-x-frame-options-header.conf:/config/add-x-frame-options.conf
environment:
@@ -209,7 +217,15 @@ services:
restart: always
logging: *default-logging
frontend-dashboard:
image: lblod/frontend-dashboard:1.7.0
image: lblod/frontend-dashboard:1.10.0
environment:
EMBER_LOGIN_ROUTE: "acmidm-login"
EMBER_ACMIDM_CLIENT_ID: "<CLIENT_ID>"
EMBER_ACMIDM_BASE_URL: "<BASE_URL>"
EMBER_ACMIDM_REDIRECT_URL: "<REDIRECT_URL>"
EMBER_ACMIDM_LOGOUT_URL: "<LOGOUT_URL>"
EMBER_ACMIDM_SCOPE: "openid vo profile abb_organisatieportaal"
EMBER_ENGLISH_ACCOUNTS_MODEL: true
labels:
- "logging=true"
restart: always

View File

@@ -48,21 +48,6 @@
"mounts": {
"app": "/data/app/"
}
},
{
"documentation": {
"command": "generate-dashboard-login",
"description": "generate a login account for the jobs dashboard",
"arguments": []
},
"environment": {
"image": "ruby",
"interactive": true,
"script": "generate-dashboard-login/run.sh"
},
"mounts": {
"app": "/project/"
}
}
]
}
}

View File

@@ -1,80 +0,0 @@
#!/usr/bin/env ruby
require 'bundler/inline'
require 'yaml'
require 'securerandom'
require 'date'
$stdout.sync = true
print "installing dependencies..."
gemfile do
source 'https://rubygems.org'
gem 'bcrypt'
end
puts "done"
salt = ""
begin
File.open("/project/docker-compose.override.yml") do |file|
config = YAML.load(file)
salt = config.dig("services", "dashboard-login", "environment", "MU_APPLICATION_SALT")
throw "invalid salt" unless salt
end
rescue
puts "Tried to locate login salt in docker-compose.override.yml, but couldn't find it."
puts "Please make sure a salt is configured:"
puts <<EOF
login:
restart: "no"
environment:
MU_APPLICATION_SALT: "#{SecureRandom.hex}"
EOF
end
puts "this script will generate a new user account"
print "username: "
STDOUT.flush
account_name = STDIN.gets.chomp
print "password: "
STDOUT.flush
password = STDIN.gets.chomp
account_salt = SecureRandom.hex
person_uuid = SecureRandom.uuid
account_uuid = SecureRandom.uuid
domain = "data.gift"
hashed_password = BCrypt::Password.create(password + salt + account_salt)
now = DateTime.now.xmlschema
query = %(
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX people: <http://#{domain}/people/>
PREFIX accounts: <http://#{domain}/accounts/>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX mu: <http://mu.semte.ch/vocabularies/core/>
PREFIX ext: <http://mu.semte.ch/vocabularies/ext/>
PREFIX account: <http://mu.semte.ch/vocabularies/account/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
INSERT DATA {
GRAPH <http://mu.semte.ch/application> {
people:#{person_uuid} a foaf:Person ;
foaf:name "#{account_name}";
foaf:account accounts:#{account_uuid};
mu:uuid "#{person_uuid}";
dcterms:created "#{now}"^^xsd:datetime;
dcterms:modified "#{now}"^^xsd:datetime.
accounts:#{account_uuid} a foaf:OnlineAccount;
foaf:accountName "#{account_name}";
mu:uuid "#{account_uuid}";
account:password """#{hashed_password}""";
account:salt "#{account_salt}";
account:status <http://mu.semte.ch/vocabularies/account/status/active>;
dcterms:created "#{now}"^^xsd:datetime;
ext:sessionRole "dashboard-user";
dcterms:modified "#{now}"^^xsd:datetime.
}}
)
timestamp = DateTime.now.strftime("%Y%m%d%H%M%L")
filename = "#{timestamp}-create-user-#{account_name.gsub(" ", "-")}.sparql"
File.write("/project/config/migrations/local/#{filename}", query)
puts "generated migration ./config/migrations/local/#{filename} for #{account_name.inspect} : #{password.inspect}"