Skip to content

Commit

Permalink
Get demo cpppo.crypto.licensing server running again
Browse files Browse the repository at this point in the history
o make build/install now use python -m build module
o Ship the licensing_test demo configuration files
o Remove recursive logging with a WSGI log handler
o Remove some bench tests from CI that don't work there yet
  • Loading branch information
pjkundert committed Nov 27, 2021
1 parent e171a12 commit 6f1bc21
Show file tree
Hide file tree
Showing 12 changed files with 43 additions and 31 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ jobs:
python -m pip install --upgrade pip
pip install wheel
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
if [ -f requirements-optional.txt ]; then pip install -r requirements-optional.txt; fi
pip install flake8
pip install flake8 pytest pytz tzlocal pymodbus pylogix
pip install 'argparse; python_version < "2.7"'
pip install 'configparser; python_version < "3.0"'
pip install 'ipaddress; python_version < "3.0"'
Expand Down
23 changes: 17 additions & 6 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ PY=python
PY2=python2
PY3=python3

VERSION=$(shell $(PY3) -c 'exec(open("version.py").read()); print( __version__ )')

# PY[23]TEST is the desired method of invoking py.test; either as a command, or
# loading it as module, by directly invoking the target Python interpreter.
#
Expand Down Expand Up @@ -97,17 +99,26 @@ pylint:
cd .. && pylint cpppo --disable=W,C,R


build-check:
@$(PY3) -m build --version \
|| ( echo "\n*** Missing Python modules; run:\n\n $(PY3) -m pip install --upgrade pip setuptools build\n" \
&& false )

build3: build-check clean
$(PY3) -m build
@ls -last dist
build: build3

dist/cpppo-$(VERSION)-py3-none-any.whl: build3

install2:
$(PY2) setup.py install
install3:
$(PY3) setup.py install
install3: dist/cpppo-$(VERSION)-py3-none-any.whl
$(PY3) -m pip install --force-reinstall $^

install23: install2 install3
install: install23
install: install3

build: clean
$(PY3) -m build
@ls -last dist

# Support uploading a new version of cpppo to pypi. Must:
# o advance __version__ number in cpppo/version.py
Expand Down

This file was deleted.

3 changes: 1 addition & 2 deletions crypto/licensing/licensing.sql.authors
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
CREATE TABLE authors (
name char(128) UNIQUE NOT NULL, -- The unique name of the Author
salt char(24) NOT NULL, -- 96-bit salt in hex
seed char(96) NOT NULL, -- 384-bit encrypted seed in hex
ciphertext char(96) NOT NULL, -- 384-bit encrypted seed in hex
PRIMARY KEY (name)
);

File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/*
* Test authors "End User LLC" and "Awesome, Inc." are both encrypted with '[email protected]' : 'password'
*/
Expand Down
33 changes: 16 additions & 17 deletions crypto/licensing/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@
ACCFILE = "licensing.access"

CRDFILE = "licensing.credentials" # Any author credentials available persistently
KEYFILE = "licensing.cpppo-keypair"
LICFILE = "licensing.cpppo-license"
KEYFILE = "licensing.cpppo-keypair*"
LICFILE = "licensing.cpppo-license*"

# SQL configurations are typically found in cpppo/crypto/licensing/, but may be customized and
# placed in any of the Cpppo configuration file paths (eg. ~/.cpppo/, /etc/cpppo/, or the current
Expand Down Expand Up @@ -251,14 +251,12 @@ def emit( *provs ):
try:
# Load most general/distant Licenses first, including the optional extra config dirs
global config_extras
for path, prov in licensing.load( basename=LICFILE, extra=config_extras, reverse=False ):
for path, prov in licensing.load( package=__package__, extra=config_extras, reverse=False ):
for sig, lic in emit( prov ):
yield sig, lic
found += 1
except ConfigNotFoundError:
pass
except Exception as exc:
log.error( "Failed to load {}*: {}".format( path or LICFILE, exc ))
log.error( "Failed to load license from {}: {}".format( path or __package__, exc ))
pass
log.info( "Licenses loaded: {}".format( found ))

Expand All @@ -279,7 +277,7 @@ def credentials( *add ):
credentials.local.update( add )
for name, (username, password) in credentials.local.items():
yield name, (username, password)
log.info( "Credentials saved: {}".format( len( credentials.local )))
log.info( "Credentials cached: {}".format( len( credentials.local )))

found = 0
path = None
Expand All @@ -302,8 +300,6 @@ def credentials( *add ):
log.detail( " {n:<20}: {u:>20} / {p}".format( n=name, u=username, p='*' * len( password )))
yield name, (username, password)
found += 1
except ConfigNotFoundError:
pass
except Exception as exc:
log.error( "Failed to load {}*: {}".format( path or CRDFILE, exc ))
pass
Expand All @@ -325,10 +321,11 @@ def keypairs():
loaded = set()
saved = 0
for credname,(username,password) in credentials():
log.info( "Keypairs for {}'s credential:".format( username ))
for r in db.select( 'authors' ):
cred = dict( username=username, password=password )
try:
keypair = licensing.KeypairEncrypted( salt=r.salt, seed=r.seed )
keypair = licensing.KeypairEncrypted( ciphertext=r.ciphertext, salt=r.salt )
keypair.into_keypair( **cred ) # Ensure the supplied credentials can decrypt it
yield r.name, keypair, cred
saved += 1
Expand All @@ -341,15 +338,17 @@ def keypairs():
# Any Plaintext Keypairs (and perhaps some Encrypted ones, if duplicate credentials are
# supplied) will be found multiple times. Report keypairs at the same path only once. We
# want to load the most general/distant keys first, so reverse=False.
global config_extras
path = None
try:
global config_extras
for path, keypair, cred in licensing.load_keys(
basename=KEYFILE, username=username, password=password,
package=__package__, username=username, password=password,
extra=config_extras, reverse=False ):
if path not in loaded:
yield path, keypair, cred
loaded.add( path )
except ConfigNotFoundError:
except Exception as exc:
log.error( "Failed to load keypair from {}: {}".format( path or __package__, exc ))
pass
log.info( "Keypairs saved: {}".format( saved ))
log.info( "Keypairs loaded: {}".format( len( loaded )))
Expand Down Expand Up @@ -445,6 +444,7 @@ def keypairs_data( path ):
creds = dict( credentials() )
creds_reverse = { v: k for k,v in creds.items() }

log.detail( "Keypairs data w/ {} credential:".format( len( creds_reverse )))
for name,keypair,cred in keypairs():
log.info("Found keypair: {!r}".format( (name,keypair,cred) ))
if pathsegs and pathsegs[0] and not fnmatch.fnmatch( name, pathsegs[0] ):
Expand Down Expand Up @@ -1499,7 +1499,9 @@ def GET( self, path, input_variable="queries" ):
# raised, it should be an appropriate one from the supplied framework to
# carry a meaningful HTTP status code. Otherwise, a generic 500 Server
# Error will be produced.
content, response = self.__class__.__dict__['request'](
request = self.__class__.__dict__['request']
log.detail( "Tabular API call: {!r}".format( request ))
content, response = request(
render=render, path=path, environ=web.ctx.environ,
accept=accept, framework=web, logged=logged,
**{ input_variable: web.input() } )
Expand Down Expand Up @@ -1628,9 +1630,6 @@ def log( self, status, environ ):
environ['REMOTE_ADDR'] = cf_ip
if cf_country:
environ['REMOTE_PORT'] = cf_country
log.isEnabledFor( logging.INFO ) and log.info(
"CF IP: {!r} (was {!r}), Port: {!r} (was {!r}) Environment: {}".format(
cf_ip, ip, cf_country, port, licensing.into_JSON( environ, indent=4, default=str )))
return super( LogMiddlewareCF, self ).log( status, environ )


Expand Down
10 changes: 8 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,15 @@ def walk( path ):
"cpppo/bin": "./bin",
}

# Including data in the package is complex. See: https://sinoroc.gitlab.io/kb/python/package_data.html
# Including data in the package is complex: https://sinoroc.gitlab.io/kb/python/package_data.html
#
# Ship the static data for the cpppo.crypto.licensing server, and some demo test data. From the
# parent of your cpppo source, run:
#
# rm -f licensing.* && python3 -m cpppo.crypto.licensing -vv --config cpppo/crypto/licensing/licensing_test --no-gui
#
package_data = {
'cpppo/crypto/licensing': find_data_files( 'crypto/licensing', 'licensing.sql*', 'static' )
'cpppo/crypto/licensing': find_data_files( 'crypto/licensing', 'licensing.sql*', 'licensing_test', 'static' )
}

import json
Expand Down

0 comments on commit 6f1bc21

Please sign in to comment.