Authorization and OAuth2 provider for LibrisXL.
First, set your app's secret key as an environment variable. For
example, add the following to .bashrc
or .bash_profile
.
export XL_AUTH_SECRET='something-really-secret'
Run the following commands to bootstrap your environment:
git clone https://github.com/libris/xl_auth
cd xl_auth
python3 -m venv venv && source venv/bin/activate
pip install wheel
pip install -r requirements/dev.txt
npm install
export FLASK_APP=$(pwd)/autoapp.py
export FLASK_DEBUG=1
npm run build
flask db upgrade
flask create-user --email [email protected] -p password --is-admin --is-active
npm start # run webpack dev server and flask server using concurrently
You will see a pretty welcome screen.
In general, before running flask shell commands, set the FLASK_APP
and
FLASK_DEBUG
environment variables:
export FLASK_APP=/path/to/autoapp.py
export FLASK_DEBUG=1
Setting FLASK_DEBUG=1 will tell the application to use DevConfig
as
specified in ./xl_auth/settings.py. This configuration sets up a SQLite
db for development and points the SQLALCHEMY_DATABASE_URI environment
variable to this db.
To open the interactive shell, run:
flask shell
By default, you will have access to the flask app
.
To compile Swedish localization support using Babel, run:
flask translate
Note: Might fail with a RuntimeError
if your shell env is set to
use ASCII. Solve it like so:
export LC_ALL=sv_SE.UTF-8
export LANG=sv_SE.UTF-8
To run all tests, run:
flask test
Whenever a database migration needs to be made. Run the following commands:
flask db migrate
This will generate a new migration script. Then run:
flask db upgrade
To apply the migration.
For a full migration command reference, run flask db --help
.
Files placed inside the assets
directory and its subdirectories
(excluding js
and css
) will be copied by webpack's Asset Modules
into the static/build
directory, with hashes of their contents
appended to their names.
For instance, if you have a file assets/img/favicon.ico
, this will get
copied into something like
static/build/img/favicon.fec40b1d14528bf9179da3b6b78079ad.ico
.
You can then put this line into your header:
<link rel="shortcut icon" href="{{ static_url_for('static', 'filename=img/favicon.ico') }}">
to refer to it inside your HTML page. If all of your static files are
managed this way, then their filenames will change whenever their
contents do, and you can ask Flask to tell web browsers that they should
cache all your assets forever by including the following line in your
settings.py
:
SEND_FILE_MAX_AGE_DEFAULT = 31556926 # one year
The latest application build can be built and run using Docker for testing purposes:
docker build -t xl_auth .
docker run -it -p 5000:5000 xl_auth
All Flask command-line tools are accessed by optional input argument to
the container, e.g. flask shell -> docker run -it xl_auth shell
,
flask db -> docker run -it xl_auth db
.
Create a user:
docker exec -it xl_auth /usr/local/bin/flask create-user -e [email protected] -p 1234 --force \
--is-admin --is-active
# Now open localhost:5000 in the browser and login as [email protected]
To import users, collections and permissions into the Docker container, run:
docker exec -it xl_auth /usr/local/bin/flask import-data [email protected]
Technology choices:
libsodium
and Argon2 for hashing?- Early-on Docker integration for easy testing during ahead of first stable release
- Solution implemented as Gunicorn-Flask application, intended to run behind Nginx reverse-proxying in production and utilizing Flask-OAuthlib for OAuth2 support
- Python 3.8+
- Jenkins multi-branch declarative pipeline for CI during development
- The production database of choice is Postgres, using SQLAlchemy PostgreSQL Engine
- Bump various dependencies, notably Gunicorn to 22.0.0
- Bump dependencies to make xl_auth work with newer (3.9+) versions of Python
- Make Dockerfile work again
- Update README; remove outdated things
- Remove old, unused Ansible files
- Remove old, unused docker-compose file
- Convert README from rst to Markdown
- Upgrade to Flask 2.2.x
- Bump various Python and Node.js dependencies
- Include user id in [/verify]{.title-ref} response
Bump dependencies
- CSS fixes
- Bump version number
- Soft-delete users in web interface and using [flask soft-delete-user]{.title-ref}; support changing user email address
- Make locally stored token lifetime explicit
- Adaptions to run with Python 3 and Postgres 13
- Bump dependencies and fix security warnings
- Update/remove links related to GDPR/Libris info and support
- Add 'Global Registrant' permission type
- Clarify copy
- Add support for OAuth2 Backend Application FLow
- Update ToS page
- Add GDPR information
- Allow cataloging admins to create and edit cataloging admin permissions
- Save scope authorization in user session
- Allow CORS requests
- Add support for OAuth2 implicit flow
- Add CLI tool for purging a user from the system (#148)
- Clean up Jenkinsfile
- Replace Docker container runtimes with local installs of xl_auth and Postgres (#178)
- Copy improvements / UX (#176, #173)
- Added support for creating new users directly from register/edit permission views (#140)
- UX enhancements (#142, #133)
- Link to Permissions' overview removed from navbar
- Ignoring/discarding permissions on inactive collections
- Revised API endpoints for registering/editing permissions; now allowing cataloging admins to register new and edit existing permissions on their collections (#126)
- UX enhancements (#129, #134, #131, #130)
- Preserve permissions created by others than [email protected] superuser
- Revised API endpoint for deleting permissions; now allowing cataloging admins to delete permissions on their collections (#123)
- Added "view collection" link to user profile page
- Terms of Service view added, requesting the user to approve (#112)
- Bug fix for loading Voyager permissions on SEK (#113)
- Bug fix for permissions exchange with LibrisXL (#110)
- Secret usability improvements for admin interface
- Under-the-hood traceability updates (#78)
- Added support for resetting forgotten user account passwords (#41)
- When registering new user accounts, opting in for a password reset email is the preferred way of enabling them to login (#102)
- Update internal links to reference users by ID instead of email (#25)
- Refactored OAuth2 (internal) paths
- Reuse existing OAuth2 tokens on refresh
- Fix broken 0.5.5 build
- Bug fix for OAuth2 token handling
- UI fixes for OAuth2 authorization view
- Bug fix for
/oauth/token
API endpoint
- Add collection name to
/oauth/verify
response - Fix broken database migration (#68)
- Add
app_version
property to response from OAuth2 API endpoints - Bug fixes for OAuth2 data model; fully re-created on
flask db upgrade
(#68) - Updated Voyager/SysAdmin data import (#38)
- Update
/oauth/verify
API response format (#68) - Fix bug where collections would read the wrong active/inactive state from bibdb.libris.kb.se
- Minor traceability improvements (#78)
- Data import updates (#44)
- UI adjustments; irrelevant permissions no longer shown to cataloging admins, using term "sigel" instead of "kod"
- Ansible provisioning updated to use Nginx reverse proxy and SSL (#39)
- Personalized user icons (Gravatar, #70)
- Updated
/about/
page with current version number + links (#71) - Only list permissions on active collections on
/users/profile/
page
- Event stricter restrictions on non-admin users (#48)
- Improved Ansible deployment logic for login.libris.kb.se (#39)
- UI and help text improvements
- Added
flask import-data
CLI tool for pulling data from legacy systems (#38, #43) - Styling and usability improvements (#6, #22)
- Applied restrictions on anonymous users and non-admins (#48)
- Added new type of permission, "being the cataloging admin for a collection" (#40)
- Support for dev deployment on login.libris.kb.se (#39)
- Added the concept of users having permissions on zero or more collections (#27)
- Bug fix for uniqueness checks on email addresses and collection codes (#30)
- Added localization for Swedish and set it as the default
BABEL_DEFAULT_LOCALE
(#17) - Added support for editing users (#19)
- Replaced project template with https://github.com/sloria/cookiecutter-flask
- Basic functionality of registering a user by email address and logging in
- A simple form of "collections" can be added and edited
- Dockerfile added for testing purposes (running Flask in debug mode with a ephemeral SQLite db)
- Jenkinsfile (multibranch pipeline) added for testing/linting/building on any code changes
- Establishing initial project requirements, with none of the intended functionality in place