Skip to content

Commit

Permalink
Feature: Notification system (#1766)
Browse files Browse the repository at this point in the history
* added websocket reconnect javascript

* timeout fix

* FIXED server timout issue

* working port config

* added websockets

* fixed cypress test

* graceful exit, but client is slow

* fast shutdown

* Switch to other port, if this one is blocked

* better error handling

* undid the port retrying

* trying CI with different port for websockets

* added getting port from ENV

* test CI with longer wait time for cypress

* reset wait time to 1000

* test fix

* doc

* Bugfix: Flash cannot be called without a context.

If a WebAPI (initiated from a different thread) fails, and flash is acalled as a backup the flash is without context.

Now I simply added a attribute that flash cannot be called from any thread.  It now skips it during the "Trying to rebroadcast"

* restore feature that the WebAPI permission is updated

* js formatting

* doc and reshuffling methods

* localhost fix for cypress

* fixed bug that i introduced recently.

* doc

* refactoring

* refactoring

* fix bug and refactoring

* removed use_reloader=false

* made the CreateNotification more robust

* better log

* bug fix

* pytest fix

* bug fix

* pytest works... but ugly

* do not start the websockets server in the tests

* Introducing SPECTER_WEBSOCKET_ACTIVE

* fix for incomplete SPECTER_WEBSOCKET_ACTIVE

* fix for incomplete SPECTER_WEBSOCKET_ACTIVE

* working websockets server shutdown when main thread dies

* doc

* camelCase  for js

also changed WebAPI --> webapi

* better naming

* ssl working for python client and server, but not javascript

* minimal working example for self-signed ssl

* working minimal echo server in specter

works with self signed cert

* working user recognition

* working websocket server.  The client shows an ssl error

* added ssl_context, but doesn't work yet

* no error... not tested yet

* working

* working, but not in js yet

* almost working!!!

* client is not working

* still cannot get a 1 server to many clients working

* minimal client example

* working minimal exaple to send to all connected clients

* working (at first, but then disconnecting)

* working. but cient needs some simplifications

* working great!!!

* fix closing connection handling

* also for non ssl working

* doc and requirements

* better config

* fix for multiple connections of 1 user

* imports

* doc

* better logging

* added endpoint to test

* cleanup

* added a possibility to quit websocket connections via a special command.

* fix error message

* doc

* refactoring

* remove old code

* undo

* Docs: Add mobile access question to the FAQ (#1829)

* starting pytest

pytest mocking doesn't work yet

working pytest

* better descriptions

* more notification arguments

* added pytest

* move notifications.js such that it is always available

* fix css issue

* A test-page in the devhelper extension

* defaults that shows a message without changing values

* doc and rename: clarifying point about the flask flash

* improved logging formatting

* js_message_box  reflects noy the notification_type

* doc

addressing #1766 (comment)

* doc

addressing #1766 (comment)

* fix pytest

* doc and use get instead of []

* redirect flash call

* feature now complete

* documentation

* rename callback

* Adding add_wallettab

* moving to server_endpoints

* proper removal

* refactor robust_json_dumps import

* forgot one reference of robust_json_dumps

* remove unintended changes

* import fixes and polishing

* docs revised

* working notifications

* working

almost completely moved

* not working yet.... somehow sending to the server doesn't work.

* working

* added TODO

* redirect flash

* fix for flash

* implemented callbacks

Can test with js code
a = await pythonCommand("app.specter.service_manager.execute_ext_callbacks(        'create_and_show_notification', 'title', target_uis='js_message_box', timeout=3000)")

* invisible in sidebar and enabled by default

* added logo

* adding wallet_alias and docs

* pictures for the docs

* added import

* forgotten change

* pytest fix

* forgotten part 2

* add HOST to config and fix pytest

* examples in settings and wallet menu

* app is not required in callback_after_serverpy_init_app

* better error logging

* fix: better error logging

* fix: include

* Removing Werkzeug Request logs for Cypress

* selectWallet twice to fix weird issues

* explicitly returing None if no user found

* better structuring in server function

* reset lots of flash changes

* add timeout for websocket server connections

* reset helpers.py

* added connection_report

- also changed the registering logic slightly,  to now have an easy overview of the open connections
- also added constants INTERNAL_NOTIFICATION_TITLES

* better default services in user.py

* tiny cleanup

* avoid slow_request_detection_stop

* move css

#1766 (comment)

* typo

#1766 (comment)

* callback_cleanup_on_exit

#1766 (comment)

* move also css colors to service

* upgrade simple_websocket got rid of ssl error on close connection

* fix tests

* better default loading of notifications

* fix bug

see #1766 (comment)

* better callback_cleanup_on_exit

* deleted files

* fix 1 pytest

* removed example code

#1766 (comment)

* cleaned up js logic for the initial connection

* moved  sendRequest

* doc

* doc

* increase ping/timeout interval, because the websocket connection closure works well now

* increase migration count

* renaming

* changed order of notifications cypress test

* disable the websockets during all pytest

* reenable websockets for cypress

* fix bug

* pytest debugging  ONLY. Have to rollback

* Revert "pytest debugging  ONLY. Have to rollback"

This reverts commit ccee38f.

* info output for pytest debugging

* pytest experiment...  Can be rolled back.

* Revert "info output for pytest debugging"

This reverts commit 07f3aaa.

* fix

see #1907 (comment)

* added view_functions comment

* trying to fix flaky cpyress

* fix for hardcoded url

* added auto-reconnection on request failiure

* remove user_secret_decrypted_required

* remove user_secret_decrypted_required

* Removed verbose logging unless logging level < 10

* remove verbose_debug from notification.id

* fix

* fix pytest

* fix non-working migration

* set devstatus_alpha and opt-in

* delete cypress test and remove migration from pytest

* len(classlist) seems to differ in CI and locally

* remove useless code

* done #1766 (comment)

- removed duplicate sendRequest

* moved service_manager_cleanup_on_exit

see #1766 (comment)

* added comment

see #1766 (comment)

* attempt to fix #1766 (comment)

* pytest works. Was a variation in requirements.txt

---------

Co-authored-by: Manolis Mandrapilias <[email protected]>
Co-authored-by: Kim Neunert <[email protected]>
Co-authored-by: moneymanolis <[email protected]>
  • Loading branch information
4 people authored Jan 31, 2023
1 parent 40a6a2e commit 8eef5c7
Show file tree
Hide file tree
Showing 40 changed files with 2,888 additions and 73 deletions.
5 changes: 3 additions & 2 deletions requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ certifi==2022.12.7
chardet==3.0.4
Click==8.1.1
Flask==2.1.1
Werkzeug==2.0.0 # need to pin because Flask doesn't work with newer ones
Werkzeug==2.0.3 # need to pin because Flask doesn't work with newer ones
Flask-Babel==2.0.0
Flask-Cors==3.0.10
Flask-Login==0.5.0
Expand All @@ -25,6 +25,7 @@ mnemonic==0.20
cryptography==3.4.7
Flask-APScheduler==1.12.4
gunicorn==20.1.0
simple-websocket==0.8.1
protobuf==3.20.2
PyJWT==2.4.0
pytimeparse==1.1.8
Expand All @@ -34,4 +35,4 @@ cryptoadvance-liquidissuer==0.2.4
specterext-exfund==0.1.7
specterext-faucet==0.1.2
cryptoadvance.spectrum==0.3.1
specterext-stacktrack==0.2.1
specterext-stacktrack==0.2.1
82 changes: 47 additions & 35 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile
# This file is autogenerated by pip-compile with python 3.10
# To update, run:
#
# pip-compile --generate-hashes requirements.in
Expand All @@ -12,9 +12,9 @@ apscheduler==3.9.1 \
--hash=sha256:65e6574b6395498d371d045f2a8a7e4f7d50c6ad21ef7313d15b1c7cf20df1e3 \
--hash=sha256:ddc25a0ddd899de44d7f451f4375fb971887e65af51e41e5dcf681f59b8b2c9a
# via flask-apscheduler
babel==2.10.3 \
--hash=sha256:7614553711ee97490f732126dc077f8d0ae084ebc6a96e23db1482afabdb2c51 \
--hash=sha256:ff56f4892c1c4bf0d814575ea23471c230d544203c7748e8c68f0089478d48eb
babel==2.11.0 \
--hash=sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe \
--hash=sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6
# via flask-babel
base58==2.1.1 \
--hash=sha256:11a36f4d3ce51dfc1043f3218591ac4eb1ceb172919cebe05b52a5bcc8d245c2 \
Expand Down Expand Up @@ -119,7 +119,7 @@ cryptoadvance-liquidissuer==0.2.4 \
--hash=sha256:5a2c531801854c5a4a46daf184877e22f731cdb42d2cfb840785bda7371ba6fb \
--hash=sha256:9e468f3e35ecc566b3f74a2263677cf26632548abb194521dba15ad37acd1e9b
# via -r requirements.in
cryptoadvance.spectrum==0.3.1 \
cryptoadvance-spectrum==0.3.1 \
--hash=sha256:c0eedce7d88f28a1fbf3a5afbcf3b03f1effdb0983f07445953a1d9fbe789209 \
--hash=sha256:c8eba63d3aec6cc391784e5dde99ec39b13f719a062ef1ce786e5fdf850150d8
# via -r requirements.in
Expand Down Expand Up @@ -153,7 +153,21 @@ embit==0.6.1 \
--hash=sha256:16a84c6668dc9ffc907594457a46f7142cee379646bc009a5a9b77b0d2cb4e12
# via
# -r requirements.in
# cryptoadvance.spectrum
# cryptoadvance-spectrum
flask==2.1.1 \
--hash=sha256:8a4cf32d904cf5621db9f0c9fbcd7efabf3003f22a04e4d0ce790c7137ec5264 \
--hash=sha256:a8c9bd3e558ec99646d177a9739c41df1ded0629480b4c8d2975412f3c9519c8
# via
# -r requirements.in
# cryptoadvance-spectrum
# flask-apscheduler
# flask-babel
# flask-cors
# flask-httpauth
# flask-login
# flask-restful
# flask-sqlalchemy
# flask-wtf
flask-apscheduler==1.12.4 \
--hash=sha256:681dae34dc6cc9403ce674795e53abd0bff540472129cfd3d3c93e0e1d502da8
# via -r requirements.in
Expand All @@ -180,22 +194,8 @@ flask-restful==0.3.9 \
flask-sqlalchemy==2.5.1 \
--hash=sha256:2bda44b43e7cacb15d4e05ff3cc1f8bc97936cc464623424102bfc2c35e95912 \
--hash=sha256:f12c3d4cc5cc7fdcc148b9527ea05671718c3ea45d50c7e732cceb33f574b390
# via cryptoadvance.spectrum
flask==2.1.1 \
--hash=sha256:8a4cf32d904cf5621db9f0c9fbcd7efabf3003f22a04e4d0ce790c7137ec5264 \
--hash=sha256:a8c9bd3e558ec99646d177a9739c41df1ded0629480b4c8d2975412f3c9519c8
# via
# -r requirements.in
# cryptoadvance.spectrum
# flask-apscheduler
# flask-babel
# flask-cors
# flask-httpauth
# flask-login
# flask-restful
# flask-sqlalchemy
# flask-wtf
flask_wtf==0.15.1 \
# via cryptoadvance-spectrum
flask-wtf==0.15.1 \
--hash=sha256:6ff7af73458f182180906a37a783e290bdc8a3817fe4ad17227563137ca285bf \
--hash=sha256:ff177185f891302dc253437fe63081e7a46a4e99aca61dfe086fb23e54fff2dc
# via -r requirements.in
Expand Down Expand Up @@ -271,6 +271,10 @@ gunicorn==20.1.0 \
--hash=sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e \
--hash=sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8
# via -r requirements.in
h11==0.14.0 \
--hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \
--hash=sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761
# via wsproto
hidapi==0.12.0.post2 \
--hash=sha256:00bad74617622b7b7abbb24eae5c11bd91957bb87217d62d8feea15c971a77b5 \
--hash=sha256:0292a29325b905fbfbb39cc368055cda63339fed684eceb7d4d241acc5e60d50 \
Expand Down Expand Up @@ -317,7 +321,7 @@ idna==3.4 \
--hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \
--hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2
# via requests
importlib_metadata==4.8.1 \
importlib-metadata==4.8.1 \
--hash=sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15 \
--hash=sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1
# via -r requirements.in
Expand Down Expand Up @@ -594,7 +598,7 @@ psycopg2-binary==2.9.5 \
--hash=sha256:f95b8aca2703d6a30249f83f4fe6a9abf2e627aa892a5caaab2267d56be7ab69
# via
# -r requirements.in
# cryptoadvance.spectrum
# cryptoadvance-spectrum
pyaes==1.6.1 \
--hash=sha256:02c1b1405c38d3c370b085fb952dd8bea3fadcee6411ad99f312cc129c536d8f
# via hwi
Expand Down Expand Up @@ -637,29 +641,33 @@ pytimeparse==1.1.8 \
--hash=sha256:04b7be6cc8bd9f5647a6325444926c3ac34ee6bc7e69da4367ba282f076036bd \
--hash=sha256:e86136477be924d7e670646a98561957e8ca7308d44841e21f5ddea757556a0a
# via -r requirements.in
pytz-deprecation-shim==0.1.0.post0 \
--hash=sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6 \
--hash=sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d
# via tzlocal
pytz==2022.5 \
--hash=sha256:335ab46900b1465e714b4fda4963d87363264eb662aab5e65da039c25f1f5b22 \
--hash=sha256:c4d88f472f54d615e9cd582a5004d1e5f624854a6a27a6211591c251f22a6914
pytz==2022.7.1 \
--hash=sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0 \
--hash=sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a
# via
# apscheduler
# babel
# flask-babel
# flask-restful
# pandas
pytz-deprecation-shim==0.1.0.post0 \
--hash=sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6 \
--hash=sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d
# via tzlocal
requests==2.26.0 \
--hash=sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24 \
--hash=sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7
# via
# -r requirements.in
# cryptoadvance.spectrum
# cryptoadvance-spectrum
semver==2.13.0 \
--hash=sha256:ced8b23dceb22134307c1b8abfa523da14198793d9787ac838e70e29e77458d4 \
--hash=sha256:fa0fe2722ee1c3f57eac478820c3a5ae2f624af8264cbdf9000c980ff7f75e3f
# via bitbox02
simple-websocket==0.8.1 \
--hash=sha256:0abe874f6a0c6ddd197dbd4f0ce5708b47610a0d14fa2b0762e515659573d44a \
--hash=sha256:bab2f34151d8b9abb1ea6d911e5edc8232fc203b6f814d179db0ba3f93e4e026
# via -r requirements.in
six==1.16.0 \
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
Expand Down Expand Up @@ -751,12 +759,16 @@ urllib3==1.26.12 \
--hash=sha256:3fa96cf423e6987997fc326ae8df396db2a8b7c667747d47ddd8ecba91f4a74e \
--hash=sha256:b930dd878d5a8afb066a637fbb35144fe7901e3b209d1cd4f524bd0e9deee997
# via requests
werkzeug==2.0.0 \
--hash=sha256:3389bbfe6d40c6dd25e6d3f974155163c8b3de5bbda6a89342d4ab93fae80ba0 \
--hash=sha256:64c02f6495ba01eddd6625b3675f357cd358a73f1e38458a56ad86c5baa30b53
werkzeug==2.0.3 \
--hash=sha256:1421ebfc7648a39a5c58c601b154165d05cf47a3cd0ccb70857cbdacf6c8f2b8 \
--hash=sha256:b863f8ff057c522164b6067c9e28b041161b4be5ba4d0daceeaa50a163822d3c
# via
# -r requirements.in
# flask
wsproto==1.2.0 \
--hash=sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065 \
--hash=sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736
# via simple-websocket
wtforms==3.0.1 \
--hash=sha256:6b351bbb12dd58af57ffef05bc78425d08d1914e0fd68ee14143b7ade023c5bc \
--hash=sha256:837f2f0e0ca79481b92884962b914eba4e72b7a2daaf1f939c890ed0124b834b
Expand Down
36 changes: 23 additions & 13 deletions src/cryptoadvance/specter/cli/cli_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,29 @@ def server(
if key:
app.config["KEY"] = key

# the app.config needs to be configured before init_app, such that the service callbacks
# like after_serverpy_init_app have this information available
if host != app.config["HOST"]:
app.config["HOST"] = host

# set up kwargs dict for app.run
kwargs = {
"host": host,
"port": app.config["PORT"],
}
# watch templates folder to reload when something changes
extra_dirs = ["templates"]
extra_files = extra_dirs[:]
for extra_dir in extra_dirs:
for dirname, dirs, files in os.walk(extra_dir):
for filename in files:
filename = os.path.join(dirname, filename)
if os.path.isfile(filename):
extra_files.append(filename)
kwargs["extra_files"] = extra_files

kwargs = configure_ssl(kwargs, app.config, ssl)

app.app_context().push()
init_app(app, hwibridge=hwibridge)

Expand All @@ -140,19 +163,6 @@ def server(

toraddr_file = path.join(app.specter.data_folder, "onion.txt")

# watch templates folder to reload when something changes
extra_dirs = ["templates"]
extra_files = extra_dirs[:]
for extra_dir in extra_dirs:
for dirname, dirs, files in os.walk(extra_dir):
for filename in files:
filename = os.path.join(dirname, filename)
if os.path.isfile(filename):
extra_files.append(filename)

kwargs = {"host": host, "port": app.config["PORT"], "extra_files": extra_files}
kwargs = configure_ssl(kwargs, app.config, ssl)

if hwibridge:
if kwargs.get("ssl_context"):
logger.error(
Expand Down
2 changes: 2 additions & 0 deletions src/cryptoadvance/specter/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class BaseConfig(object):
# The prefix for extensions which don't get access to the session cookie (if SPECTER_URL_PREFIX isn't compromised)
ISOLATED_CLIENT_EXT_URL_PREFIX = "/ext"

HOST = os.getenv("HOST", "127.0.0.1")
PORT = os.getenv("PORT", 25441)
CONNECT_TOR = _get_bool_env_var(os.getenv("CONNECT_TOR", "False"))
SPECTER_DATA_FOLDER = os.path.expanduser(
Expand Down Expand Up @@ -183,6 +184,7 @@ class BaseConfig(object):
"cryptoadvance.specterext.swan.service",
"cryptoadvance.specterext.liquidissuer.service",
"cryptoadvance.specterext.devhelp.service",
"cryptoadvance.specterext.notifications.service",
"cryptoadvance.specterext.exfund.service",
"cryptoadvance.specterext.faucet.service",
"cryptoadvance.specterext.electrum.service",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

from cryptoadvance.specter.util.specter_migrator import SpecterMigration

from ...services.service import Service
from ...services.service import Service, ServiceOptionality
from ...services import callbacks, ExtensionException
from ...util.reflection import (
_get_module_from_class,
Expand Down Expand Up @@ -395,6 +395,16 @@ def delete_services_with_unencrypted_storage(self, user: User):
self.specter.service_unencrypted_storage_manager.delete_all_service_data(user)
logger.debug(f"Deleted unencrypted services")

def add_required_services_to_users(self, users, force_opt_out=False):
"Adds the mandatory and opt_out (only if no services activated for user) services to users"
for service in self.services.values():
for user in users:
if service.optionality == ServiceOptionality.mandatory or (
service.optionality == ServiceOptionality.opt_out
and ((service.id not in user.services) or force_opt_out)
):
user.add_service(service.id)

@classmethod
def get_service_x_dirs(cls, x):
"""returns a list of package-directories which each represents a specific service.
Expand Down
20 changes: 18 additions & 2 deletions src/cryptoadvance/specter/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,13 @@ def init_app(app: SpecterFlask, hwibridge=False, specter=None):
specter=specter, devstatus_threshold=app.config["SERVICES_DEVSTATUS_THRESHOLD"]
)

def service_manager_cleanup_on_exit(signum, frame):
return specter.service_manager.execute_ext_callbacks(
callbacks.cleanup_on_exit, signum, frame
)

specter.call_functions_at_cleanup_on_exit.append(service_manager_cleanup_on_exit)

specter.initialize()

# HWI
Expand Down Expand Up @@ -206,9 +213,17 @@ def login(id, password: str = None):
from cryptoadvance.specter.server_endpoints import controller
from cryptoadvance.specter.services import controller as serviceController

# this number of view_functions needs to be updated by hand when some are added or removed.
number_of_expected_view_functions = 105
if app.config.get("TESTING"):
logger.info(f"We have {len(app.view_functions)} view Functions")
if app.config.get("TESTING") and len(app.view_functions) <= 51:
logger.info(
f"We have {len(app.view_functions)} view Functions. "
f"There should be {number_of_expected_view_functions}."
)
if (
app.config.get("TESTING")
and len(app.view_functions) < number_of_expected_view_functions
):
# Need to force a reload as otherwise the import is skipped
# in pytest, the app is created anew for each test
# But we shouldn't do that if not necessary as this would result in
Expand Down Expand Up @@ -277,6 +292,7 @@ def every5seconds():

scheduler.init_app(app)
scheduler.start()
specter.service_manager.add_required_services_to_users(specter.user_manager.users)
logger.info("----> starting service callback_after_serverpy_init_app ")
specter.service_manager.execute_ext_callbacks(
after_serverpy_init_app, scheduler=scheduler
Expand Down
11 changes: 10 additions & 1 deletion src/cryptoadvance/specter/server_endpoints/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
from flask import flash as flask_flash
from flask import current_app as app
from ..services import callbacks


def flash(*args, **kwargs):
"""An indirection in order to potentially handle a flash differently
This function could be placed in util but as it might
use the service_manager, we place it here for now.
"""
flask_flash(*args, **kwargs)

return_values = app.specter.service_manager.execute_ext_callbacks(
callbacks.flash, *args, **kwargs
)

# if no extension handled the callback
if not return_values:
flask_flash(*args, **kwargs)
1 change: 1 addition & 0 deletions src/cryptoadvance/specter/server_endpoints/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ def register():
plaintext_password=password,
config=config,
)
app.specter.service_manager.add_required_services_to_users([user])

flash(
_(
Expand Down
16 changes: 16 additions & 0 deletions src/cryptoadvance/specter/services/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,19 @@
Will get called right after having access to app.specter
"""
specter_added_to_flask_app = "specter_added_to_flask_app"

"""
Will get called when the server_endpoints.flash is called
"""
flash = "flash"

"""
Callback that is not used yet, but could be implmented in server_endpoints just as flash
"""
create_and_show_notification = "create_and_show_notification"


"""
Callback that is called last in specter.cleanup_on_exit()
"""
cleanup_on_exit = "cleanup_on_exit"
8 changes: 8 additions & 0 deletions src/cryptoadvance/specter/services/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
devstatus_prod = "prod"


class ServiceOptionality:
mandatory = "mandatory" # mandatory is not used yet by any service. Before it can be used it has to be clarified what happens in delete_services_with_encrypted_storage of mandatory services
opt_in = "opt_in"
opt_out = "opt_out"


class Service:
"""A base class for Services"""

Expand All @@ -38,6 +44,8 @@ class Service:
# If the blueprint gets a "/ext" prefix (isolated_client = True), the login cookie won't work for all specter core functionality
isolated_client = True
devstatus = devstatus_alpha
optionality = ServiceOptionality.opt_in
visible_in_sidebar = True
encrypt_data = False

def __init__(self, active, specter):
Expand Down
Loading

0 comments on commit 8eef5c7

Please sign in to comment.