Browse Source

working on client creation

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
sqlite
Stephan Richter 4 months ago
parent
commit
1c0ef0e257
  1. 1
      de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Client.java
  2. 1
      de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/ClientService.java
  3. 8
      de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Constants.java
  4. 1
      de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/PathHandler.java
  5. 5
      de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Permission.java
  6. 4
      de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/User.java
  7. 4
      de.srsoftware.oidc.app/src/main/java/de/srsoftware/oidc/app/Application.java
  8. 21
      de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/Backend.java
  9. 24
      de.srsoftware.oidc.datastore.file/src/main/java/de/srsoftware/oidc/datastore/file/FileStore.java
  10. 2
      de.srsoftware.oidc.web/src/main/resources/en/clients.html
  11. 4
      de.srsoftware.oidc.web/src/main/resources/en/clients.js
  12. 4
      de.srsoftware.oidc.web/src/main/resources/en/common.js
  13. 3
      de.srsoftware.oidc.web/src/main/resources/en/login.js
  14. 6
      de.srsoftware.oidc.web/src/main/resources/en/logout.js
  15. 7
      de.srsoftware.oidc.web/src/main/resources/en/newclient.html
  16. 37
      de.srsoftware.oidc.web/src/main/resources/en/newclient.js
  17. 5
      de.srsoftware.oidc.web/src/main/resources/en/settings.js
  18. 5
      de.srsoftware.oidc.web/src/main/resources/en/style.css
  19. 2
      de.srsoftware.oidc.web/src/main/resources/en/user.js

1
de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Client.java

@ -1,3 +1,4 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api;
import java.util.Set; import java.util.Set;

1
de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/ClientService.java

@ -1,3 +1,4 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api;
import java.util.List; import java.util.List;

8
de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Constants.java

@ -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";
}

1
de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/PathHandler.java

@ -9,7 +9,6 @@ import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpServer;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;

5
de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Permission.java

@ -1,5 +1,4 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api;
public enum Permission { public enum Permission { MANAGE_CLIENTS }
MANAGE_CLIENTS
}

4
de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/User.java

@ -65,9 +65,7 @@ public final class User {
public Map<String, Object> map(boolean includePassword) { public Map<String, Object> map(boolean includePassword) {
return 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);
? 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() { public String realName() {

4
de.srsoftware.oidc.app/src/main/java/de/srsoftware/oidc/app/Application.java

@ -2,6 +2,8 @@
package de.srsoftware.oidc.app; package de.srsoftware.oidc.app;
import static de.srsoftware.oidc.api.Permission.MANAGE_CLIENTS;
import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpServer;
import de.srsoftware.oidc.api.ClientService; import de.srsoftware.oidc.api.ClientService;
import de.srsoftware.oidc.api.SessionService; import de.srsoftware.oidc.api.SessionService;
@ -18,8 +20,6 @@ import java.nio.file.Path;
import java.util.*; import java.util.*;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import static de.srsoftware.oidc.api.Permission.MANAGE_CLIENTS;
public class Application { public class Application {
public static final String BACKEND = "/api"; public static final String BACKEND = "/api";
private static final String FAVICON = "/favicon.ico"; private static final String FAVICON = "/favicon.ico";

21
de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/Backend.java

@ -3,23 +3,19 @@ package de.srsoftware.oidc.backend;
import static de.srsoftware.oidc.api.Permission.MANAGE_CLIENTS; import static de.srsoftware.oidc.api.Permission.MANAGE_CLIENTS;
import static de.srsoftware.oidc.api.User.*; import static de.srsoftware.oidc.api.User.*;
import static de.srsoftware.oidc.api.Constants.*;
import static java.net.HttpURLConnection.*; import static java.net.HttpURLConnection.*;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.cookies.SessionToken; import de.srsoftware.cookies.SessionToken;
import de.srsoftware.oidc.api.*; import de.srsoftware.oidc.api.*;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
public class Backend extends PathHandler { 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 SessionService sessions;
private final UserService users; private final UserService users;
private final ClientService clients; private final ClientService clients;
@ -30,6 +26,17 @@ public class Backend extends PathHandler {
users = userService; 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 { private boolean authorize(HttpExchange ex, Session session) throws IOException {
var json = json(ex); var json = json(ex);
var clientId = json.getString(CLIENT_ID); var clientId = json.getString(CLIENT_ID);
@ -92,6 +99,8 @@ public class Backend extends PathHandler {
// post-login paths // post-login paths
var session = optSession.get(); var session = optSession.get();
switch (path) { switch (path) {
case "/add/client":
return addClient(ex,session);
case "/authorize": case "/authorize":
return authorize(ex, session); return authorize(ex, session);
case "/clients": case "/clients":

24
de.srsoftware.oidc.datastore.file/src/main/java/de/srsoftware/oidc/datastore/file/FileStore.java

@ -1,5 +1,6 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.datastore.file; /* © 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 static de.srsoftware.oidc.api.User.*;
import de.srsoftware.oidc.api.*; import de.srsoftware.oidc.api.*;
@ -15,7 +16,11 @@ import java.util.*;
import org.json.JSONObject; import org.json.JSONObject;
public class FileStore implements ClientService, SessionService, UserService { public class FileStore implements ClientService, SessionService, UserService {
private static final String CLIENTS = "clients";
private static final String EXPIRATION = "expiration"; 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 SESSIONS = "sessions";
private static final String USERS = "users"; private static final String USERS = "users";
private static final String USER = "user"; private static final String USER = "user";
@ -57,13 +62,13 @@ public class FileStore implements ClientService, SessionService, UserService {
@Override @Override
public FileStore init(User defaultUser) { 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(SESSIONS)) json.put(SESSIONS, new JSONObject());
if (!json.has(USERS)) save(defaultUser); if (!json.has(USERS)) save(defaultUser);
return this; return this;
} }
@Override @Override
public List<User> list() { public List<User> list() {
return List.of(); return List.of();
@ -195,7 +200,9 @@ public class FileStore implements ClientService, SessionService, UserService {
@Override @Override
public ClientService add(Client client) { 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 @Override
@ -205,7 +212,18 @@ public class FileStore implements ClientService, SessionService, UserService {
@Override @Override
public List<Client> listClients() { 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 @Override

2
de.srsoftware.oidc.web/src/main/resources/en/clients.html

@ -21,7 +21,7 @@ These are clients that are registered with LightOIDC:
</tr> </tr>
<tr> <tr>
<td> <td>
<button onclick="window.location.href='newclient.html';">Add new site</button> <button onclick="window.location.href='newclient.html';">Add new client</button>
</td> </td>
</tr> </tr>
</table> </table>

4
de.srsoftware.oidc.web/src/main/resources/en/clients.js

@ -1,11 +1,11 @@
async function handleClients(response){ async function handleClients(response){
if (response.status == UNAUTHORIZED) { 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; return;
} }
var clients = await response.json(); var clients = await response.json();
console.log(clients); get()
} }
fetch(api+"/clients",{method:'POST'}).then(handleClients); fetch(api+"/clients",{method:'POST'}).then(handleClients);

4
de.srsoftware.oidc.web/src/main/resources/en/common.js

@ -19,6 +19,10 @@ function getValue(id){
return get(id).value; return get(id).value;
} }
function redirect(page){
window.location.href = page;
}
function setText(id, text){ function setText(id, text){
get(id).innerHTML = text; get(id).innerHTML = text;
} }

3
de.srsoftware.oidc.web/src/main/resources/en/login.js

@ -9,8 +9,7 @@ async function handleLogin(response){
function doRedirect(){ function doRedirect(){
let params = new URL(document.location.toString()).searchParams; let params = new URL(document.location.toString()).searchParams;
let redirect = params.get("return_to") || 'index.html'; redirect( params.get("return_to") || 'index.html');
window.location.href = redirect,true;
return false; return false;
} }

6
de.srsoftware.oidc.web/src/main/resources/en/logout.js

@ -1,7 +1,5 @@
function handleLogout(response){ function handleLogout(response){
if (response.ok){ if (response.ok) document.body.innerHTML += 'success';
document.body.innerHTML += 'success'; redirect('index.html')
document.location.href='index.html';
}
} }
fetch(api+"/logout").then(handleLogout) fetch(api+"/logout").then(handleLogout)

7
de.srsoftware.oidc.web/src/main/resources/en/newclient.html

@ -4,13 +4,19 @@
<title>Light OIDC</title> <title>Light OIDC</title>
<script src="common.js"></script> <script src="common.js"></script>
<script src="user.js"></script> <script src="user.js"></script>
<script src="newclient.js"></script>
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
</head> </head>
<body> <body>
<nav></nav>
<h1>Add new client</h1> <h1>Add new client</h1>
<fieldset> <fieldset>
<legend>Settings</legend> <legend>Settings</legend>
<table> <table>
<tr>
<th>client id</th>
<td><input type="text" size="50" id="client-id"></td>
</tr>
<tr> <tr>
<th>client name</th> <th>client name</th>
<td><input type="text" size="50" id="client-name"></td> <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> <td><textarea cols="50" rows="5" id="redirect-urls"></textarea></td>
</tr> </tr>
</table> </table>
<button id="button" type="button" onclick="addClient()">Add client</button>
</fieldset> </fieldset>
</body> </body>
</html> </html>

37
de.srsoftware.oidc.web/src/main/resources/en/newclient.js

@ -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);

5
de.srsoftware.oidc.web/src/main/resources/en/settings.js

@ -28,7 +28,6 @@ function handlePasswordResponse(response){
function update(){ function update(){
disable('updateBtn'); disable('updateBtn');
setText('updateBtn','sent…');
var newData = { var newData = {
username : getValue('username'), username : getValue('username'),
email : getValue('email'), email : getValue('email'),
@ -41,11 +40,11 @@ function update(){
}, },
body : JSON.stringify(newData) body : JSON.stringify(newData)
}).then(handleResponse) }).then(handleResponse)
setText('updateBtn','sent…');
} }
function updatePass(){ function updatePass(){
disable('passBtn'); disable('passBtn');
setText('passBtn','sent…');
var newData = { var newData = {
oldpass : getValue('oldpass'), oldpass : getValue('oldpass'),
newpass : [getValue('newpass1'),getValue('newpass2')], newpass : [getValue('newpass1'),getValue('newpass2')],
@ -58,7 +57,7 @@ function updatePass(){
}, },
body : JSON.stringify(newData) body : JSON.stringify(newData)
}).then(handlePasswordResponse); }).then(handlePasswordResponse);
setText('passBtn','sent…');
setTimeout(function(){ setTimeout(function(){
setText('passBtn','Update'); setText('passBtn','Update');
enable('passBtn'); enable('passBtn');

5
de.srsoftware.oidc.web/src/main/resources/en/style.css

@ -10,3 +10,8 @@ body fieldset {
a { a {
color: yellow; color: yellow;
} }
fieldset th,
form th{
text-align: right;
}

2
de.srsoftware.oidc.web/src/main/resources/en/user.js

@ -1,7 +1,7 @@
var user = null; var user = null;
async function handleUser(response){ async function handleUser(response){
if (response.status == UNAUTHORIZED) { 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; return;
} }
if (response.ok){ if (response.ok){

Loading…
Cancel
Save