Browse Source

working on edit client

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
sqlite
Stephan Richter 7 months ago
parent
commit
80c8c750c6
  1. 6
      de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Client.java
  2. 9
      de.srsoftware.oidc.api/src/main/java/de/srsoftware/oidc/api/Constants.java
  3. 15
      de.srsoftware.oidc.backend/src/main/java/de/srsoftware/oidc/backend/Backend.java
  4. 39
      de.srsoftware.oidc.web/src/main/resources/en/clients.html
  5. 6
      de.srsoftware.oidc.web/src/main/resources/en/clients.js
  6. 11
      de.srsoftware.oidc.web/src/main/resources/en/common.js
  7. 41
      de.srsoftware.oidc.web/src/main/resources/en/edit_client.html
  8. 20
      de.srsoftware.oidc.web/src/main/resources/en/edit_client.js
  9. 28
      de.srsoftware.oidc.web/src/main/resources/en/login.html
  10. 6
      de.srsoftware.oidc.web/src/main/resources/en/login.js
  11. 5
      de.srsoftware.oidc.web/src/main/resources/en/newclient.html
  12. 2
      de.srsoftware.oidc.web/src/main/resources/en/newclient.js
  13. 22
      de.srsoftware.oidc.web/src/main/resources/en/settings.html
  14. 42
      de.srsoftware.oidc.web/src/main/resources/en/settings.js
  15. 14
      de.srsoftware.oidc.web/src/main/resources/en/style.css

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

@ -1,7 +1,13 @@
/* © SRSoftware 2024 */ /* © SRSoftware 2024 */
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api;
import static de.srsoftware.oidc.api.Constants.*;
import java.util.Map;
import java.util.Set; import java.util.Set;
public record Client(String id, String name, String secret, Set<String> redirectUris) { public record Client(String id, String name, String secret, Set<String> redirectUris) {
public Map<String, Object> map() {
return Map.of(CLIENT_ID, id, NAME, name, SECRET, secret, REDIRECT_URIS, redirectUris);
}
} }

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

@ -2,8 +2,9 @@
package de.srsoftware.oidc.api; package de.srsoftware.oidc.api;
public class Constants { public class Constants {
public static final String CLIENT_ID = "client_id"; public static final String CLIENT_ID = "client_id";
public static final String NAME = "name"; public static final String NAME = "name";
public static final String REDIRECT_URI = "redirect_uri"; public static final String REDIRECT_URI = "redirect_uri";
public static final String SECRET = "secret"; public static final String REDIRECT_URIS = "redirect_uris";
public static final String SECRET = "secret";
} }

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

@ -30,7 +30,7 @@ public class Backend extends PathHandler {
if (!session.user().hasPermission(MANAGE_CLIENTS)) return sendError(ex, "NOT ALLOWED"); if (!session.user().hasPermission(MANAGE_CLIENTS)) return sendError(ex, "NOT ALLOWED");
var json = json(ex); var json = json(ex);
var redirects = new HashSet<String>(); var redirects = new HashSet<String>();
for (Object o : json.getJSONArray(REDIRECT_URI)) { for (Object o : json.getJSONArray(REDIRECT_URIS)) {
if (o instanceof String s) redirects.add(s); if (o instanceof String s) redirects.add(s);
} }
var client = new Client(json.getString(CLIENT_ID), json.getString(NAME), json.getString(SECRET), redirects); var client = new Client(json.getString(CLIENT_ID), json.getString(NAME), json.getString(SECRET), redirects);
@ -128,6 +128,8 @@ public class Backend extends PathHandler {
return addClient(ex, session); return addClient(ex, session);
case "/authorize": case "/authorize":
return authorize(ex, session); return authorize(ex, session);
case "/client":
return loadClient(ex, session);
case "/clients": case "/clients":
return clients(ex, session); return clients(ex, session);
case "/update/password": case "/update/password":
@ -145,6 +147,17 @@ public class Backend extends PathHandler {
return SessionToken.from(ex).map(SessionToken::sessionId).flatMap(sessions::retrieve); return SessionToken.from(ex).map(SessionToken::sessionId).flatMap(sessions::retrieve);
} }
private boolean loadClient(HttpExchange ex, Session session) throws IOException {
if (!session.user().hasPermission(MANAGE_CLIENTS)) return sendEmptyResponse(HTTP_FORBIDDEN, ex);
var json = json(ex);
if (json.has(CLIENT_ID)) {
var clientID = json.getString(CLIENT_ID);
var client = clients.getClient(clientID).map(Client::map).map(JSONObject::new);
if (client.isPresent()) return sendContent(ex, client.get());
}
return sendEmptyResponse(HTTP_NOT_FOUND, ex);
}
private boolean logout(HttpExchange ex, Session session) throws IOException { private boolean logout(HttpExchange ex, Session session) throws IOException {
sessions.dropSession(session.id()); sessions.dropSession(session.id());
new SessionToken("").addTo(ex); new SessionToken("").addTo(ex);

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

@ -12,24 +12,25 @@
<a id="clients" href="clients.html">Clients</a> <a id="clients" href="clients.html">Clients</a>
</nav> </nav>
<h1>Clients</h1> <h1>Clients</h1>
<fieldset>
These are clients that are registered with LightOIDC: <legend>These are clients that are registered with LightOIDC:</legend>
<table> <table>
<tr> <tr>
<th>Client</th> <th>Client</th>
<th>ID</th> <th>ID</th>
<th>Redirect URLs</th> <th>Redirect URLs</th>
<th>Actions</th> <th>Actions</th>
</tr> </tr>
<tr id="bottom"> <tr id="bottom">
<td></td> <td></td>
<td></td> <td></td>
<td></td> <td></td>
<td> <td>
<button onclick="window.location.href='newclient.html';">Add new client…</button> <button onclick="window.location.href='newclient.html';">Add new client…</button>
</td> </td>
</tr> </tr>
</table> </table>
<span class="hidden" id="message">Really remove client "{}"?</span> <span class="hidden" id="message">Really remove client "{}"?</span>
</fieldset>
</body> </body>
</html> </html>

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

@ -8,7 +8,7 @@ async function handleClients(response){
for (let id in clients){ for (let id in clients){
var row = document.createElement("tr"); var row = document.createElement("tr");
var client = clients[id]; var client = clients[id];
row.innerHTML = "<td>"+client.name+"</td>\n<td>"+id+"</td>\n<td>"+client.redirect_uris.join("<br/>")+'</td>\n<td><button onclick="remove(\''+id+'\')" type="button">remove '+client.name+'</button></td>'; row.innerHTML = "<td>"+client.name+"</td>\n<td>"+id+"</td>\n<td>"+client.redirect_uris.join("<br/>")+'</td>\n<td><button onclick="remove(\''+id+'\')" type="button">remove '+client.name+'</button><button type="button" onclick="edit(\''+id+'\')">Edit</button></td>';
bottom.parentNode.insertBefore(row,bottom); bottom.parentNode.insertBefore(row,bottom);
} }
} }
@ -27,4 +27,8 @@ function remove(clientId){
} }
} }
function edit(clientId){
redirect("edit_client.html?id="+clientId);
}
fetch(api+"/clients",{method:'POST'}).then(handleClients); fetch(api+"/clients",{method:'POST'}).then(handleClients);

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

@ -19,6 +19,11 @@ function getValue(id){
return get(id).value; return get(id).value;
} }
function hide(id){
console.log('hide('+id+')');
get(id).style.display = 'none';
}
function redirect(page){ function redirect(page){
window.location.href = page; window.location.href = page;
} }
@ -29,6 +34,10 @@ function setText(id, text){
function setValue(id,newVal){ function setValue(id,newVal){
document.getElementById(id).value = newVal; get(id).value = newVal;
} }
function show(id){
console.log('show('+id+')');
get(id).style.display = '';
}

41
de.srsoftware.oidc.web/src/main/resources/en/edit_client.html

@ -0,0 +1,41 @@
<html>
<head>
<meta charset="utf-8">
<title>Light OIDC</title>
<script src="common.js"></script>
<script src="user.js"></script>
<script src="edit_client.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<nav></nav>
<h1>Edit client</h1>
<fieldset>
<legend>Data</legend>
<table>
<tr>
<th>ID</th>
<td><input type="text" disabled="true" id="client_id" /></td>
</tr>
<tr>
<th>Name</th>
<td><input type="text" id="name" /></td>
</tr>
<tr>
<th>Secret</th>
<td><input type="text" id="secret" /></td>
</tr>
<tr>
<th>Redirect URIs</th>
<td>
<textarea id="redirects"></textarea>
</td>
</tr>
<tr>
<td></td>
<td><button type="button" id="button">Update</button></td>
</tr>
</table>
</fieldset>
</body>
</html>

20
de.srsoftware.oidc.web/src/main/resources/en/edit_client.js

@ -0,0 +1,20 @@
var params = new URLSearchParams(window.location.search);
var id = params.get('id');
fetch(api+'/client',
{
method: 'POST',
body: JSON.stringify({
client_id : id
})
}).then(handleResponse);
async function handleResponse(response){
if (response.ok){
var json = await response.json();
get('client_id').value = json.client_id;
get('name').value = json.name;
get('secret').value = json.secret;
get('redirects').value = json.redirect_uris.join("\n");
}
}

28
de.srsoftware.oidc.web/src/main/resources/en/login.html

@ -10,16 +10,24 @@
<h1>Login</h1> <h1>Login</h1>
<fieldset id="login"> <fieldset id="login">
<legend>User credentials</legend> <legend>User credentials</legend>
<label> <table>
Username <tr>
<input type="text" id="username" /> <th>User name</th>
</label> <td><input type="text" id="username" /></td>
<label> </tr>
Password <tr>
<input type="password" id="password" onkeydown="keyDown()"/> <th>Password</th>
</label> <td><input type="password" id="password" onkeydown="keyDown()"/></td>
<button type="button" onClick="tryLogin()">Login</button> </tr>
<tr id="error" style="display: none">
<th>Error</th>
<td class="warning">Failed to log in!</td>
</tr>
<tr>
<td></td>
<td><button type="button" onClick="tryLogin()">Login</button></td>
</tr>
</table>
</fieldset> </fieldset>
<div id="error"></div>
</body> </body>
</html> </html>

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

@ -1,10 +1,11 @@
async function handleLogin(response){ async function handleLogin(response){
if (response.ok){ if (response.ok){
var body = await response.json(); var body = await response.json();
hide('error');
setTimeout(doRedirect,100); setTimeout(doRedirect,100);
} else {
show('error');
} }
return false;
} }
function doRedirect(){ function doRedirect(){
@ -14,7 +15,6 @@ function doRedirect(){
} }
function tryLogin(){ function tryLogin(){
document.getElementById("error").innerHTML = "";
var username = getValue('username'); var username = getValue('username');
var password = getValue('password'); var password = getValue('password');
fetch(api+"/login",{ fetch(api+"/login",{

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

@ -29,8 +29,11 @@
<th>redirect urls</th> <th>redirect urls</th>
<td><textarea cols="50" rows="5" id="redirect-urls"></textarea></td> <td><textarea cols="50" rows="5" id="redirect-urls"></textarea></td>
</tr> </tr>
<tr>
<td></td>
<td><button id="button" type="button" onclick="addClient()">Add client</button></td>
</tr>
</table> </table>
<button id="button" type="button" onclick="addClient()">Add client</button>
</fieldset> </fieldset>
</body> </body>
</html> </html>

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

@ -4,7 +4,7 @@ function addClient(){
client_id : getValue('client-id'), client_id : getValue('client-id'),
name : getValue('client-name'), name : getValue('client-name'),
secret : getValue('client-secret'), secret : getValue('client-secret'),
redirect_uri : getValue('redirect-urls').split("\n") redirect_uris : getValue('redirect-urls').split("\n")
}; };
fetch(api+'/add/client',{ fetch(api+'/add/client',{
method : 'POST', method : 'POST',

22
de.srsoftware.oidc.web/src/main/resources/en/settings.html

@ -28,8 +28,15 @@
<th>ID</th> <th>ID</th>
<td><input id="uuid" type="text" disabled="true"></td> <td><input id="uuid" type="text" disabled="true"></td>
</tr> </tr>
<tr id="update_error" style="display: none">
<th>Error</th>
<td class="warning">Failed to update settings!</td>
</tr>
<tr>
<td></td>
<td><button id="updateBtn" type="button" onClick="update()">Update</button></td>
</tr>
</table> </table>
<button id="updateBtn" type="button" onClick="update()">Update</button>
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend> <legend>
@ -48,8 +55,19 @@
<th>Repeat Password</th> <th>Repeat Password</th>
<td><input id="newpass2" type="password" onkeydown="passKeyDown()"></td> <td><input id="newpass2" type="password" onkeydown="passKeyDown()"></td>
</tr> </tr>
<tr id="wrong_password" style="display: none">
<th>Error</th>
<td class="warning">Wrong password!</td>
</tr>
<tr id="password_mismatch" style="display: none">
<th>Error</th>
<td class="warning">Mismatch between new password and repetition!</td>
</tr>
<tr>
<td></td>
<td><button id="passBtn" type="button" onClick="updatePass()">Update</button></td>
</tr>
</table> </table>
<button id="passBtn" type="button" onClick="updatePass()">Update</button>
</fieldset> </fieldset>
</form> </form>
</body> </body>

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

@ -11,18 +11,16 @@ function fillForm(){
function handleResponse(response){ function handleResponse(response){
setText('updateBtn',response.ok ? 'saved.' : 'failed!'); if (response.ok){
hide('update_error')
setText('updateBtn', 'saved.');
} else {
show('update_error');
setText('updateBtn', 'Update failed!');
}
enable('updateBtn');
setTimeout(function(){ setTimeout(function(){
setText('updateBtn','Update'); setText('updateBtn','Update');
enable('updateBtn');
},10000);
}
function handlePasswordResponse(response){
setText('passBtn',response.ok ? 'saved.' : 'failed!');
setTimeout(function(){
setText('passBtn','Update');
enable('passBtn');
},10000); },10000);
} }
@ -43,6 +41,26 @@ function update(){
setText('updateBtn','sent…'); setText('updateBtn','sent…');
} }
async function handlePasswordResponse(response){
if (response.ok){
hide('wrong_password');
hide('password_mismatch');
setText('passBtn', 'saved.');
} else {
setText('passBtn', 'Update failed!');
var text = await response.text();
if (text == 'wrong password') show('wrong_password');
if (text == 'password mismatch') show('password_mismatch');
}
enable('passBtn');
setTimeout(function(){
setText('passBtn','Update');
},10000);
}
function updatePass(){ function updatePass(){
disable('passBtn'); disable('passBtn');
var newData = { var newData = {
@ -58,10 +76,6 @@ function updatePass(){
body : JSON.stringify(newData) body : JSON.stringify(newData)
}).then(handlePasswordResponse); }).then(handlePasswordResponse);
setText('passBtn','sent…'); setText('passBtn','sent…');
setTimeout(function(){
setText('passBtn','Update');
enable('passBtn');
},10000);
} }
function passKeyDown(ev){ function passKeyDown(ev){

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

@ -5,12 +5,22 @@ body {
body fieldset { body fieldset {
border-radius: 10px; border-radius: 10px;
display: inline-block;
} }
a { a {
color: yellow; color: yellow;
} }
input, textarea{
width: 600px;
}
input:disabled{
color: white;
background-color: gray;
}
fieldset th, fieldset th,
form th{ form th{
text-align: right; text-align: right;
@ -18,4 +28,8 @@ form th{
.hidden{ .hidden{
display: none; display: none;
}
.warning{
color: yellow;
} }
Loading…
Cancel
Save