Compare commits
No commits in common. "master" and "0.9.21" have entirely different histories.
|
@ -266,4 +266,3 @@ tags
|
||||||
# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
|
# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
|
||||||
.flaskenv
|
.flaskenv
|
||||||
docker.env
|
docker.env
|
||||||
flask_session/
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ from flask import Flask, render_template, g
|
||||||
from werkzeug.exceptions import HTTPException
|
from werkzeug.exceptions import HTTPException
|
||||||
|
|
||||||
from flask_mobility import Mobility
|
from flask_mobility import Mobility
|
||||||
from flask_session import Session
|
|
||||||
|
|
||||||
from . import filters
|
from . import filters
|
||||||
from .lib import OIDCAuthentication
|
from .lib import OIDCAuthentication
|
||||||
|
@ -11,8 +10,6 @@ import os
|
||||||
mobility = Mobility()
|
mobility = Mobility()
|
||||||
|
|
||||||
auth = OIDCAuthentication()
|
auth = OIDCAuthentication()
|
||||||
# SESSION_TYPE = 'filesystem'
|
|
||||||
sess = Session()
|
|
||||||
|
|
||||||
|
|
||||||
def create_app(environment='development'):
|
def create_app(environment='development'):
|
||||||
|
@ -53,8 +50,6 @@ def create_app(environment='development'):
|
||||||
app.logger.info("jinja2 custom filters loaded")
|
app.logger.info("jinja2 custom filters loaded")
|
||||||
filters.init_app(app)
|
filters.init_app(app)
|
||||||
|
|
||||||
sess.init_app(app)
|
|
||||||
|
|
||||||
# Error handlers.
|
# Error handlers.
|
||||||
@app.errorhandler(HTTPException)
|
@app.errorhandler(HTTPException)
|
||||||
def handle_http_error(exc):
|
def handle_http_error(exc):
|
||||||
|
|
27
app/lib.py
27
app/lib.py
|
@ -5,7 +5,7 @@ from flask import request, abort, current_app
|
||||||
from flask import session as flask_session, jsonify
|
from flask import session as flask_session, jsonify
|
||||||
from flask_pyoidc import OIDCAuthentication as _OIDCAuth
|
from flask_pyoidc import OIDCAuthentication as _OIDCAuth
|
||||||
from flask_pyoidc.user_session import UserSession
|
from flask_pyoidc.user_session import UserSession
|
||||||
from flask_pyoidc.provider_configuration import ProviderConfiguration, ClientMetadata, ProviderMetadata
|
from flask_pyoidc.provider_configuration import ProviderConfiguration, ClientMetadata
|
||||||
|
|
||||||
from typing import Callable, List
|
from typing import Callable, List
|
||||||
|
|
||||||
|
@ -51,36 +51,35 @@ class OIDCAuthentication(_OIDCAuth):
|
||||||
super().init_app(app)
|
super().init_app(app)
|
||||||
app.auth = self
|
app.auth = self
|
||||||
|
|
||||||
@property
|
|
||||||
def userinfo(self) -> dict:
|
|
||||||
log.debug(flask_session.get('userinfo', {}))
|
|
||||||
return flask_session.get('userinfo', {})
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def username(self) -> str:
|
def username(self) -> str:
|
||||||
# This need to be changed after upgrading headscale version
|
userinfo = flask_session['userinfo']
|
||||||
# when hs will use the preferred_username field as username
|
return userinfo['email'].split('@')[0]
|
||||||
return self.email.split('@')[0]
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def email(self) -> str:
|
def email(self) -> str:
|
||||||
return self.userinfo.get('email', 'unknown')
|
userinfo = flask_session['userinfo']
|
||||||
|
return userinfo['email']
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def login_name(self) -> str:
|
def login_name(self) -> str:
|
||||||
return self.userinfo.get('preferred_username', self.username)
|
userinfo = flask_session['userinfo']
|
||||||
|
return userinfo.get('preferred_username', self.username)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def full_name(self) -> str:
|
def full_name(self) -> str:
|
||||||
return self.userinfo.get('name', self.username)
|
userinfo = flask_session['userinfo']
|
||||||
|
return userinfo.get('name')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def groups(self) -> list:
|
def groups(self) -> list:
|
||||||
return self.userinfo.get('groups', [])
|
userinfo = flask_session['userinfo']
|
||||||
|
return userinfo.get('groups') or []
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def isAdmin(self) -> bool:
|
def isAdmin(self) -> bool:
|
||||||
user_groups = self.userinfo.get('groups', [])
|
userinfo = flask_session['userinfo']
|
||||||
|
user_groups = userinfo.get('groups', [])
|
||||||
with current_app.app_context():
|
with current_app.app_context():
|
||||||
admin_groups = current_app.config.get('ADMIN_GROUPS', [])
|
admin_groups = current_app.config.get('ADMIN_GROUPS', [])
|
||||||
admin_users = current_app.config.get('ADMIN_USERS', [])
|
admin_users = current_app.config.get('ADMIN_USERS', [])
|
||||||
|
|
|
@ -101,7 +101,7 @@ function uploadACL(obj) {
|
||||||
});
|
});
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "policy/upload",
|
url: "/policy/upload",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
xhrFields: {
|
xhrFields: {
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
{{policy.updatedAt | htime_dt }}
|
{{policy.updatedAt | htime_dt }}
|
||||||
</span>
|
</span>
|
||||||
<div>
|
<div>
|
||||||
<button type="button" class="btn btn-outline-primary btn-sm plain"><a class="plain" href="{{ url_for('main.policy', action='view') }}" target="_blank">View</a></button>
|
<button type="button" class="btn btn-outline-primary btn-sm plain"><a class="plain" href="/policy/view" target="_blank">View</a></button>
|
||||||
<button type="button" class="btn btn-outline-primary btn-sm plain"><a class="plain" href="{{ url_for('main.policy', action='download') }}">Download</a></button>
|
<button type="button" class="btn btn-outline-primary btn-sm plain"><a class="plain" href="/policy/download">Download</a></button>
|
||||||
<button type="button" class="btn btn-outline-primary btn-sm plain" data-toggle="modal" data-target="#uploadACL">Upload</button>
|
<button type="button" class="btn btn-outline-primary btn-sm plain" data-toggle="modal" data-target="#uploadACL">Upload</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,6 +6,8 @@ from flask import render_template, Blueprint
|
||||||
from flask import redirect, session, url_for
|
from flask import redirect, session, url_for
|
||||||
from app import auth
|
from app import auth
|
||||||
|
|
||||||
|
# from ..lib import username
|
||||||
|
|
||||||
from flask import jsonify, make_response
|
from flask import jsonify, make_response
|
||||||
from flask_pyoidc.user_session import UserSession
|
from flask_pyoidc.user_session import UserSession
|
||||||
|
|
||||||
|
@ -45,8 +47,6 @@ def index():
|
||||||
@main_blueprint.route('/logout')
|
@main_blueprint.route('/logout')
|
||||||
@auth.oidc_logout
|
@auth.oidc_logout
|
||||||
def logout():
|
def logout():
|
||||||
# UserSession(session).clear()
|
|
||||||
session.clear()
|
|
||||||
return redirect(url_for('main.index'))
|
return redirect(url_for('main.index'))
|
||||||
|
|
||||||
|
|
||||||
|
@ -136,6 +136,7 @@ def routes():
|
||||||
@main_blueprint.route('/policy/<action>', methods=['GET'])
|
@main_blueprint.route('/policy/<action>', methods=['GET'])
|
||||||
@auth.authorize_admins('default')
|
@auth.authorize_admins('default')
|
||||||
def policy(action):
|
def policy(action):
|
||||||
|
log.debug(f"action: {action}")
|
||||||
policy = Policy().get()
|
policy = Policy().get()
|
||||||
if action == "view":
|
if action == "view":
|
||||||
return policy.json
|
return policy.json
|
||||||
|
|
|
@ -13,13 +13,8 @@ class BaseConfig(object):
|
||||||
APP_PREFIX = os.getenv('APP_PREFIX', '')
|
APP_PREFIX = os.getenv('APP_PREFIX', '')
|
||||||
DEBUG_TB_ENABLED = False
|
DEBUG_TB_ENABLED = False
|
||||||
WTF_CSRF_ENABLED = False
|
WTF_CSRF_ENABLED = False
|
||||||
# Session
|
|
||||||
# We store sessions in filesystem, max 100 files, expire in 2 hours
|
|
||||||
SESSION_TYPE = 'filesystem'
|
|
||||||
SESSION_FILE_THRESHOLD = 100
|
|
||||||
PERMANENT_SESSION_LIFETIME = 7200
|
|
||||||
|
|
||||||
# All the following vars can be overriden
|
# All the followinf vars can be overriden
|
||||||
# in the environment, using `HSMAN_` prefix
|
# in the environment, using `HSMAN_` prefix
|
||||||
SECRET_KEY = "secreto"
|
SECRET_KEY = "secreto"
|
||||||
ADMIN_GROUPS = "adminGroup"
|
ADMIN_GROUPS = "adminGroup"
|
||||||
|
@ -27,7 +22,6 @@ class BaseConfig(object):
|
||||||
OIDC_CLIENT_SECRET = 'client-secreto'
|
OIDC_CLIENT_SECRET = 'client-secreto'
|
||||||
OIDC_URL = "https://myidp.example.com/auth"
|
OIDC_URL = "https://myidp.example.com/auth"
|
||||||
OIDC_REDIRECT_URI = 'http://localhost:5000/auth'
|
OIDC_REDIRECT_URI = 'http://localhost:5000/auth'
|
||||||
OIDC_CLOCK_SKEW = 30
|
|
||||||
|
|
||||||
# These are required by hsapi, should not be defined here
|
# These are required by hsapi, should not be defined here
|
||||||
# HSAPI_SERVER = "https://headscale.example.com"
|
# HSAPI_SERVER = "https://headscale.example.com"
|
||||||
|
|
|
@ -17,7 +17,7 @@ RUN apk --update --no-cache add \
|
||||||
libffi-dev \
|
libffi-dev \
|
||||||
curl && \
|
curl && \
|
||||||
chmod g+w /run && \
|
chmod g+w /run && \
|
||||||
pip install poetry gunicorn poetry-plugin-export
|
pip install poetry gunicorn
|
||||||
|
|
||||||
COPY . /hsman
|
COPY . /hsman
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +1,10 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "hsman"
|
name = "hsman"
|
||||||
version = "0.9.24"
|
version = "0.9.21"
|
||||||
description = "Flask Admin webui for Headscale"
|
description = "Flask Admin webui for Headscale"
|
||||||
authors = ["Andrea Mistrali <andrea@mistrali.pw>"]
|
authors = ["Andrea Mistrali <andrea@mistrali.pw>"]
|
||||||
license = "BSD"
|
license = "BSD"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
package-mode = false
|
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = ">=3.11,<4.0"
|
python = ">=3.11,<4.0"
|
||||||
|
@ -18,7 +17,6 @@ flask-pydantic = "^0.12.0"
|
||||||
uvicorn = "^0.30.1"
|
uvicorn = "^0.30.1"
|
||||||
hsapi-client = "^0.9.9"
|
hsapi-client = "^0.9.9"
|
||||||
# hsapi_client = { path = "../hsapi-client", develop = true }
|
# hsapi_client = { path = "../hsapi-client", develop = true }
|
||||||
flask-session = "^0.8.0"
|
|
||||||
|
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
|
|
Loading…
Reference in New Issue