page rename, successful MySQL test

This commit is contained in:
KF7EEL 2021-06-19 08:58:15 -07:00
parent c761e740bc
commit 3c461363a4
4 changed files with 212 additions and 149 deletions

View File

@ -1,8 +1,8 @@
![ ](https://raw.githubusercontent.com/kf7eel/hblink3/hbnet/HBNet.png "Logo")
HBNet is a fork of HBLink3 the extends the functionality of HBLink through several optional features, making it more of a usable application and less of a framework. HBNet aims to be complete and easy to use application that can be used to build, administrate, and run a DMR network.
HBNet is a fork of [HBlink3](https://github.com/HBLink-org/hblink3) the extends the functionality of HBLink through several optional features, making it more of a usable application and less of a framework. HBNet aims to be complete and easy to use application that can be used to build, administrate, and run a DMR network.
HBNet consists of 2 parts, web control panel, and the actual DMR server, based on HBLink.
HBNet consists of 2 parts, HBNet Web Server and the actual DMR server, based on HBLink.
### User end features:
@ -11,16 +11,29 @@ HBNet consists of 2 parts, web control panel, and the actual DMR server, based o
* Individual passphrases for each user
* Automatic retrieval of DMR IDs on registration
* Monitor and change active talkgroups (WORK IN PROGRESS)
### Administrative features:
* Administrate multiple DMR servers through the web panel
* Optional manual approval of new users
* Multiple Admin user logins
* Entirely configure HBLink in web panel
* Entirely configure DMR server (HBlink) in web server
* Log all peer authentication
### Other features
* SQLite or MySQL backend
* APRS and SMS features (WORK IN PROGRESS)
---
### FOR SUPPORT, DISCUSSION, GETTING INVOLVED ###

View File

@ -1,4 +1,25 @@
# HBLink User Managment Server
# HBNet Web Server
###############################################################################
# HBNet Web Server - Copyright (C) 2020 Eric Craw, KF7EEL <kf7eel@qsl.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
###############################################################################
'''
Flask based application that is the web server for HBNet. Controls user authentication, DMR server config, etc.
'''
from flask import Flask, render_template_string, request, make_response, jsonify, render_template, Markup, flash, redirect, url_for, current_app
from flask_sqlalchemy import SQLAlchemy
@ -124,17 +145,17 @@ def create_app():
# User authentication information. The collation='NOCASE' is required
# to search case insensitively when USER_IFIND_MODE is 'nocase_collation'.
username = db.Column(db.String(100, collation='NOCASE'), nullable=False, unique=True)
username = db.Column(db.String(100,), nullable=False, unique=True)
password = db.Column(db.String(255), nullable=False, server_default='')
email_confirmed_at = db.Column(db.DateTime())
email = db.Column(db.String(255, collation='NOCASE'), nullable=False, unique=True)
email = db.Column(db.String(255), nullable=False, unique=True)
# User information
first_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
last_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
dmr_ids = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
city = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
notes = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
first_name = db.Column(db.String(100), nullable=False, server_default='')
last_name = db.Column(db.String(100), nullable=False, server_default='')
dmr_ids = db.Column(db.String(100), nullable=False, server_default='')
city = db.Column(db.String(100), nullable=False, server_default='')
notes = db.Column(db.String(100), nullable=False, server_default='')
#Used for initial approval
initial_admin_approved = db.Column('initial_admin_approved', db.Boolean(), nullable=False, server_default='1')
# Define the relationship to Role via UserRoles
@ -154,212 +175,214 @@ def create_app():
role_id = db.Column(db.Integer(), db.ForeignKey('roles.id', ondelete='CASCADE'))
class BurnList(db.Model):
__tablename__ = 'burn_list'
## id = db.Column(db.Integer(), primary_key=True)
dmr_id = db.Column(db.Integer(), unique=True, primary_key=True)
version = db.Column(db.Integer(), primary_key=True)
class AuthLog(db.Model):
__tablename__ = 'auth_log'
login_dmr_id = db.Column(db.Integer(), primary_key=True)
login_time = db.Column(db.DateTime(), primary_key=True)
peer_ip = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
server_name = db.Column(db.Integer(), primary_key=True)
login_auth_method = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
portal_username = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
login_type = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
id = db.Column(db.Integer(), primary_key=True)
login_dmr_id = db.Column(db.Integer())
login_time = db.Column(db.DateTime())
peer_ip = db.Column(db.String(100), nullable=False, server_default='')
server_name = db.Column(db.String(100))
login_auth_method = db.Column(db.String(100), nullable=False, server_default='')
portal_username = db.Column(db.String(100), nullable=False, server_default='')
login_type = db.Column(db.String(100), nullable=False, server_default='')
class mmdvmPeer(db.Model):
__tablename__ = 'MMDVM_peers'
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
name = db.Column(db.String(100), nullable=False, server_default='')
enabled = db.Column(db.Boolean(), nullable=False, server_default='1')
loose = db.Column(db.Boolean(), nullable=False, server_default='1')
ip = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='127.0.0.1')
ip = db.Column(db.String(100), nullable=False, server_default='127.0.0.1')
port = db.Column(db.Integer(), primary_key=False)
master_ip = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
master_ip = db.Column(db.String(100), nullable=False, server_default='')
master_port = db.Column(db.Integer(), primary_key=False)
passphrase = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
callsign = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
passphrase = db.Column(db.String(100), nullable=False, server_default='')
callsign = db.Column(db.String(100), nullable=False, server_default='')
radio_id = db.Column(db.Integer(), primary_key=False)
rx_freq = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
tx_freq = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
tx_power = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
color_code = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
latitude = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
longitude = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
height = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
location = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
description = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
slots = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
url = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
group_hangtime = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
rx_freq = db.Column(db.String(100), nullable=False, server_default='')
tx_freq = db.Column(db.String(100), nullable=False, server_default='')
tx_power = db.Column(db.String(100), nullable=False, server_default='')
color_code = db.Column(db.String(100), nullable=False, server_default='')
latitude = db.Column(db.String(100), nullable=False, server_default='')
longitude = db.Column(db.String(100), nullable=False, server_default='')
height = db.Column(db.String(100), nullable=False, server_default='')
location = db.Column(db.String(100), nullable=False, server_default='')
description = db.Column(db.String(100), nullable=False, server_default='')
slots = db.Column(db.String(100), nullable=False, server_default='')
url = db.Column(db.String(100), nullable=False, server_default='')
group_hangtime = db.Column(db.String(100), nullable=False, server_default='')
enable_unit = db.Column(db.Boolean(), nullable=False, server_default='1')
options = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
options = db.Column(db.String(100), nullable=False, server_default='')
use_acl = db.Column(db.Boolean(), nullable=False, server_default='0')
sub_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
tg1_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
tg2_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
server = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
notes = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
sub_acl = db.Column(db.String(100), nullable=False, server_default='')
tg1_acl = db.Column(db.String(100), nullable=False, server_default='')
tg2_acl = db.Column(db.String(100), nullable=False, server_default='')
server = db.Column(db.String(100), nullable=False, server_default='')
notes = db.Column(db.String(100), nullable=False, server_default='')
class xlxPeer(db.Model):
__tablename__ = 'XLX_peers'
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
name = db.Column(db.String(100), nullable=False, server_default='')
enabled = db.Column(db.Boolean(), nullable=False, server_default='1')
loose = db.Column(db.Boolean(), nullable=False, server_default='1')
ip = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='127.0.0.1')
ip = db.Column(db.String(100), nullable=False, server_default='127.0.0.1')
port = db.Column(db.Integer(), primary_key=False)
master_ip = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
master_ip = db.Column(db.String(100), nullable=False, server_default='')
master_port = db.Column(db.Integer(), primary_key=False)
passphrase = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
callsign = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
passphrase = db.Column(db.String(100), nullable=False, server_default='')
callsign = db.Column(db.String(100), nullable=False, server_default='')
radio_id = db.Column(db.Integer(), primary_key=False)
rx_freq = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
tx_freq = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
tx_power = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
color_code = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
latitude = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
longitude = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
height = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
location = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
description = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
slots = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
url = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
group_hangtime = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
xlxmodule = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
options = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
rx_freq = db.Column(db.String(100), nullable=False, server_default='')
tx_freq = db.Column(db.String(100), nullable=False, server_default='')
tx_power = db.Column(db.String(100), nullable=False, server_default='')
color_code = db.Column(db.String(100), nullable=False, server_default='')
latitude = db.Column(db.String(100), nullable=False, server_default='')
longitude = db.Column(db.String(100), nullable=False, server_default='')
height = db.Column(db.String(100), nullable=False, server_default='')
location = db.Column(db.String(100), nullable=False, server_default='')
description = db.Column(db.String(100), nullable=False, server_default='')
slots = db.Column(db.String(100), nullable=False, server_default='')
url = db.Column(db.String(100), nullable=False, server_default='')
group_hangtime = db.Column(db.String(100), nullable=False, server_default='')
xlxmodule = db.Column(db.String(100), nullable=False, server_default='')
options = db.Column(db.String(100), nullable=False, server_default='')
enable_unit = db.Column(db.Boolean(), nullable=False, server_default='1')
use_acl = db.Column(db.Boolean(), nullable=False, server_default='0')
sub_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
tg1_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
tg2_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
server = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
notes = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
sub_acl = db.Column(db.String(100), nullable=False, server_default='')
tg1_acl = db.Column(db.String(100), nullable=False, server_default='')
tg2_acl = db.Column(db.String(100), nullable=False, server_default='')
server = db.Column(db.String(100), nullable=False, server_default='')
notes = db.Column(db.String(100), nullable=False, server_default='')
class ServerList(db.Model):
__tablename__ = 'server_list'
name = db.Column(db.String(100, collation='NOCASE'), unique=True, primary_key=True)
name = db.Column(db.String(100), unique=True, primary_key=True)
secret = db.Column(db.String(255), nullable=False, server_default='')
## public_list = db.Column(db.Boolean(), nullable=False, server_default='1')
id = db.Column(db.Integer(), primary_key=False)
ip = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
ip = db.Column(db.String(100), nullable=False, server_default='')
port = db.Column(db.Integer(), primary_key=False)
global_path = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='./')
global_path = db.Column(db.String(100), nullable=False, server_default='./')
global_ping_time = db.Column(db.Integer(), primary_key=False)
global_max_missed = db.Column(db.Integer(), primary_key=False)
global_use_acl = db.Column(db.Boolean(), nullable=False, server_default='1')
global_reg_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='PERMIT:ALL')
global_sub_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='DENY:1')
global_tg1_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='PERMIT:ALL')
global_tg2_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='PERMIT:ALL')
global_reg_acl = db.Column(db.String(100), nullable=False, server_default='PERMIT:ALL')
global_sub_acl = db.Column(db.String(100), nullable=False, server_default='DENY:1')
global_tg1_acl = db.Column(db.String(100), nullable=False, server_default='PERMIT:ALL')
global_tg2_acl = db.Column(db.String(100), nullable=False, server_default='PERMIT:ALL')
ai_try_download = db.Column(db.Boolean(), nullable=False, server_default='1')
ai_path = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='./')
ai_peer_file = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='peer_ids.json')
ai_subscriber_file = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='subscriber_ids.json')
ai_tgid_file = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='talkgroup_ids.json')
ai_peer_url = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='https://www.radioid.net/static/rptrs.json')
ai_subs_url = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='https://www.radioid.net/static/users.json')
ai_path = db.Column(db.String(100), nullable=False, server_default='./')
ai_peer_file = db.Column(db.String(100), nullable=False, server_default='peer_ids.json')
ai_subscriber_file = db.Column(db.String(100), nullable=False, server_default='subscriber_ids.json')
ai_tgid_file = db.Column(db.String(100), nullable=False, server_default='talkgroup_ids.json')
ai_peer_url = db.Column(db.String(100), nullable=False, server_default='https://www.radioid.net/static/rptrs.json')
ai_subs_url = db.Column(db.String(100), nullable=False, server_default='https://www.radioid.net/static/users.json')
ai_stale = db.Column(db.Integer(), primary_key=False, server_default='7')
# Pull from config file for now
## um_append_int = db.Column(db.Integer(), primary_key=False, server_default='2')
um_shorten_passphrase = db.Column(db.Boolean(), nullable=False, server_default='0')
um_burn_file = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='./burned_ids.txt')
um_burn_file = db.Column(db.String(100), nullable=False, server_default='./burned_ids.txt')
# Pull from config file for now
## um_burn_int = db.Column(db.Integer(), primary_key=False, server_default='6')
report_enable = db.Column(db.Boolean(), nullable=False, server_default='1')
report_interval = db.Column(db.Integer(), primary_key=False, server_default='60')
report_port = db.Column(db.Integer(), primary_key=False, server_default='4321')
report_clients =db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='127.0.0.1')
report_clients =db.Column(db.String(100), nullable=False, server_default='127.0.0.1')
unit_time = db.Column(db.Integer(), primary_key=False, server_default='10080')
notes = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
notes = db.Column(db.String(100), nullable=False, server_default='')
class MasterList(db.Model):
__tablename__ = 'master_list'
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
name = db.Column(db.String(100), nullable=False, server_default='')
static_positions = db.Column(db.Boolean(), nullable=False, server_default='0')
repeat = db.Column(db.Boolean(), nullable=False, server_default='1')
active = db.Column(db.Boolean(), nullable=False, server_default='1')
max_peers = db.Column(db.Integer(), primary_key=False, server_default='10')
ip = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
ip = db.Column(db.String(100), nullable=False, server_default='')
port = db.Column(db.Integer(), primary_key=False)
enable_um = db.Column(db.Boolean(), nullable=False, server_default='1')
passphrase = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
passphrase = db.Column(db.String(100), nullable=False, server_default='')
group_hang_time = db.Column(db.Integer(), primary_key=False, server_default='5')
use_acl = db.Column(db.Boolean(), nullable=False, server_default='1')
reg_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
sub_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
tg1_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
tg2_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
reg_acl = db.Column(db.String(100), nullable=False, server_default='')
sub_acl = db.Column(db.String(100), nullable=False, server_default='')
tg1_acl = db.Column(db.String(100), nullable=False, server_default='')
tg2_acl = db.Column(db.String(100), nullable=False, server_default='')
enable_unit = db.Column(db.Boolean(), nullable=False, server_default='1')
server = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
notes = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
server = db.Column(db.String(100), nullable=False, server_default='')
notes = db.Column(db.String(100), nullable=False, server_default='')
public_list = db.Column(db.Boolean(), nullable=False, server_default='1')
class ProxyList(db.Model):
__tablename__ = 'proxy_list'
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
name = db.Column(db.String(100), nullable=False, server_default='')
active = db.Column(db.Boolean(), nullable=False, server_default='1')
static_positions = db.Column(db.Boolean(), nullable=False, server_default='0')
repeat = db.Column(db.Boolean(), nullable=False, server_default='1')
enable_um = db.Column(db.Boolean(), nullable=False, server_default='1')
passphrase = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
passphrase = db.Column(db.String(100), nullable=False, server_default='')
external_proxy = db.Column(db.Boolean(), nullable=False, server_default='0')
external_port = db.Column(db.Integer(), primary_key=False)
group_hang_time = db.Column(db.Integer(), primary_key=False)
internal_start_port = db.Column(db.Integer(), primary_key=False)
internal_stop_port = db.Column(db.Integer(), primary_key=False)
use_acl = db.Column(db.Boolean(), nullable=False, server_default='1')
reg_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
sub_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
tg1_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
tg2_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
reg_acl = db.Column(db.String(100), nullable=False, server_default='')
sub_acl = db.Column(db.String(100), nullable=False, server_default='')
tg1_acl = db.Column(db.String(100), nullable=False, server_default='')
tg2_acl = db.Column(db.String(100), nullable=False, server_default='')
enable_unit = db.Column(db.Boolean(), nullable=False, server_default='1')
server = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
notes = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
server = db.Column(db.String(100), nullable=False, server_default='')
notes = db.Column(db.String(100), nullable=False, server_default='')
public_list = db.Column(db.Boolean(), nullable=False, server_default='1')
class OBP(db.Model):
__tablename__ = 'OpenBridge'
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
name = db.Column(db.String(100), nullable=False, server_default='')
enabled = db.Column(db.Boolean(), nullable=False, server_default='1')
network_id = db.Column(db.Integer(), primary_key=False)
ip = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
ip = db.Column(db.String(100), nullable=False, server_default='')
port = db.Column(db.Integer(), primary_key=False)
passphrase = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
target_ip = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
passphrase = db.Column(db.String(100), nullable=False, server_default='')
target_ip = db.Column(db.String(100), nullable=False, server_default='')
target_port = db.Column(db.Integer(), primary_key=False)
both_slots = db.Column(db.Boolean(), nullable=False, server_default='1')
use_acl = db.Column(db.Boolean(), nullable=False, server_default='1')
sub_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
tg_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
sub_acl = db.Column(db.String(100), nullable=False, server_default='')
tg_acl = db.Column(db.String(100), nullable=False, server_default='')
enable_unit = db.Column(db.Boolean(), nullable=False, server_default='1')
server = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
notes = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
server = db.Column(db.String(100), nullable=False, server_default='')
notes = db.Column(db.String(100), nullable=False, server_default='')
class BridgeRules(db.Model):
__tablename__ = 'bridge_rules'
id = db.Column(db.Integer(), primary_key=True)
bridge_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
system_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
bridge_name = db.Column(db.String(100), nullable=False, server_default='')
system_name = db.Column(db.String(100), nullable=False, server_default='')
ts = db.Column(db.Integer(), primary_key=False)
tg = db.Column(db.Integer(), primary_key=False)
active = db.Column(db.Boolean(), nullable=False, server_default='1')
timeout = db.Column(db.Integer(), primary_key=False)
to_type = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
on = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
off = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
reset = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
server = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
to_type = db.Column(db.String(100), nullable=False, server_default='')
on = db.Column(db.String(100), nullable=False, server_default='')
off = db.Column(db.String(100), nullable=False, server_default='')
reset = db.Column(db.String(100), nullable=False, server_default='')
server = db.Column(db.String(100), nullable=False, server_default='')
public_list = db.Column(db.Boolean(), nullable=False, server_default='0')
proxy = db.Column(db.Boolean(), nullable=False, server_default='0')
class BridgeList(db.Model):
__tablename__ = 'bridge_list'
id = db.Column(db.Integer(), primary_key=True)
bridge_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
description = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
bridge_name = db.Column(db.String(100), nullable=False, server_default='')
description = db.Column(db.String(100), nullable=False, server_default='')
public_list = db.Column(db.Boolean(), nullable=False, server_default='0')
tg = db.Column(db.Integer(), primary_key=False)
@ -712,6 +735,7 @@ def create_app():
elif request.method == 'POST': # and request.form.get('callsign') and request.form.get('subject') and request.form.get('message'):
u = User.query.filter_by(username=request.args.get('callsign')).first()
msg = Message(recipients=[u.email],
sender=(title, MAIL_DEFAULT_SENDER),
subject=request.form.get('subject'),
body=request.form.get('message'))
mail.send(msg)
@ -880,8 +904,9 @@ def create_app():
edit_user.initial_admin_approved = True
db.session.commit()
msg = Message(recipients=[edit_user.email],
subject='Account Approval - ' + title,
body='''You are receiving this message because an administrator has approved your account. You may now login and view your MMDVM passphrase(s).''')
sender=(title, MAIL_DEFAULT_SENDER),
subject='Account Approval',
body='''You are receiving this message because an administrator has approved your account. You may now login and use ''' + title + '''.''')
mail.send(msg)
content = '''<p style="text-align: center;">User approved: <strong>''' + str(request.args.get('callsign')) + '''</strong></p>\n'''
@ -1457,7 +1482,7 @@ def create_app():
content = content + '</tbody></table>'
return render_template('flask_user_layout.html', markup_content = Markup(content))
@app.route('/self_care')
@app.route('/user_tg')
def tg_status():
cu = current_user
u = User.query.filter_by(username=cu.username).first()
@ -4967,4 +4992,4 @@ def create_app():
if __name__ == '__main__':
app = create_app()
app.run(debug = True, port=ums_port, host=ums_host)
app.run(debug = True, port=hws_port, host=hws_host)

View File

@ -1,33 +1,65 @@
'''
Settings for user management portal.
Settings for HBNet Web Server.
'''
# Database location
db_location = 'sqlite:///./users.db'
# Database options
# Using SQLite is simple and easiest. Comment out this line and uncomment the MySQL
# line to use a MySQL/MariaDB server.
db_location = 'sqlite:///hbnet.sqlite'
# Uncomment and change this line to use a MySQL DB. It is best to start with a fresh
# DB without data in it.
#db_location = 'mysql+pymysql://DB_USERNAME:DB_PASSWORD@DB_HOST:MySQL_PORT/DB_NAME'
# Title of the HBNet Web Server
title = 'HBNet DMR server'
# Port to run server
hws_port = 8080
# IP to run server on
hws_host = '127.0.0.1'
# Publicly accessible URL of the web server. THIS IS REQUIRED AND MUST BE CORRECT.
url = 'http://localhost:8080'
# Replace below with some random string such as an SHA256
secret_key = 'SUPER SECRET LONG KEY'
# Default state for newly created user accounts. Setting to False will require
# the approval of an admin user before the user can login.
default_account_state = True
# Legacy passphrase used in hblink.cfg
legacy_passphrase = 'passw0rd'
#legacy_passphrase = 'passw0rd'
# Trim passphrases to 8 characters
use_short_passphrase = False
# Title of the Dashboard
title = 'MMDVM User Portal'
# Port to run server
ums_port = 8080
# IP to run server on
ums_host = '127.0.0.1'
url = 'http://localhost:8080'
# Passphrase calculation config. If REMOTE_CONFIG is not used in your DMR server config
# (hblink.cfg), then the values in section [USER_MANAGER] MUST match the values below.
# If REMOTE_CONFIG is enabled, the DMR server (hblink) will automatically use the values below.
# These config options affect the generation of user passphrases.
# Set to a value between 1 - 99. This value is used in the normal calculation.
append_int = 1
shared_secrets = ['test']
# Set to a value between 1 - 99. This value is used for compromised passphrases.
burn_int = 5
legacy_passphrase = 'passw0rd'
# Set to a value between 1 - 99 This value is used in the normal calculation.
extra_int_1 = 5
# Set to a value between 1 - 99 This value is used in the normal calculation.
extra_int_2 = 8
# Set to a length of about 10 characters.
extra_1 = 'TeSt'
extra_2 = 'DmR4'
# Shorten generated passphrases
use_short_passphrase = True
# Character length of shortened passphrase
shorten_length = 6
# How often to pick character from long passphrase when shortening.
shorten_sample = 4
# Email settings
MAIL_SERVER = 'smtp.gmail.com'
@ -38,12 +70,10 @@ MAIL_USERNAME = 'app@gmail.com'
MAIL_PASSWORD = 'password'
MAIL_DEFAULT_SENDER = '"' + title + '" <app@gmail.com>'
# UMS settings
secret_key = 'SUPER SECRET LONG KEY'
# User settings settings
USER_ENABLE_EMAIL = True
USER_ENABLE_USERNAME = True # Enable username authentication
USER_REQUIRE_RETYPE_PASSWORD = True # Simplify register form
USER_ENABLE_USERNAME = True
USER_REQUIRE_RETYPE_PASSWORD = True
USER_ENABLE_CHANGE_USERNAME = False
USER_ENABLE_MULTIPLE_EMAILS = True
USER_ENABLE_CONFIRM_EMAIL = True
@ -51,12 +81,7 @@ USER_ENABLE_REGISTER = True
USER_AUTO_LOGIN_AFTER_CONFIRM = False
USER_SHOW_USERNAME_DOES_NOT_EXIST = True
# Gateway contact info displayed on about page.
contact_name = 'your name'
contact_call = 'N0CALL'
contact_email = 'email@example.org'
contact_website = 'https://hbl.ink'
# Time format for display
# Time format for display on some pages
time_format = '%H:%M:%S - %m/%d/%y'

View File

@ -53,7 +53,7 @@
{% endif %}
<td style="text-align: center;"><a href={{url}}/help>Help</a></td>
<td style="text-align: center;"><a href={{url}}/generate_passphrase>View Passphrase(s)</a></td>
<td style="text-align: center;"><a href={{url}}/self_care>Self Care</a></td>
<td style="text-align: center;"><a href={{url}}/user_tg>Current TGs</a></td>
<td style="text-align: center;"><a href="{{ url_for('user.edit_user_profile') }}">Edit {{ current_user.username or current_user.email }}</a></td>
<td style="text-align: center;"><a href={{ url_for('user.logout') }}>Sign out</a></td>
{% endif %}