Version 1.0
This commit is contained in:
parent
ca72edd087
commit
454eae48a0
|
@ -16,7 +16,7 @@ class v1PreAuthKeyResponse(BaseModel):
|
||||||
|
|
||||||
class v1ExpirePreAuthKeyRequest(BaseModel):
|
class v1ExpirePreAuthKeyRequest(BaseModel):
|
||||||
user: str = Field(alias="user", default=None)
|
user: str = Field(alias="user", default=None)
|
||||||
key: int = Field(alias="key", default=None)
|
key: str = Field(alias="key", default=None)
|
||||||
|
|
||||||
|
|
||||||
class v1CreatePreAuthKeyRequest(BaseModel):
|
class v1CreatePreAuthKeyRequest(BaseModel):
|
||||||
|
|
|
@ -45,7 +45,10 @@ class v1PreAuthKey(BaseModel):
|
||||||
def expired(self) -> bool:
|
def expired(self) -> bool:
|
||||||
tzinfo = timezone(timedelta(hours=0)) # UTC
|
tzinfo = timezone(timedelta(hours=0)) # UTC
|
||||||
now = datetime.now(tzinfo)
|
now = datetime.now(tzinfo)
|
||||||
return self.expiration < now # type: ignore
|
exptime = self.expiration < now
|
||||||
|
expused = not self.reusable and self.used
|
||||||
|
expephemereal = self.ephemeral and self.used
|
||||||
|
return exptime or expused or expephemereal
|
||||||
|
|
||||||
|
|
||||||
class v1User(BaseModel):
|
class v1User(BaseModel):
|
||||||
|
|
|
@ -13,11 +13,11 @@ import os
|
||||||
mobility = Mobility()
|
mobility = Mobility()
|
||||||
|
|
||||||
client_metadata = ClientMetadata(
|
client_metadata = ClientMetadata(
|
||||||
client_id='client-id',
|
client_id=os.getenv('HSMAN_OIDC_CLIENT_ID'),
|
||||||
client_secret='client-secret')
|
client_secret=os.getenv('HSMAN_OIDC_CLIENT_SECRET'))
|
||||||
|
|
||||||
|
|
||||||
provider_config = ProviderConfiguration(issuer='oidc-issuer-url',
|
provider_config = ProviderConfiguration(issuer=os.getenv('HSMAN_OIDC_URL'),
|
||||||
client_metadata=client_metadata,
|
client_metadata=client_metadata,
|
||||||
auth_request_params={
|
auth_request_params={
|
||||||
'scope': ['openid',
|
'scope': ['openid',
|
||||||
|
|
|
@ -99,3 +99,7 @@ a.route.False {
|
||||||
div.dt-container div.dt-scroll-body {
|
div.dt-container div.dt-scroll-body {
|
||||||
border-bottom: none !important;
|
border-bottom: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tr.pka-hide {
|
||||||
|
visibility: collapse;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
function renameNode(nodeId) {
|
function renameNode(nodeId) {
|
||||||
var newName = $("#newName").val();
|
var newName = $("#newName").val();
|
||||||
var url = "/node/" + nodeId + "/rename/" + newName;
|
var url = `/node/${nodeId}/rename/${newName}`;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: url,
|
url: url,
|
||||||
xhrFields: {
|
xhrFields: {
|
||||||
|
@ -13,9 +13,38 @@ function renameNode(nodeId) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createPKA(username) {
|
||||||
|
console.log(username);
|
||||||
|
var url = `/user/${username}/pakcreate`;
|
||||||
|
console.log(url);
|
||||||
|
var ephemereal = $("#ephemereal").is(":checked");
|
||||||
|
var reusable = $("#reusable").is(":checked");
|
||||||
|
var expiration = $("#expiration").val();
|
||||||
|
console.log(expiration);
|
||||||
|
$.ajax({
|
||||||
|
url: url,
|
||||||
|
method: "POST",
|
||||||
|
dataType: "json",
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
xhrFields: {
|
||||||
|
withCredentials: true,
|
||||||
|
},
|
||||||
|
data: JSON.stringify({
|
||||||
|
ephemeral: ephemereal,
|
||||||
|
reusable: reusable,
|
||||||
|
expiration: expiration,
|
||||||
|
}),
|
||||||
|
|
||||||
|
success: function (data) {
|
||||||
|
$("#createPKA").modal("hide");
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function copyToClipboard(obj) {
|
function copyToClipboard(obj) {
|
||||||
var span = $(obj);
|
var span = $(obj);
|
||||||
var value = span.attr("data-original-title");
|
var value = span.attr("value");
|
||||||
var original = span.html();
|
var original = span.html();
|
||||||
try {
|
try {
|
||||||
navigator.clipboard.writeText(value);
|
navigator.clipboard.writeText(value);
|
||||||
|
@ -28,3 +57,12 @@ function copyToClipboard(obj) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleExpired(obj) {
|
||||||
|
var toggle = $(obj);
|
||||||
|
if (toggle.is(":checked")) {
|
||||||
|
$(".pka-expired").removeClass("pka-hide");
|
||||||
|
} else {
|
||||||
|
$(".pka-expired").addClass("pka-hide");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h3>
|
<h3>
|
||||||
<span id="givenName">
|
<span id="givenName">
|
||||||
|
@ -51,21 +50,21 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p></p>
|
<p></p>
|
||||||
<div class="row">
|
|
||||||
<div class="col col-3 float-left">
|
<!-- ADDRESSES -->
|
||||||
<h5>addresses</h5>
|
<h5>addresses</h5>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% for ip in node.ipAddresses %}
|
{% for ip in node.ipAddresses %}
|
||||||
<div class="row data">
|
<div class="row data">
|
||||||
<div class="col col-3 float-left">
|
<div class="col col-3">
|
||||||
{{ ip }}
|
{{ ip }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<p></p>
|
<p></p>
|
||||||
|
|
||||||
|
<!-- TAGS -->
|
||||||
<h5>tags</h5>
|
<h5>tags</h5>
|
||||||
<div class="row">
|
<div class="row data">
|
||||||
<div class="col col-3 float-left">
|
<div class="col col-3 float-left">
|
||||||
<strong>
|
<strong>
|
||||||
announced
|
announced
|
||||||
|
@ -74,7 +73,7 @@
|
||||||
<div class="col col-6 float-left">
|
<div class="col col-6 float-left">
|
||||||
{% if node.validTags %}
|
{% if node.validTags %}
|
||||||
{% for tag in node.validTags %}
|
{% for tag in node.validTags %}
|
||||||
<span class="badge badge-pill badge-success">
|
<span class="badge badge-pill badge-info">
|
||||||
{{ tag }}
|
{{ tag }}
|
||||||
</span>
|
</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -83,7 +82,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row data">
|
||||||
<div class="col col-3 float-left">
|
<div class="col col-3 float-left">
|
||||||
<strong>forced</strong>
|
<strong>forced</strong>
|
||||||
</div>
|
</div>
|
||||||
|
@ -100,12 +99,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- KEYS -->
|
||||||
<p></p>
|
<p></p>
|
||||||
<h5>keys</h5>
|
<h5>keys</h5>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row data">
|
||||||
<div class="col col-4 float-left">
|
<div class="col col-3 float-left">
|
||||||
<strong>machineKey</strong>
|
<strong>machineKey</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-8 float-left">
|
<div class="col col-8 float-left">
|
||||||
|
@ -113,8 +112,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row data">
|
||||||
<div class="col col-4 float-left">
|
<div class="col col-3 float-left">
|
||||||
<strong>nodeKey</strong>
|
<strong>nodeKey</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-8 float-left">
|
<div class="col col-8 float-left">
|
||||||
|
@ -122,43 +121,43 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row data">
|
||||||
<div class="col col-4 float-left">
|
<div class="col col-3 float-left">
|
||||||
<strong>discoKey</strong>
|
<strong>discoKey</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-8 float-left">
|
<div class="col col-8 float-left">
|
||||||
<code>{{ node.discoKey }}</code>
|
<code>{{ node.discoKey }}</code>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p></p>
|
<p></p>
|
||||||
|
|
||||||
|
<!-- ROUTES -->
|
||||||
<h5>routes
|
<h5>routes
|
||||||
{% if isExitNode %}
|
{% if isExitNode %}
|
||||||
<span class="small badge-pill badge-success">Exit Node</span>
|
<span class="small badge-pill badge-primary">Exit Node</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</h5>
|
</h5>
|
||||||
{% if routes %}
|
{% if routes %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-4 float-left">
|
<div class="col col-3 float-left">
|
||||||
<strong>prefix</strong>
|
<strong>prefix</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-4 float-left">
|
<div class="col col-3 float-left">
|
||||||
<strong>enabled</strong>
|
<strong>enabled</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-4 float-left">
|
<div class="col col-3 float-left">
|
||||||
<strong>primary</strong>
|
<strong>primary</strong>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% for route in routes | sort(attribute='prefix') %}
|
{% for route in routes | sort(attribute='prefix') %}
|
||||||
<div class="row data">
|
<div class="row data">
|
||||||
<div class="col col-4 float-left">
|
<div class="col col-3 float-left">
|
||||||
{{ route.prefix }}
|
{{ route.prefix }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-4 float-left">
|
<div class="col col-3 float-left">
|
||||||
{{ route.enabled | fancyBool | safe }}
|
{{ route.enabled | fancyBool | safe }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-4 float-left">
|
<div class="col col-3 float-left">
|
||||||
{{ route.isPrimary | fancyBool | safe }}
|
{{ route.isPrimary | fancyBool | safe }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -169,6 +168,7 @@
|
||||||
<h3>No routes announced</h3>
|
<h3>No routes announced</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<!-- rename modal -->
|
<!-- rename modal -->
|
||||||
<!-- Modal -->
|
<!-- Modal -->
|
||||||
|
@ -191,5 +191,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -14,12 +14,15 @@
|
||||||
<strong>registered</strong>
|
<strong>registered</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-8">
|
<div class="col col-8">
|
||||||
<span data-toggle="tooltip" data-placement="right" title="{{ user.createdAt | fmt_datetime }}">
|
<span data-toggle="tooltip"
|
||||||
|
data-placement="right"
|
||||||
|
title="{{ user.createdAt | fmt_datetime }}">
|
||||||
{{ user.createdAt | htime_dt }}
|
{{ user.createdAt | htime_dt }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p></p>
|
<p></p>
|
||||||
|
<!-- NODES -->
|
||||||
<h5>nodes</h5>
|
<h5>nodes</h5>
|
||||||
<table id="nodes" class="display" style="width:80%">
|
<table id="nodes" class="display" style="width:80%">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -38,7 +41,9 @@
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span data-toggle="tooltip" data-placement="right" title="{{ node.lastSeen | fmt_datetime }}">
|
<span data-toggle="tooltip"
|
||||||
|
data-placement="right"
|
||||||
|
title="{{ node.lastSeen | fmt_datetime }}">
|
||||||
{{node.lastSeen | htime_dt }}
|
{{node.lastSeen | htime_dt }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
@ -50,26 +55,40 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<p></p>
|
<p></p>
|
||||||
<h5>pre auth keys</h5>
|
<!-- PRE AUTH KEYS -->
|
||||||
|
<h5>
|
||||||
|
pre auth keys
|
||||||
|
|
||||||
|
<button class="btn btn-outline-primary btn-sm" data-toggle="modal" data-target="#createPKA">create</button>
|
||||||
|
|
||||||
|
</h5>
|
||||||
{% if preauthKeys %}
|
{% if preauthKeys %}
|
||||||
<table id="paks" class="display" style="width:80%">
|
<table id="paks" class="display" style="width:80%">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th> </th>
|
<th>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<label class="form-check-label small" for="showExpired">
|
||||||
|
show expired
|
||||||
|
</label>
|
||||||
|
<input type="checkbox" class="form-check-input form-control-sm" id="showExpired">
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
<th>created</th>
|
<th>created</th>
|
||||||
<th>expiration</th>
|
<th>expiration</th>
|
||||||
<th>attributes</th>
|
<th>attributes</th>
|
||||||
<!-- <th>valid</th> -->
|
<!-- <th> </th> -->
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for key in preauthKeys %}
|
{% for key in preauthKeys %}
|
||||||
<tr>
|
<tr class="pka{% if key.expired %} pka-expired pka-hide{% endif %}">
|
||||||
<td>
|
<td>
|
||||||
<span data-toggle="tooltip"
|
<span data-toggle="tooltip"
|
||||||
data-placement="right"
|
data-placement="right"
|
||||||
title="click to copy"
|
value="{{ key.key}}"
|
||||||
class="pak_copy">{{ key.key }}</span>
|
title="click to copy full value"
|
||||||
|
class="pak_copy">{{ key.key[:5] }}…{{ key.key[-5:] }}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span data-toggle="tooltip"
|
<span data-toggle="tooltip"
|
||||||
|
@ -97,7 +116,11 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<!-- <td>
|
<!-- <td>
|
||||||
{{(not key.expired) | fancyBool | safe}}
|
<span data-toggle="tooltip" data-placement="right" title="expire">
|
||||||
|
<a class="nodeco" href="/user/{{user.name}}/expire/{{key.key}}">
|
||||||
|
<i class="fas fa-trash"></i>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
</td> -->
|
</td> -->
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -111,7 +134,38 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<!-- new key modal -->
|
||||||
|
<div class="modal fade" id="createPKA" tabindex="-1" role="dialog" aria-labelledby="cretePKA" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="renameModalLabel">create new pre auth key</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" type="datetime-local" name="expiration" id="expiration" value="{{ defaultExpiry}}">
|
||||||
|
<label class="form-check-label" for="ephemereal">expiration</label>
|
||||||
|
</div>
|
||||||
|
<p></p>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" type="checkbox" name="reusable" id="reusable">
|
||||||
|
<label class="form-check-label" for="reusable">reusable</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input class="form-check-input" type="checkbox" name="ephemereal" id="ephemereal">
|
||||||
|
<label class="form-check-label" for="ephemereal">ephemereal</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||||
|
<button type="button" class="btn btn-primary" onClick="createPKA(user='{{user.name}}')">Save changes</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
|
@ -121,6 +175,9 @@
|
||||||
$('.pak_copy').on('click', function() {
|
$('.pak_copy').on('click', function() {
|
||||||
copyToClipboard(this)
|
copyToClipboard(this)
|
||||||
})
|
})
|
||||||
|
$('#showExpired').on('change', function() {
|
||||||
|
toggleExpired(this)
|
||||||
|
})
|
||||||
|
|
||||||
new DataTable('#nodes', {
|
new DataTable('#nodes', {
|
||||||
scrollY: 130,
|
scrollY: 130,
|
||||||
|
@ -138,7 +195,7 @@
|
||||||
keys: false,
|
keys: false,
|
||||||
});
|
});
|
||||||
new DataTable('#paks', {
|
new DataTable('#paks', {
|
||||||
scrollY: 130,
|
scrollY: 230,
|
||||||
scrollCollapse: true,
|
scrollCollapse: true,
|
||||||
paging: false,
|
paging: false,
|
||||||
// lengthMenu: [5, 10, 30, 50, { label: 'All', value: -1 }],
|
// lengthMenu: [5, 10, 30, 50, { label: 'All', value: -1 }],
|
||||||
|
|
|
@ -1,22 +1,26 @@
|
||||||
from flask import render_template, Blueprint
|
import logging
|
||||||
|
from .lib import remote_ip
|
||||||
|
import datetime
|
||||||
|
from flask import render_template, Blueprint, request
|
||||||
from flask import redirect, session, url_for
|
from flask import redirect, session, url_for
|
||||||
from app import auth
|
from app import auth
|
||||||
|
|
||||||
from flask import jsonify
|
from flask import jsonify
|
||||||
from flask_pyoidc.user_session import UserSession
|
from flask_pyoidc.user_session import UserSession
|
||||||
|
|
||||||
from hsapi import Node, User, Route, PreAuthKey, v1ListPreAuthKeyRequest
|
from hsapi import Node, User, Route, PreAuthKey
|
||||||
|
from hsapi.preauthkeys import (v1ListPreAuthKeyRequest,
|
||||||
|
v1CreatePreAuthKeyRequest,
|
||||||
|
v1ExpirePreAuthKeyRequest)
|
||||||
|
|
||||||
from .lib import remote_ip
|
|
||||||
|
|
||||||
import logging
|
|
||||||
log = logging.getLogger()
|
log = logging.getLogger()
|
||||||
|
|
||||||
main_blueprint = Blueprint('main', __name__)
|
main_blueprint = Blueprint('main', __name__)
|
||||||
|
|
||||||
|
|
||||||
@main_blueprint.route('/', methods=['GET', 'POST'])
|
@ main_blueprint.route('/', methods=['GET', 'POST'])
|
||||||
@auth.access_control('default')
|
@ auth.access_control('default')
|
||||||
def index():
|
def index():
|
||||||
user_session = UserSession(session)
|
user_session = UserSession(session)
|
||||||
hs_user = user_session.userinfo['email'].split('@')[0]
|
hs_user = user_session.userinfo['email'].split('@')[0]
|
||||||
|
@ -26,35 +30,35 @@ def index():
|
||||||
session=user_session)
|
session=user_session)
|
||||||
|
|
||||||
|
|
||||||
@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():
|
||||||
user_session = UserSession(session)
|
user_session = UserSession(session)
|
||||||
return jsonify(user_session.userinfo)
|
return jsonify(user_session.userinfo)
|
||||||
|
|
||||||
|
|
||||||
@main_blueprint.route('/call', methods=['GET', 'POST'])
|
@ main_blueprint.route('/call', methods=['GET', 'POST'])
|
||||||
@auth.access_control('default')
|
@ auth.access_control('default')
|
||||||
def call():
|
def call():
|
||||||
return "CALL OK"
|
return "CALL OK"
|
||||||
|
|
||||||
|
|
||||||
@main_blueprint.route('/logout')
|
@ main_blueprint.route('/logout')
|
||||||
@auth.oidc_logout
|
@ auth.oidc_logout
|
||||||
def logout():
|
def logout():
|
||||||
return redirect('/')
|
return redirect('/')
|
||||||
|
|
||||||
|
|
||||||
@main_blueprint.route('/nodes', methods=['GET'])
|
@ main_blueprint.route('/nodes', methods=['GET'])
|
||||||
@auth.authorize_admins('default')
|
@ auth.authorize_admins('default')
|
||||||
def nodes():
|
def nodes():
|
||||||
nodelist = Node().list()
|
nodelist = Node().list()
|
||||||
return render_template('nodes.html',
|
return render_template('nodes.html',
|
||||||
nodes=nodelist.nodes)
|
nodes=nodelist.nodes)
|
||||||
|
|
||||||
|
|
||||||
@main_blueprint.route('/node/<int:nodeId>', methods=['GET'])
|
@ main_blueprint.route('/node/<int:nodeId>', methods=['GET'])
|
||||||
@auth.authorize_admins('default')
|
@ auth.authorize_admins('default')
|
||||||
def node(nodeId):
|
def node(nodeId):
|
||||||
# There is a bug in HS api with retrieving a single node
|
# There is a bug in HS api with retrieving a single node
|
||||||
# and we added a workaround to hsapi, so node.get() returns a
|
# and we added a workaround to hsapi, so node.get() returns a
|
||||||
|
@ -69,8 +73,8 @@ def node(nodeId):
|
||||||
node=node)
|
node=node)
|
||||||
|
|
||||||
|
|
||||||
@main_blueprint.route('/users', methods=['GET'])
|
@ main_blueprint.route('/users', methods=['GET'])
|
||||||
@auth.authorize_admins('default')
|
@ auth.authorize_admins('default')
|
||||||
def users():
|
def users():
|
||||||
userList = User().list()
|
userList = User().list()
|
||||||
# Get online status of devices of the user
|
# Get online status of devices of the user
|
||||||
|
@ -85,24 +89,27 @@ def users():
|
||||||
online=online)
|
online=online)
|
||||||
|
|
||||||
|
|
||||||
@main_blueprint.route('/user/<userName>', methods=['GET'])
|
@ main_blueprint.route('/user/<userName>', methods=['GET'])
|
||||||
@auth.authorize_admins('default')
|
@ auth.authorize_admins('default')
|
||||||
def user(userName):
|
def user(userName):
|
||||||
user = User().get(userName)
|
user = User().get(userName)
|
||||||
userNodeList = [n for n in Node().list().nodes if n.user.name == userName]
|
userNodeList = [n for n in Node().list().nodes if n.user.name == userName]
|
||||||
preauthkeyreq = v1ListPreAuthKeyRequest(user=userName)
|
|
||||||
|
|
||||||
|
preauthkeyreq = v1ListPreAuthKeyRequest(user=userName)
|
||||||
preauthKeys = PreAuthKey().list(preauthkeyreq)
|
preauthKeys = PreAuthKey().list(preauthkeyreq)
|
||||||
validpak = [k for k in preauthKeys.preAuthKeys if not k.expired]
|
|
||||||
|
defaultExpiry = datetime.datetime.now() + datetime.timedelta(days=7)
|
||||||
|
expStr = defaultExpiry.strftime('%Y-%m-%dT%H:%M')
|
||||||
|
|
||||||
return render_template("user.html",
|
return render_template("user.html",
|
||||||
user=user.user,
|
user=user.user,
|
||||||
preauthKeys=validpak,
|
defaultExpiry=expStr,
|
||||||
|
preauthKeys=preauthKeys.preAuthKeys,
|
||||||
userNodeList=userNodeList)
|
userNodeList=userNodeList)
|
||||||
|
|
||||||
|
|
||||||
@main_blueprint.route('/routes', methods=['GET'])
|
@ main_blueprint.route('/routes', methods=['GET'])
|
||||||
@auth.authorize_admins('default')
|
@ auth.authorize_admins('default')
|
||||||
def routes():
|
def routes():
|
||||||
routes = Route().list()
|
routes = Route().list()
|
||||||
|
|
||||||
|
@ -120,8 +127,8 @@ def routes():
|
||||||
routes=final)
|
routes=final)
|
||||||
|
|
||||||
|
|
||||||
@main_blueprint.route('/routeToggle/<int:routeId>', methods=['GET'])
|
@ main_blueprint.route('/routeToggle/<int:routeId>', methods=['GET'])
|
||||||
@auth.authorize_admins('default')
|
@ auth.authorize_admins('default')
|
||||||
def routeToggle(routeId: int):
|
def routeToggle(routeId: int):
|
||||||
routes = Route().list()
|
routes = Route().list()
|
||||||
route = [r for r in routes.routes if r.id == routeId]
|
route = [r for r in routes.routes if r.id == routeId]
|
||||||
|
@ -134,36 +141,36 @@ def routeToggle(routeId: int):
|
||||||
return redirect(url_for("main.routes"))
|
return redirect(url_for("main.routes"))
|
||||||
|
|
||||||
|
|
||||||
@main_blueprint.route('/node/<int:nodeId>/expire', methods=['GET'])
|
@ main_blueprint.route('/node/<int:nodeId>/expire', methods=['GET'])
|
||||||
@auth.authorize_admins('default')
|
@ auth.authorize_admins('default')
|
||||||
def expireNode(nodeId: int):
|
def expireNode(nodeId: int):
|
||||||
Node().expire(nodeId)
|
Node().expire(nodeId)
|
||||||
return redirect(url_for("main.node", nodeId=nodeId))
|
return redirect(url_for("main.node", nodeId=nodeId))
|
||||||
|
|
||||||
|
|
||||||
@main_blueprint.route('/node/<int:nodeId>/list-expire', methods=['GET'])
|
@ main_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):
|
||||||
Node().expire(nodeId)
|
Node().expire(nodeId)
|
||||||
return redirect(url_for("main.nodes"))
|
return redirect(url_for("main.nodes"))
|
||||||
|
|
||||||
|
|
||||||
@main_blueprint.route('/node/<int:nodeId>/delete', methods=['GET'])
|
@ main_blueprint.route('/node/<int:nodeId>/delete', methods=['GET'])
|
||||||
@auth.authorize_admins('default')
|
@ auth.authorize_admins('default')
|
||||||
def deleteNode(nodeId: int):
|
def deleteNode(nodeId: int):
|
||||||
Node().delete(nodeId)
|
Node().delete(nodeId)
|
||||||
return redirect(url_for("main.nodes"))
|
return redirect(url_for("main.nodes"))
|
||||||
|
|
||||||
|
|
||||||
@main_blueprint.route('/node/<int:nodeId>/rename/<newName>', methods=['GET'])
|
@ main_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):
|
||||||
Node().rename(nodeId, newName)
|
Node().rename(nodeId, newName)
|
||||||
return jsonify(dict(newName=newName))
|
return jsonify(dict(newName=newName))
|
||||||
|
|
||||||
|
|
||||||
@main_blueprint.route('/user/<userName>/delete', methods=['GET'])
|
@ main_blueprint.route('/user/<userName>/delete', methods=['GET'])
|
||||||
@auth.authorize_admins('default')
|
@ auth.authorize_admins('default')
|
||||||
def deleteUser(userName: str):
|
def deleteUser(userName: str):
|
||||||
nodes = Node().byUser(userName)
|
nodes = Node().byUser(userName)
|
||||||
for node in nodes.nodes:
|
for node in nodes.nodes:
|
||||||
|
@ -171,3 +178,27 @@ def deleteUser(userName: str):
|
||||||
Node().delete(node.id)
|
Node().delete(node.id)
|
||||||
User().delete(userName)
|
User().delete(userName)
|
||||||
return redirect(url_for("main.users"))
|
return redirect(url_for("main.users"))
|
||||||
|
|
||||||
|
|
||||||
|
@ main_blueprint.route('/user/<userName>/pakcreate', methods=['POST'])
|
||||||
|
@ auth.authorize_admins('default')
|
||||||
|
def createPKA(userName: str):
|
||||||
|
data = request.json
|
||||||
|
log.debug(data)
|
||||||
|
expiration = f"{data['expiration']}:00Z"
|
||||||
|
req = v1CreatePreAuthKeyRequest(user=userName,
|
||||||
|
reusable=data['reusable'],
|
||||||
|
ephemeral=data['ephemeral'],
|
||||||
|
expiration=expiration)
|
||||||
|
pak = PreAuthKey().create((req))
|
||||||
|
return jsonify(dict(key=pak.preAuthKey.key))
|
||||||
|
|
||||||
|
|
||||||
|
@ main_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)
|
||||||
|
|
||||||
|
PreAuthKey().expire(req)
|
||||||
|
return redirect(url_for('main.user', userName=userName))
|
||||||
|
|
Loading…
Reference in New Issue