forked from oscar.krause/fastapi-dls
Merge branch 'dev' into 'main'
1.3.4 See merge request oscar.krause/fastapi-dls!22
This commit is contained in:
commit
b905ab9dd9
@ -11,6 +11,7 @@ license=('MIT')
|
|||||||
depends=('python' 'python-jose' 'python-starlette' 'python-httpx' 'python-fastapi' 'python-dotenv' 'python-dateutil' 'python-sqlalchemy' 'python-pycryptodome' 'uvicorn' 'python-markdown' 'openssl')
|
depends=('python' 'python-jose' 'python-starlette' 'python-httpx' 'python-fastapi' 'python-dotenv' 'python-dateutil' 'python-sqlalchemy' 'python-pycryptodome' 'uvicorn' 'python-markdown' 'openssl')
|
||||||
provider=("$pkgname")
|
provider=("$pkgname")
|
||||||
install="$pkgname.install"
|
install="$pkgname.install"
|
||||||
|
backup=('etc/default/fastapi-dls')
|
||||||
source=('git+file:///builds/oscar.krause/fastapi-dls' # https://gitea.publichub.eu/oscar.krause/fastapi-dls.git
|
source=('git+file:///builds/oscar.krause/fastapi-dls' # https://gitea.publichub.eu/oscar.krause/fastapi-dls.git
|
||||||
"$pkgname.default"
|
"$pkgname.default"
|
||||||
"$pkgname.service"
|
"$pkgname.service"
|
||||||
|
26
README.md
26
README.md
@ -7,11 +7,31 @@ Compatibility tested with official DLS 2.0.1.
|
|||||||
This service can be used without internet connection.
|
This service can be used without internet connection.
|
||||||
Only the clients need a connection to this service on configured port.
|
Only the clients need a connection to this service on configured port.
|
||||||
|
|
||||||
|
**Official Links**
|
||||||
|
|
||||||
|
- https://git.collinwebdesigns.de/oscar.krause/fastapi-dls
|
||||||
|
- https://gitea.publichub.eu/oscar.krause/fastapi-dls
|
||||||
|
- Docker Image `collinwebdesigns/fastapi-dls:latest`
|
||||||
|
|
||||||
|
*All other repositories are forks! (which is no bad - just for information and bug reports)*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
[[_TOC_]]
|
[[_TOC_]]
|
||||||
|
|
||||||
|
|
||||||
# Setup (Service)
|
# Setup (Service)
|
||||||
|
|
||||||
|
**System requirements**
|
||||||
|
|
||||||
|
- 256mb ram
|
||||||
|
- 4gb hdd
|
||||||
|
|
||||||
|
Tested with Ubuntu 22.10 (from Proxmox templates), actually its consuming 100mb ram and 750mb hdd.
|
||||||
|
|
||||||
|
**Prepare your system**
|
||||||
|
|
||||||
|
- Make sure your timezone is set correct on you fastapi-dls server and your client
|
||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
Docker-Images are available here:
|
Docker-Images are available here:
|
||||||
@ -348,10 +368,6 @@ Shows current runtime environment variables and their values.
|
|||||||
|
|
||||||
HTML rendered README.md.
|
HTML rendered README.md.
|
||||||
|
|
||||||
### `GET /-/docs`, `GET /-/redoc`
|
|
||||||
|
|
||||||
OpenAPI specifications rendered from `GET /-/openapi.json`.
|
|
||||||
|
|
||||||
### `GET /-/manage`
|
### `GET /-/manage`
|
||||||
|
|
||||||
Shows a very basic UI to delete origins or leases.
|
Shows a very basic UI to delete origins or leases.
|
||||||
|
23
app/main.py
23
app/main.py
@ -22,12 +22,13 @@ from sqlalchemy.orm import sessionmaker
|
|||||||
from util import load_key, load_file
|
from util import load_key, load_file
|
||||||
from orm import Origin, Lease, init as db_init, migrate
|
from orm import Origin, Lease, init as db_init, migrate
|
||||||
|
|
||||||
logger = logging.getLogger()
|
|
||||||
load_dotenv('../version.env')
|
load_dotenv('../version.env')
|
||||||
|
|
||||||
|
TZ = datetime.now().astimezone().tzinfo
|
||||||
|
|
||||||
VERSION, COMMIT, DEBUG = env('VERSION', 'unknown'), env('COMMIT', 'unknown'), bool(env('DEBUG', False))
|
VERSION, COMMIT, DEBUG = env('VERSION', 'unknown'), env('COMMIT', 'unknown'), bool(env('DEBUG', False))
|
||||||
|
|
||||||
config = dict(openapi_url='/-/openapi.json', docs_url='/-/docs', redoc_url='/-/redoc')
|
config = dict(openapi_url=None, docs_url=None, redoc_url=None) # dict(openapi_url='/-/openapi.json', docs_url='/-/docs', redoc_url='/-/redoc')
|
||||||
app = FastAPI(title='FastAPI-DLS', description='Minimal Delegated License Service (DLS).', version=VERSION, **config)
|
app = FastAPI(title='FastAPI-DLS', description='Minimal Delegated License Service (DLS).', version=VERSION, **config)
|
||||||
db = create_engine(str(env('DATABASE', 'sqlite:///db.sqlite')))
|
db = create_engine(str(env('DATABASE', 'sqlite:///db.sqlite')))
|
||||||
db_init(db), migrate(db)
|
db_init(db), migrate(db)
|
||||||
@ -44,6 +45,7 @@ TOKEN_EXPIRE_DELTA = relativedelta(days=int(env('TOKEN_EXPIRE_DAYS', 1)), hours=
|
|||||||
LEASE_EXPIRE_DELTA = relativedelta(days=int(env('LEASE_EXPIRE_DAYS', 90)), hours=int(env('LEASE_EXPIRE_HOURS', 0)))
|
LEASE_EXPIRE_DELTA = relativedelta(days=int(env('LEASE_EXPIRE_DAYS', 90)), hours=int(env('LEASE_EXPIRE_HOURS', 0)))
|
||||||
LEASE_RENEWAL_PERIOD = float(env('LEASE_RENEWAL_PERIOD', 0.15))
|
LEASE_RENEWAL_PERIOD = float(env('LEASE_RENEWAL_PERIOD', 0.15))
|
||||||
LEASE_RENEWAL_DELTA = timedelta(days=int(env('LEASE_EXPIRE_DAYS', 90)), hours=int(env('LEASE_EXPIRE_HOURS', 0)))
|
LEASE_RENEWAL_DELTA = timedelta(days=int(env('LEASE_EXPIRE_DAYS', 90)), hours=int(env('LEASE_EXPIRE_HOURS', 0)))
|
||||||
|
CLIENT_TOKEN_EXPIRE_DELTA = relativedelta(years=12)
|
||||||
CORS_ORIGINS = str(env('CORS_ORIGINS', '')).split(',') if (env('CORS_ORIGINS')) else [f'https://{DLS_URL}']
|
CORS_ORIGINS = str(env('CORS_ORIGINS', '')).split(',') if (env('CORS_ORIGINS')) else [f'https://{DLS_URL}']
|
||||||
|
|
||||||
jwt_encode_key = jwk.construct(INSTANCE_KEY_RSA.export_key().decode('utf-8'), algorithm=ALGORITHMS.RS256)
|
jwt_encode_key = jwk.construct(INSTANCE_KEY_RSA.export_key().decode('utf-8'), algorithm=ALGORITHMS.RS256)
|
||||||
@ -58,6 +60,8 @@ app.add_middleware(
|
|||||||
allow_headers=['*'],
|
allow_headers=['*'],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logging.basicConfig()
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
logger.setLevel(logging.DEBUG if DEBUG else logging.INFO)
|
logger.setLevel(logging.DEBUG if DEBUG else logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
@ -97,6 +101,7 @@ async def _config():
|
|||||||
'LEASE_EXPIRE_DELTA': str(LEASE_EXPIRE_DELTA),
|
'LEASE_EXPIRE_DELTA': str(LEASE_EXPIRE_DELTA),
|
||||||
'LEASE_RENEWAL_PERIOD': str(LEASE_RENEWAL_PERIOD),
|
'LEASE_RENEWAL_PERIOD': str(LEASE_RENEWAL_PERIOD),
|
||||||
'CORS_ORIGINS': str(CORS_ORIGINS),
|
'CORS_ORIGINS': str(CORS_ORIGINS),
|
||||||
|
'TZ': str(TZ),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -192,7 +197,7 @@ async def _lease_delete(request: Request, lease_ref: str):
|
|||||||
@app.get('/-/client-token', summary='* Client-Token', description='creates a new messenger token for this service instance')
|
@app.get('/-/client-token', summary='* Client-Token', description='creates a new messenger token for this service instance')
|
||||||
async def _client_token():
|
async def _client_token():
|
||||||
cur_time = datetime.utcnow()
|
cur_time = datetime.utcnow()
|
||||||
exp_time = cur_time + relativedelta(years=12)
|
exp_time = cur_time + CLIENT_TOKEN_EXPIRE_DELTA
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"jti": str(uuid4()),
|
"jti": str(uuid4()),
|
||||||
@ -529,6 +534,18 @@ async def leasing_v1_lessor_shutdown(request: Request):
|
|||||||
return JSONr(response)
|
return JSONr(response)
|
||||||
|
|
||||||
|
|
||||||
|
@app.on_event('startup')
|
||||||
|
async def app_on_startup():
|
||||||
|
logger.info(f'''
|
||||||
|
Using timezone: {str(TZ)}. Make sure this is correct and match your clients!
|
||||||
|
|
||||||
|
Your clients renew their license every {str(Lease.calculate_renewal(LEASE_RENEWAL_PERIOD, LEASE_RENEWAL_DELTA))}.
|
||||||
|
If the renewal fails, the license is {str(LEASE_RENEWAL_DELTA)} valid.
|
||||||
|
|
||||||
|
Your client-token file (.tok) is valid for {str(CLIENT_TOKEN_EXPIRE_DELTA)}.
|
||||||
|
''')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
|
14
app/orm.py
14
app/orm.py
@ -57,12 +57,12 @@ class Origin(Base):
|
|||||||
session.close()
|
session.close()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def delete(engine: Engine, origins: ["Origin"] = None) -> int:
|
def delete(engine: Engine, origin_refs: [str] = None) -> int:
|
||||||
session = sessionmaker(bind=engine)()
|
session = sessionmaker(bind=engine)()
|
||||||
if origins is None:
|
if origin_refs is None:
|
||||||
deletions = session.query(Origin).delete()
|
deletions = session.query(Origin).delete()
|
||||||
else:
|
else:
|
||||||
deletions = session.query(Origin).filter(Origin.origin_ref in origins).delete()
|
deletions = session.query(Origin).filter(Origin.origin_ref in origin_refs).delete()
|
||||||
session.commit()
|
session.commit()
|
||||||
session.close()
|
session.close()
|
||||||
return deletions
|
return deletions
|
||||||
@ -170,6 +170,14 @@ class Lease(Base):
|
|||||||
renew = delta.total_seconds() * LEASE_RENEWAL_PERIOD
|
renew = delta.total_seconds() * LEASE_RENEWAL_PERIOD
|
||||||
renew = datetime.timedelta(seconds=renew)
|
renew = datetime.timedelta(seconds=renew)
|
||||||
expires = delta - renew # 19.2
|
expires = delta - renew # 19.2
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
LEASE_RENEWAL_PERIOD=0.15 # 15%
|
||||||
|
delta = datetime.timedelta(days=90)
|
||||||
|
renew = delta.total_seconds() * LEASE_RENEWAL_PERIOD
|
||||||
|
renew = datetime.timedelta(seconds=renew)
|
||||||
|
expires = delta - renew # 76 days, 12:00:00 hours
|
||||||
|
|
||||||
"""
|
"""
|
||||||
renew = delta.total_seconds() * renewal_period
|
renew = delta.total_seconds() * renewal_period
|
||||||
renew = timedelta(seconds=renew)
|
renew = timedelta(seconds=renew)
|
||||||
|
@ -5,4 +5,4 @@ pycryptodome==3.16.0
|
|||||||
python-dateutil==2.8.2
|
python-dateutil==2.8.2
|
||||||
sqlalchemy==1.4.46
|
sqlalchemy==1.4.46
|
||||||
markdown==3.4.1
|
markdown==3.4.1
|
||||||
python-dotenv==0.21.0
|
python-dotenv==0.21.1
|
||||||
|
@ -1 +1 @@
|
|||||||
VERSION=1.3.3
|
VERSION=1.3.4
|
||||||
|
Loading…
Reference in New Issue
Block a user