User can control their own nodes: delete/expire
This commit is contained in:
parent
facaaed9eb
commit
426c01ba6b
|
@ -22,10 +22,16 @@ def remote_ip() -> str:
|
||||||
|
|
||||||
|
|
||||||
def username() -> str:
|
def username() -> str:
|
||||||
|
userinfo = flask_session['userinfo']
|
||||||
|
return userinfo['email'].split('@')[0]
|
||||||
|
|
||||||
|
|
||||||
|
def login_name() -> str:
|
||||||
userinfo = flask_session['userinfo']
|
userinfo = flask_session['userinfo']
|
||||||
if 'preferred_username' in userinfo:
|
if 'preferred_username' in userinfo:
|
||||||
return userinfo['preferred_username']
|
return userinfo['preferred_username']
|
||||||
return userinfo['email']
|
else:
|
||||||
|
return username()
|
||||||
|
|
||||||
|
|
||||||
def webMode() -> bool:
|
def webMode() -> bool:
|
||||||
|
@ -56,6 +62,7 @@ class OIDCAuthentication(_OIDCAuth):
|
||||||
session_refresh_interval_seconds=1800)
|
session_refresh_interval_seconds=1800)
|
||||||
super().__init__({'default': provider_config})
|
super().__init__({'default': provider_config})
|
||||||
super().init_app(app)
|
super().init_app(app)
|
||||||
|
app.auth = self
|
||||||
|
|
||||||
def authorize(self, provider_name: str, authz_fn: Callable, **kwargs):
|
def authorize(self, provider_name: str, authz_fn: Callable, **kwargs):
|
||||||
if provider_name not in self._provider_configurations:
|
if provider_name not in self._provider_configurations:
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
<div class="col col-2"><strong>registered</strong></div>
|
<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>last event</strong></div>
|
||||||
<div class="col col-2"><strong>online</strong></div>
|
<div class="col col-2"><strong>online</strong></div>
|
||||||
|
<div class="col col-2"><strong> </strong></div>
|
||||||
</div>
|
</div>
|
||||||
{% for node in userNodeList %}
|
{% for node in userNodeList %}
|
||||||
<div class="row data">
|
<div class="row data">
|
||||||
|
@ -66,6 +67,13 @@
|
||||||
<div class="col col-2">
|
<div class="col col-2">
|
||||||
{{node.online | fancyBool | safe }}
|
{{node.online | fancyBool | safe }}
|
||||||
</div>
|
</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>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="badge badge-pill badge-danger">offline</span>
|
<span class="badge badge-pill badge-danger">offline</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
(<span data-toggle="tooltip" data-placement="right" title="{{ node.lastSeen | fmt_datetime }}">
|
||||||
|
{{ node.lastSeen | htime_dt }}
|
||||||
|
</span>)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<th>name</th>
|
<th>name</th>
|
||||||
<th>user</th>
|
<th>user</th>
|
||||||
<th>expire</th>
|
<th>expire</th>
|
||||||
<th>last event</th>
|
<th>last activity</th>
|
||||||
<th>addresses</th>
|
<th>addresses</th>
|
||||||
<th>online</th>
|
<th>online</th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
|
|
|
@ -23,8 +23,9 @@
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
<th>last connect</th>
|
<th>last activity</th>
|
||||||
<th>online</th>
|
<th>online</th>
|
||||||
|
<th> </th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -45,6 +46,22 @@
|
||||||
<td>
|
<td>
|
||||||
{{node.online | fancyBool | safe}}
|
{{node.online | fancyBool | safe}}
|
||||||
</td>
|
</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>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#SUKA
|
|
||||||
import logging
|
import logging
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
|
@ -41,8 +40,12 @@ def index():
|
||||||
@main_blueprint.route('/token', methods=['GET', 'POST'])
|
@main_blueprint.route('/token', methods=['GET', 'POST'])
|
||||||
@auth.access_control('default')
|
@auth.access_control('default')
|
||||||
def token():
|
def token():
|
||||||
|
print(auth.valid_access_token())
|
||||||
user_session = UserSession(session)
|
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')
|
@main_blueprint.route('/logout')
|
||||||
|
|
|
@ -4,7 +4,7 @@ from flask import Blueprint, request
|
||||||
from flask import redirect, url_for
|
from flask import redirect, url_for
|
||||||
from app import auth
|
from app import auth
|
||||||
|
|
||||||
from ..lib import username
|
from ..lib import login_name, username
|
||||||
|
|
||||||
from flask import jsonify
|
from flask import jsonify
|
||||||
|
|
||||||
|
@ -51,6 +51,20 @@ def expireNode(nodeId: int):
|
||||||
return redirect(url_for("main.node", nodeId=nodeId))
|
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'])
|
@rest_blueprint.route('/node/<int:nodeId>/list-expire', methods=['GET'])
|
||||||
@auth.authorize_admins('default')
|
@auth.authorize_admins('default')
|
||||||
def expireNodeList(nodeId: int):
|
def expireNodeList(nodeId: int):
|
||||||
|
@ -67,9 +81,31 @@ def expireNodeList(nodeId: int):
|
||||||
@ auth.authorize_admins('default')
|
@ auth.authorize_admins('default')
|
||||||
def deleteNode(nodeId: int):
|
def deleteNode(nodeId: int):
|
||||||
Node().delete(nodeId)
|
Node().delete(nodeId)
|
||||||
|
log.info(f"node '{nodeId}' deleted by '{username()}'")
|
||||||
return redirect(url_for("main.nodes"))
|
return redirect(url_for("main.nodes"))
|
||||||
|
|
||||||
|
|
||||||
|
@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'])
|
@ rest_blueprint.route('/node/<int:nodeId>/rename/<newName>', methods=['GET'])
|
||||||
@ auth.authorize_admins('default')
|
@ auth.authorize_admins('default')
|
||||||
def renameNode(nodeId: int, newName: str):
|
def renameNode(nodeId: int, newName: str):
|
||||||
|
|
Loading…
Reference in New Issue