Merge commit '41466943eb5bd93fa948c486ca7253b33767c835' into sqlite
This commit is contained in:
@@ -81,7 +81,7 @@ public class Application {
|
||||
new Forward(INDEX).bindPath(ROOT).on(server);
|
||||
new WellKnownController().bindPath(WELL_KNOWN, "/realms/oidc" + WELL_KNOWN).on(server);
|
||||
new UserController(mailConfig, sessionService, userService, staticPages).bindPath(API_USER).on(server);
|
||||
var tokenControllerConfig = new TokenController.Configuration("https://lightoidc.srsoftware.de", 10); // TODO configure or derive from hostname
|
||||
var tokenControllerConfig = new TokenController.Configuration(10);
|
||||
new TokenController(authService, clientService, keyManager, userService, tokenControllerConfig).bindPath(API_TOKEN).on(server);
|
||||
new ClientController(authService, clientService, sessionService, userService).bindPath(API_CLIENT).on(server);
|
||||
new KeyStoreController(keyStore).bindPath(JWKS).on(server);
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.jose4j.lang.JoseException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class TokenController extends PathHandler {
|
||||
public record Configuration(String issuer, int tokenExpirationMinutes) {
|
||||
public record Configuration(int tokenExpirationMinutes) {
|
||||
}
|
||||
private final ClientService clients;
|
||||
private final AuthorizationService authorizations;
|
||||
@@ -115,7 +115,8 @@ public class TokenController extends PathHandler {
|
||||
var user = optUser.get();
|
||||
|
||||
var accessToken = users.accessToken(user);
|
||||
String jwToken = createJWT(client, user, accessToken);
|
||||
var issuer = hostname(ex);
|
||||
String jwToken = createJWT(client, user, accessToken, issuer);
|
||||
ex.getResponseHeaders().add("Cache-Control", "no-store");
|
||||
JSONObject response = new JSONObject();
|
||||
response.put(ACCESS_TOKEN, accessToken.id());
|
||||
@@ -126,13 +127,13 @@ public class TokenController extends PathHandler {
|
||||
return sendContent(ex, response);
|
||||
}
|
||||
|
||||
private String createJWT(Client client, User user, AccessToken accessToken) {
|
||||
private String createJWT(Client client, User user, AccessToken accessToken, String issuer) {
|
||||
try {
|
||||
PublicJsonWebKey key = keyManager.getKey();
|
||||
var algo = key.getAlgorithm();
|
||||
var atHash = this.atHash(algo, accessToken);
|
||||
key.setUse("sig");
|
||||
JwtClaims claims = createIdTokenClaims(user, client, atHash);
|
||||
JwtClaims claims = createIdTokenClaims(user, client, atHash, issuer);
|
||||
|
||||
// A JWT is a JWS and/or a JWE with JSON claims as the payload.
|
||||
// In this example it is a JWS so we create a JsonWebSignature object.
|
||||
@@ -167,12 +168,12 @@ public class TokenController extends PathHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private JwtClaims createIdTokenClaims(User user, Client client, String atHash) {
|
||||
private JwtClaims createIdTokenClaims(User user, Client client, String atHash, String issuer) {
|
||||
var optNonce = authorizations.consumeNonce(user.uuid(), client.id());
|
||||
JwtClaims claims = new JwtClaims();
|
||||
|
||||
// required claims:
|
||||
claims.setIssuer(config.issuer); // who creates the token and signs it
|
||||
claims.setIssuer(issuer); // who creates the token and signs it
|
||||
claims.setSubject(user.uuid()); // the subject/principal is whom the token is about
|
||||
claims.setAudience(client.id());
|
||||
claims.setExpirationTimeMinutesInTheFuture(config.tokenExpirationMinutes); // time when the token will expire (10 minutes from now)
|
||||
|
||||
@@ -21,6 +21,7 @@ import jakarta.mail.*;
|
||||
import jakarta.mail.internet.*;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Light OIDC</title>
|
||||
<script src="scripts/common.js"></script>
|
||||
<script src="scripts/user.js"></script>
|
||||
<script src="scripts/authorization.js"></script>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
</head>
|
||||
<body>
|
||||
<nav></nav>
|
||||
<div id="content" style="display: none">
|
||||
Eine vertrauende Seite, <span id="rp">unknown</span>, hat Zugriff auf die folgenden Informationen erfragt:
|
||||
<ul id="scopes">
|
||||
|
||||
</ul>
|
||||
Stimmen Sie zu, diese Informationen mit <span id="rp2">unknown</span> zu teilen?
|
||||
<button type="button" onclick="grantAutorization(1)">Ja - für einen Tag</button>
|
||||
<button type="button" onclick="grantAutorization(7)">Ja - für eine Woche</button>
|
||||
<button type="button" onclick="grantAutorization(30)">Ja - für einen Monat</button>
|
||||
<button type="button" onclick="grantAutorization(365)">Ja - für ein Jahr</button>
|
||||
<button type="button" onclick="denyAutorization()">No</button>
|
||||
</div>
|
||||
<div id="error_missing_parameter" class="error" style="display: none">
|
||||
Request enthält den benötigten Parameter "<span id="parameter"></span>" nicht!
|
||||
</div>
|
||||
<div id="error_unknown_client" class="error" style="display: none">
|
||||
Client "<span id="client_id"></span>" ist dem Backend nicht bekannt!
|
||||
</div>
|
||||
<div id="error_unsupported_response_type" class="error" style="display: none">
|
||||
Rückgabe-Typ "<span id="response_type"></span>" wird nicht unterstützt!
|
||||
</div>
|
||||
<div id="error_missing_code" class="error">
|
||||
Fehlender Rückgabe-Typ: code
|
||||
</div>
|
||||
<div id="error_invalid_redirect" class="error" style="display: none">
|
||||
Ungültige Umleitung: <span id="redirect_uri"></span>
|
||||
</div>
|
||||
<div id="missing_scopes" class="error" style="display: none">Authorisierungs-Quelle lieferte weder eine Liste von <em>nicht-autorisierten Scopes</em> noch eine Liste von <em>authorisierten Scopes</em>! Das ist ein Server-Fehler.</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
Link zum Zurückseten des Passworts für {service}
|
||||
Liebe(r) {displayname},
|
||||
|
||||
Jemand – wahrscheinlich du – beauftragte das Passwort für {service} zurückzusetzen.
|
||||
|
||||
Falls du das warst öffne bitte den folgenden Link in deinem Browser:
|
||||
|
||||
{link}
|
||||
|
||||
Falls du das Zurücksetzen *nicht angefragt hast* (oder versehentlich), kannst du diese Mail einfach ignorieren.
|
||||
|
||||
Beste Grüße, dein OIDC-Admin.
|
||||
@@ -84,4 +84,7 @@ function backendAutorization(){
|
||||
}).then(handleResponse);
|
||||
}
|
||||
|
||||
document.addEventListener("logged_in", function(event) { // wait until page loaded
|
||||
backendAutorization();
|
||||
});
|
||||
|
||||
|
||||
@@ -8,17 +8,19 @@ function handleClients(response){
|
||||
return;
|
||||
}
|
||||
var clients = response.json().then(clients => {
|
||||
var arr = [];
|
||||
for (let id in clients) arr.push(clients[id]);
|
||||
arr.sort((a,b) => a.name < b.name ? -1 : 1);
|
||||
var bottom = document.getElementById('bottom');
|
||||
for (let id in clients){
|
||||
for (let client of arr){
|
||||
var row = document.createElement("tr");
|
||||
var client = clients[id];
|
||||
row.innerHTML = `<td>${client.name}</td>
|
||||
<td>${id}</td>
|
||||
<td>${client.client_id}</td>
|
||||
<td>${client.redirect_uris.join("<br/>")}</td>
|
||||
<td>${link(client.landing_page)}</td>
|
||||
<td>
|
||||
<button type="button" onclick="edit('${id}')">Edit</button>
|
||||
<button class="danger" onclick="remove('${id}')" type="button">Remove</button>
|
||||
<button type="button" onclick="edit('${client.client_id}')">Edit</button>
|
||||
<button class="danger" onclick="remove('${client.client_id}')" type="button">Remove</button>
|
||||
</td>`;
|
||||
bottom.parentNode.insertBefore(row,bottom);
|
||||
}
|
||||
|
||||
@@ -39,10 +39,13 @@ function handleUsers(response){
|
||||
return;
|
||||
}
|
||||
response.json().then(users => {
|
||||
var arr = [];
|
||||
for (let id in users) arr.push(users[id]);
|
||||
arr.sort((a,b) => a.username < b.username ? -1 : 1);
|
||||
var bottom = document.getElementById('bottom');
|
||||
for (let id in users){
|
||||
for (var u of arr){
|
||||
var row = document.createElement("tr");
|
||||
var u = users[id];
|
||||
//var u = users[id];
|
||||
var manage = {
|
||||
clients : u.permissions.includes('MANAGE_CLIENTS'),
|
||||
perms : u.permissions.includes('MANAGE_PERMISSIONS'),
|
||||
@@ -52,16 +55,16 @@ function handleUsers(response){
|
||||
row.innerHTML = `<td>${u.username}</td>
|
||||
<td>${u.realname}</td>
|
||||
<td>${u.email}</td>
|
||||
<td>${id}</td>
|
||||
<td>${u.uuid}</td>
|
||||
<td style="display: none" class="permissions">
|
||||
<button onclick="editPermission('${id}','MANAGE_CLIENTS',${manage.clients})">${manage.clients ?'-':'+'} <span>Manage</span> Clients</button>
|
||||
<button onclick="editPermission('${id}','MANAGE_PERMISSIONS',${manage.perms})">${manage.perms ?'-':'+'} <span>Manage</span> Permissions</button>
|
||||
<button onclick="editPermission('${id}','MANAGE_SMTP',${manage.smtp})">${manage.smtp ?'-':'+'} <span>Manage</span> SMTP</button>
|
||||
<button onclick="editPermission('${id}','MANAGE_USERS',${manage.users})">${manage.users ?'-':'+'} <span>Manage</span> Users</button>
|
||||
<button onclick="editPermission('${u.uuid}','MANAGE_CLIENTS',${manage.clients})">${manage.clients ?'-':'+'} <span>Manage</span> Clients</button>
|
||||
<button onclick="editPermission('${u.uuid}','MANAGE_PERMISSIONS',${manage.perms})">${manage.perms ?'-':'+'} <span>Manage</span> Permissions</button>
|
||||
<button onclick="editPermission('${u.uuid}','MANAGE_SMTP',${manage.smtp})">${manage.smtp ?'-':'+'} <span>Manage</span> SMTP</button>
|
||||
<button onclick="editPermission('${u.uuid}','MANAGE_USERS',${manage.users})">${manage.users ?'-':'+'} <span>Manage</span> Users</button>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" onclick="reset_password('${id}')" id="reset-${id}">Reset password</button>
|
||||
<button id="remove-${u.uuid}" class="danger" onclick="remove('${id}','${u.realname}')" type="button">Remove</button>
|
||||
<button type="button" onclick="reset_password('${u.uuid}')" id="reset-${u.uuid}">Reset password</button>
|
||||
<button id="remove-${u.uuid}" class="danger" onclick="remove('${u.uuid}','${u.realname}')" type="button">Remove</button>
|
||||
</td>`;
|
||||
bottom.parentNode.insertBefore(row,bottom);
|
||||
if (user.permissions.includes('MANAGE_PERMISSIONS')) showAll('permissions');
|
||||
|
||||
Reference in New Issue
Block a user