working on client creation
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.oidc.api;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.oidc.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package de.srsoftware.oidc.api;
|
||||
|
||||
public class Constants {
|
||||
public static final String CLIENT_ID = "client_id";
|
||||
public static final String NAME = "name";
|
||||
public static final String REDIRECT_URI = "redirect_uri";
|
||||
public static final String SECRET = "secret";
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.oidc.api;
|
||||
|
||||
public enum Permission {
|
||||
MANAGE_CLIENTS
|
||||
}
|
||||
public enum Permission { MANAGE_CLIENTS }
|
||||
|
||||
@@ -65,9 +65,7 @@ public final class User {
|
||||
|
||||
|
||||
public Map<String, Object> map(boolean includePassword) {
|
||||
return includePassword
|
||||
? Map.of(USERNAME, username, REALNAME, realName, EMAIL, email, PERMISSIONS, permissions, UUID, uuid, PASSWORD, hashedPassword)
|
||||
: Map.of(USERNAME, username, REALNAME, realName, EMAIL, email, PERMISSIONS, permissions, UUID, uuid);
|
||||
return includePassword ? Map.of(USERNAME, username, REALNAME, realName, EMAIL, email, PERMISSIONS, permissions, UUID, uuid, PASSWORD, hashedPassword) : Map.of(USERNAME, username, REALNAME, realName, EMAIL, email, PERMISSIONS, permissions, UUID, uuid);
|
||||
}
|
||||
|
||||
public String realName() {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
package de.srsoftware.oidc.app;
|
||||
|
||||
|
||||
import static de.srsoftware.oidc.api.Permission.MANAGE_CLIENTS;
|
||||
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import de.srsoftware.oidc.api.ClientService;
|
||||
import de.srsoftware.oidc.api.SessionService;
|
||||
@@ -18,8 +20,6 @@ import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static de.srsoftware.oidc.api.Permission.MANAGE_CLIENTS;
|
||||
|
||||
public class Application {
|
||||
public static final String BACKEND = "/api";
|
||||
private static final String FAVICON = "/favicon.ico";
|
||||
|
||||
@@ -3,23 +3,19 @@ package de.srsoftware.oidc.backend;
|
||||
|
||||
import static de.srsoftware.oidc.api.Permission.MANAGE_CLIENTS;
|
||||
import static de.srsoftware.oidc.api.User.*;
|
||||
import static de.srsoftware.oidc.api.Constants.*;
|
||||
import static java.net.HttpURLConnection.*;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import de.srsoftware.cookies.SessionToken;
|
||||
import de.srsoftware.oidc.api.*;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class Backend extends PathHandler {
|
||||
private static final String CLIENT_ID = "client_id";
|
||||
private static final String REDIRECT_URI = "redirect_uri";
|
||||
private final SessionService sessions;
|
||||
private final UserService users;
|
||||
private final ClientService clients;
|
||||
@@ -30,6 +26,17 @@ public class Backend extends PathHandler {
|
||||
users = userService;
|
||||
}
|
||||
|
||||
private boolean addClient(HttpExchange ex, Session session) throws IOException {
|
||||
var json = json(ex);
|
||||
var redirects = new HashSet<String>();
|
||||
for (Object o : json.getJSONArray(REDIRECT_URI)){
|
||||
if (o instanceof String s) redirects.add(s);
|
||||
}
|
||||
var client = new Client(json.getString(CLIENT_ID),json.getString(NAME),json.getString(SECRET),redirects);
|
||||
clients.add(client);
|
||||
return sendContent(ex,client);
|
||||
}
|
||||
|
||||
private boolean authorize(HttpExchange ex, Session session) throws IOException {
|
||||
var json = json(ex);
|
||||
var clientId = json.getString(CLIENT_ID);
|
||||
@@ -92,6 +99,8 @@ public class Backend extends PathHandler {
|
||||
// post-login paths
|
||||
var session = optSession.get();
|
||||
switch (path) {
|
||||
case "/add/client":
|
||||
return addClient(ex,session);
|
||||
case "/authorize":
|
||||
return authorize(ex, session);
|
||||
case "/clients":
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* © SRSoftware 2024 */
|
||||
package de.srsoftware.oidc.datastore.file; /* © SRSoftware 2024 */
|
||||
import static de.srsoftware.oidc.api.Constants.CLIENT_ID;
|
||||
import static de.srsoftware.oidc.api.User.*;
|
||||
|
||||
import de.srsoftware.oidc.api.*;
|
||||
@@ -15,7 +16,11 @@ import java.util.*;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class FileStore implements ClientService, SessionService, UserService {
|
||||
private static final String CLIENTS = "clients";
|
||||
private static final String EXPIRATION = "expiration";
|
||||
private static final String NAME = "name";
|
||||
private static final String REDIRECT_URIS = "redirect_uris";
|
||||
private static final String SECRET = "secret";
|
||||
private static final String SESSIONS = "sessions";
|
||||
private static final String USERS = "users";
|
||||
private static final String USER = "user";
|
||||
@@ -57,13 +62,13 @@ public class FileStore implements ClientService, SessionService, UserService {
|
||||
|
||||
@Override
|
||||
public FileStore init(User defaultUser) {
|
||||
if (!json.has(CLIENTS)) json.put(CLIENTS, new JSONObject());
|
||||
if (!json.has(SESSIONS)) json.put(SESSIONS, new JSONObject());
|
||||
if (!json.has(USERS)) save(defaultUser);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public List<User> list() {
|
||||
return List.of();
|
||||
@@ -195,7 +200,9 @@ public class FileStore implements ClientService, SessionService, UserService {
|
||||
|
||||
@Override
|
||||
public ClientService add(Client client) {
|
||||
return null;
|
||||
json.getJSONObject(CLIENTS).put(client.id(), Map.of(NAME,client.name(),SECRET,client.secret(),REDIRECT_URIS,client.redirectUris()));
|
||||
save();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -205,7 +212,18 @@ public class FileStore implements ClientService, SessionService, UserService {
|
||||
|
||||
@Override
|
||||
public List<Client> listClients() {
|
||||
return List.of();
|
||||
var clients = json.getJSONObject(CLIENTS);
|
||||
var list = new ArrayList<Client>();
|
||||
for (var clientId : clients.keySet()){
|
||||
var clientData = clients.getJSONObject(clientId);
|
||||
var redirectUris = new HashSet<String>();
|
||||
for (var o : clientData.getJSONArray(REDIRECT_URIS)){
|
||||
if (o instanceof String s) redirectUris.add(s);
|
||||
}
|
||||
var client = new Client(clientId,clientData.getString(NAME),clientData.getString(SECRET),redirectUris);
|
||||
list.add(client);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,7 +21,7 @@ These are clients that are registered with LightOIDC:
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<button onclick="window.location.href='newclient.html';">Add new site…</button>
|
||||
<button onclick="window.location.href='newclient.html';">Add new client…</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
|
||||
async function handleClients(response){
|
||||
if (response.status == UNAUTHORIZED) {
|
||||
window.location.href = 'login.html?return_to='+encodeURI(window.location.href);
|
||||
redirect('login.html?return_to='+encodeURI(window.location.href))
|
||||
return;
|
||||
}
|
||||
var clients = await response.json();
|
||||
console.log(clients);
|
||||
get()
|
||||
}
|
||||
|
||||
fetch(api+"/clients",{method:'POST'}).then(handleClients);
|
||||
@@ -19,6 +19,10 @@ function getValue(id){
|
||||
return get(id).value;
|
||||
}
|
||||
|
||||
function redirect(page){
|
||||
window.location.href = page;
|
||||
}
|
||||
|
||||
function setText(id, text){
|
||||
get(id).innerHTML = text;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,7 @@ async function handleLogin(response){
|
||||
|
||||
function doRedirect(){
|
||||
let params = new URL(document.location.toString()).searchParams;
|
||||
let redirect = params.get("return_to") || 'index.html';
|
||||
window.location.href = redirect,true;
|
||||
redirect( params.get("return_to") || 'index.html');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
function handleLogout(response){
|
||||
if (response.ok){
|
||||
document.body.innerHTML += 'success';
|
||||
document.location.href='index.html';
|
||||
}
|
||||
if (response.ok) document.body.innerHTML += 'success';
|
||||
redirect('index.html')
|
||||
}
|
||||
fetch(api+"/logout").then(handleLogout)
|
||||
@@ -4,13 +4,19 @@
|
||||
<title>Light OIDC</title>
|
||||
<script src="common.js"></script>
|
||||
<script src="user.js"></script>
|
||||
<script src="newclient.js"></script>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<nav></nav>
|
||||
<h1>Add new client</h1>
|
||||
<fieldset>
|
||||
<legend>Settings</legend>
|
||||
<table>
|
||||
<tr>
|
||||
<th>client id</th>
|
||||
<td><input type="text" size="50" id="client-id"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>client name</th>
|
||||
<td><input type="text" size="50" id="client-name"></td>
|
||||
@@ -24,6 +30,7 @@
|
||||
<td><textarea cols="50" rows="5" id="redirect-urls"></textarea></td>
|
||||
</tr>
|
||||
</table>
|
||||
<button id="button" type="button" onclick="addClient()">Add client</button>
|
||||
</fieldset>
|
||||
</body>
|
||||
</html>
|
||||
37
de.srsoftware.oidc.web/src/main/resources/en/newclient.js
Normal file
37
de.srsoftware.oidc.web/src/main/resources/en/newclient.js
Normal file
@@ -0,0 +1,37 @@
|
||||
function addClient(){
|
||||
disable('button');
|
||||
var newData = {
|
||||
client_id : getValue('client-id'),
|
||||
name : getValue('client-name'),
|
||||
secret : getValue('client-secret'),
|
||||
redirect_uri : getValue('redirect-urls').split("\n")
|
||||
};
|
||||
fetch(api+'/add/client',{
|
||||
method : 'POST',
|
||||
headers : {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body : JSON.stringify(newData)
|
||||
}).then(handleClientdResponse);
|
||||
|
||||
setText('button','sent…');
|
||||
setTimeout(function(){
|
||||
setText('button','Add client');
|
||||
enable('button');
|
||||
},10000);
|
||||
}
|
||||
|
||||
function handleClientdResponse(response){
|
||||
if (response.ok){
|
||||
redirect("clients.html");
|
||||
} else {
|
||||
setText('button','Failed!');
|
||||
enable('button');
|
||||
}
|
||||
}
|
||||
|
||||
function checkPermissions(){
|
||||
if (user && !user.permissions.includes('MANAGE_CLIENTS')) redirect("index.html");
|
||||
}
|
||||
|
||||
setTimeout(checkPermissions,100);
|
||||
@@ -28,7 +28,6 @@ function handlePasswordResponse(response){
|
||||
|
||||
function update(){
|
||||
disable('updateBtn');
|
||||
setText('updateBtn','sent…');
|
||||
var newData = {
|
||||
username : getValue('username'),
|
||||
email : getValue('email'),
|
||||
@@ -41,11 +40,11 @@ function update(){
|
||||
},
|
||||
body : JSON.stringify(newData)
|
||||
}).then(handleResponse)
|
||||
setText('updateBtn','sent…');
|
||||
}
|
||||
|
||||
function updatePass(){
|
||||
disable('passBtn');
|
||||
setText('passBtn','sent…');
|
||||
var newData = {
|
||||
oldpass : getValue('oldpass'),
|
||||
newpass : [getValue('newpass1'),getValue('newpass2')],
|
||||
@@ -58,7 +57,7 @@ function updatePass(){
|
||||
},
|
||||
body : JSON.stringify(newData)
|
||||
}).then(handlePasswordResponse);
|
||||
|
||||
setText('passBtn','sent…');
|
||||
setTimeout(function(){
|
||||
setText('passBtn','Update');
|
||||
enable('passBtn');
|
||||
|
||||
@@ -10,3 +10,8 @@ body fieldset {
|
||||
a {
|
||||
color: yellow;
|
||||
}
|
||||
|
||||
fieldset th,
|
||||
form th{
|
||||
text-align: right;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
var user = null;
|
||||
async function handleUser(response){
|
||||
if (response.status == UNAUTHORIZED) {
|
||||
window.location.href = 'login.html?return_to='+encodeURI(window.location.href);
|
||||
redirect('login.html?return_to='+encodeURI(window.location.href));
|
||||
return;
|
||||
}
|
||||
if (response.ok){
|
||||
|
||||
Reference in New Issue
Block a user