User can control their own nodes: delete/expire

This commit is contained in:
Andrea Mistrali 2024-07-26 12:03:15 +02:00
parent facaaed9eb
commit 426c01ba6b
Signed by: andre
SSH Key Fingerprint: SHA256:/D780pZnuHMQ8xFII5lAtXWy8zdowtBhgWjwi88p+lI
7 changed files with 90 additions and 16 deletions

View File

@ -22,10 +22,16 @@ def remote_ip() -> str:
def username() -> str:
userinfo = flask_session['userinfo']
return userinfo['email'].split('@')[0]
def login_name() -> str:
userinfo = flask_session['userinfo']
if 'preferred_username' in userinfo:
return userinfo['preferred_username']
return userinfo['email']
else:
return username()
def webMode() -> bool:
@ -56,6 +62,7 @@ class OIDCAuthentication(_OIDCAuth):
session_refresh_interval_seconds=1800)
super().__init__({'default': provider_config})
super().init_app(app)
app.auth = self
def authorize(self, provider_name: str, authz_fn: Callable, **kwargs):
if provider_name not in self._provider_configurations:

View File

@ -47,6 +47,7 @@
<div class="col col-2"><strong>registered</strong></div>
<div class="col col-2"><strong>last event</strong></div>
<div class="col col-2"><strong>online</strong></div>
<div class="col col-2"><strong>&nbsp;</strong></div>
</div>
{% for node in userNodeList %}
<div class="row data">
@ -66,6 +67,13 @@
<div class="col col-2">
{{node.online | fancyBool | safe }}
</div>
<div class="col col-2">
<span data-toggle="tooltip" data-placement="right" title="delete">
<a class="nodeco" href="{{ url_for('rest.deleteOwnNode', nodeId=node.id) }}">
<i class="fas fa-trash"></i>
</a>
</span>
</div>
</div>
{% endfor %}
{% endblock %}

View File

@ -24,6 +24,9 @@
{% else %}
<span class="badge badge-pill badge-danger">offline</span>
{% endif %}
(<span data-toggle="tooltip" data-placement="right" title="{{ node.lastSeen | fmt_datetime }}">
{{ node.lastSeen | htime_dt }}
</span>)
</div>
</div>
<div class="row">

View File

@ -10,7 +10,7 @@
<th>name</th>
<th>user</th>
<th>expire</th>
<th>last event</th>
<th>last activity</th>
<th>addresses</th>
<th>online</th>
<th>&nbsp;</th>

View File

@ -23,8 +23,9 @@
<thead>
<tr>
<th>&nbsp;</th>
<th>last connect</th>
<th>last activity</th>
<th>online</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
@ -45,6 +46,22 @@
<td>
{{node.online | fancyBool | safe}}
</td>
<td class="no-sort">
{% if node.expireDate and not node.expired %}
<span data-toggle="tooltip" data-placement="right" title="expire/disconnect">
<a class="nodeco" href="{{ url_for('rest.expireNodeUser', nodeId=node.id) }}">
<i class="fas fa-plug"></i>
</a>
</span>
{% else %}
<i class="fas fa-plug disabled"></i>
{% endif %}
<span data-toggle="tooltip" data-placement="right" title="delete">
<a class="nodeco" href="{{ url_for('rest.deleteNodeUser', nodeId=node.id) }}">
<i class="fas fa-trash"></i>
</a>
</span>
</td>
</tr>
{% endfor %}
</tbody>

View File

@ -1,4 +1,3 @@
#SUKA
import logging
import datetime
import os
@ -41,8 +40,12 @@ def index():
@main_blueprint.route('/token', methods=['GET', 'POST'])
@auth.access_control('default')
def token():
print(auth.valid_access_token())
user_session = UserSession(session)
return jsonify(user_session.userinfo)
# return jsonify(user_session.userinfo)
return jsonify(access_token=user_session.access_token,
id_token=user_session.id_token,
userinfo=user_session.userinfo)
@main_blueprint.route('/logout')

View File

@ -4,7 +4,7 @@ from flask import Blueprint, request
from flask import redirect, url_for
from app import auth
from ..lib import username
from ..lib import login_name, username
from flask import jsonify
@ -51,6 +51,20 @@ def expireNode(nodeId: int):
return redirect(url_for("main.node", nodeId=nodeId))
@rest_blueprint.route('/node/<int:nodeId>/user-expire', methods=['GET'])
@auth.authorize_admins('default')
def expireNodeUser(nodeId: int):
"""
This expires a node from the node page.
The difference from above is that it returns to the /node/nodeId page
"""
node = Node().get(nodeId)
userName = node.user.name
Node().expire(nodeId)
log.info(f"node '{nodeId}' expired by '{username()}'")
return redirect(url_for("main.user", userName=userName))
@rest_blueprint.route('/node/<int:nodeId>/list-expire', methods=['GET'])
@auth.authorize_admins('default')
def expireNodeList(nodeId: int):
@ -63,22 +77,44 @@ def expireNodeList(nodeId: int):
return redirect(url_for("main.nodes"))
@rest_blueprint.route('/node/<int:nodeId>/delete', methods=['GET'])
@auth.authorize_admins('default')
@ rest_blueprint.route('/node/<int:nodeId>/delete', methods=['GET'])
@ auth.authorize_admins('default')
def deleteNode(nodeId: int):
Node().delete(nodeId)
log.info(f"node '{nodeId}' deleted by '{username()}'")
return redirect(url_for("main.nodes"))
@rest_blueprint.route('/node/<int:nodeId>/rename/<newName>', methods=['GET'])
@auth.authorize_admins('default')
@rest_blueprint.route('/node/<int:nodeId>/delete-own', methods=['GET'])
@auth.access_control('default')
def deleteOwnNode(nodeId: int):
node = Node().get(nodeId)
if node.user.name != username():
response = jsonify({'message': 'not authorized'})
return response, 401
Node().delete(nodeId)
log.info(f"'{username()}' delete their own node '{nodeId}'")
return redirect(url_for("main.index"))
@rest_blueprint.route('/node/<int:nodeId>/delete-user', methods=['GET'])
@auth.access_control('default')
def deleteNodeUser(nodeId: int):
node = Node().get(nodeId)
Node().delete(nodeId)
log.info(f"'{username()}' delete their own node '{nodeId}'")
return redirect(url_for("main.user", userName=node.user.name))
@ rest_blueprint.route('/node/<int:nodeId>/rename/<newName>', methods=['GET'])
@ auth.authorize_admins('default')
def renameNode(nodeId: int, newName: str):
Node().rename(nodeId, newName)
return jsonify(dict(newName=newName))
@rest_blueprint.route('/user/<userName>/delete', methods=['GET'])
@auth.authorize_admins('default')
@ rest_blueprint.route('/user/<userName>/delete', methods=['GET'])
@ auth.authorize_admins('default')
def deleteUser(userName: str):
nodes = Node().byUser(userName)
for node in nodes.nodes:
@ -88,8 +124,8 @@ def deleteUser(userName: str):
return redirect(url_for("main.users"))
@rest_blueprint.route('/user/<userName>/pakcreate', methods=['POST'])
@auth.authorize_admins('default')
@ rest_blueprint.route('/user/<userName>/pakcreate', methods=['POST'])
@ auth.authorize_admins('default')
def createPKA(userName: str):
data = request.json
log.debug(data)
@ -102,8 +138,8 @@ def createPKA(userName: str):
return jsonify(dict(key=pak.preAuthKey.key))
@rest_blueprint.route('/user/<userName>/expire/<key>', methods=['GET'])
@auth.authorize_admins('default')
@ rest_blueprint.route('/user/<userName>/expire/<key>', methods=['GET'])
@ auth.authorize_admins('default')
def expirePKA(userName: str, key: str):
log.debug(key)
req = v1ExpirePreAuthKeyRequest(user=userName, key=key)