diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..6be64b6b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,390 @@ +# Changelog + +This document describes changes between each past release. + +## 5.1.2 (unreleased) + +### Changed + +- Minor presentation fixes (901) + +## 5.1.1 (2021-10-26) + +- No actual change, fixup release because 5.1.0 did not upload to pypi + +## 5.1.0 (2021-10-26) + +### Added + +- Add the option to display a "legal link" at the bottom of pages (#883) + +### New settings + +- Add [LEGAL_LINK](https://ihatemoney.readthedocs.io/en/latest/configuration.html#legal-link) + setting (#883) + +### Changed + +- Improve performance of balance and statistics computation (#890) +- Reduce the resolution of showcase pictures by 50% (#880) +- Improve pagination style in the list of bills (#873) + +## 5.0.1 (2021-10-20) + +- Include images in the package archives (#872) + +## 5.0.0 (2021-10-19) + +### Breaking changes + +- Include project code into project authentication token. This + invalidates all existing API tokens and invitation links from + previous versions (#802 #843) +- Drop support for Python 2 (#483) +- Drop support for Python 3.5 (#571) +- Drop support for MySQL (#743) +- Require MariaDB version 10.3.2 or above (#632) +- Enable session cookie security by default (#845) +- Change token path authentication to /{project}/join/{token} (#843) + +The minimum supported version is now Python 3.6, and the project is +tested with up to Python 3.9 + +See [upgrade instructions](https://ihatemoney.readthedocs.io/en/latest/upgrade.html) +to make sure the upgrade goes smoothly. + +### Security + +- Add CSRF validation on destructive actions (#796) +- Ask for private code to delete project or project history (#796) +- Add headers to mitigate Clickjacking, XSS, and other attacks: + [X-Frame-Options]{.title-ref}, [X-XSS-Protection]{.title-ref}, + [X-Content-Type-Options]{.title-ref}, + [Content-Security-Policy]{.title-ref}, [Referrer-Policy]{.title-ref} + (#845) +- Add URL validation to external link to prevent XSS (#846) + +### Added + +- Allow to import previously exported json data (#518) +- Add new optional field "external link" in bill form (#429) +- Add optional currencies to project and bills (#541, #864) +- Add new statistics showing monthly expenses (#526) +- Add pagination to the list of bills (#480) +- Add sorting, pagination, and searching to the admin dashboard (#538) +- Add Project History page that records all changes (#553) +- Add token-based authentication to the API (#504) +- Add illustrations as a showcase, currently only for French (#544) +- Add a page for downloading mobile application (#688) +- Add optional support for a simple CAPTCHA (#844) +- Add translations for Greek, Esperanto, Italian, Japanese, Portuguese + and Swedish +- Publish an [official docker + image](https://hub.docker.com/r/ihatemoney/ihatemoney) + +### New settings + +- Add + [ENABLE_CAPTCHA](https://ihatemoney.readthedocs.io/en/latest/configuration.html#enable-captcha) + setting (#844) +- Use and document + [SESSION_COOKIE_SECURE](https://ihatemoney.readthedocs.io/en/latest/configuration.html#session-cookie-secure) + setting (#845) +- Use and document + [BABEL_DEFAULT_TIMEZONE](https://ihatemoney.readthedocs.io/en/latest/configuration.html#babel-default-timezone) + setting (#590) + +### Changed + +- Use the external debts lib to solve settlements (#476) +- Remove balance column in statistics view (#323) +- Make language choice persistent (#547) +- Localize date strings in the current language (#590) +- Differenciate "flash alerts" notifications (#594) +- Display "flash messages" persistently instead of making them + disappear (#856) +- Improve menu bar spacing, put history and settings in a submenu + (#739) +- Change Dockerfile to install python dependencies at build time + (#793) +- Updating project settings doesn\'t require to enter or update + project code (#774) +- Bump dependencies: WTForms (#768) jinja2 (#753) itsdangerous (#756) + flask (#755 #757 #764) +- Remove requirements files in favor of setup.cfg pinning (#558) +- Make language choice persistent (#547) +- Flash messages must be dimissed manually (#856) +- Increased the font size of the logo (#828) + +### Fixed + +- Improve input of email addresses when inviting people to join a + project (#133) +- Fix order of participants in the statistics page (#608) +- Clarify project edition form: private code is not required (#774) +- Fix Python dependency contraints to be less strict +- Improve documentation (#781 #819 #821) +- Fix datepicker that was displayed twice on some browsers (#221) +- Members weight are now rounded to 2 decimal (#838) + +### Documentation + +- Reorganize "Contributing" documentation to be more accessible to + new contributors +- Improve documentation regarding database migrations (#569) +- Added a page about [the security + model](https://ihatemoney.readthedocs.io/en/latest/security.html) + (#858) + +## 4.1.5 (2020-07-26) + +This release fixes a [serious security +issue](https://github.com/spiral-project/ihatemoney/security/advisories/GHSA-67j9-c52g-w2q9). + +All users are encouraged to upgrade. + +### Fixed + +- Fix unauthorized access and modification of project data + (CVE-2020-15120) (#663) + +### Changed + +- Change mobile icon link (#598) +- Improve French translation of email templates (#593) + +### Added + +- Add translations for Portuguese (Brazil), Tamil, Hindi + +## 4.1.4 (2020-06-07) + +This is a bugfix-only release. It is almost certainly the last release +to support Python 2: you should upgrade to Python 3! + +### Fixed + +- Fix failed installation because dependencies were not being pinned + (#540, #545, #558) +- backend: Trim usernames to remove leading or trailing spaces. This + avoids a situation where different names can be visually identical + (#367) +- backend: Fix API to forbid project creation when the + [ALLOW_PUBLIC_PROJECT_CREATION]{.title-ref} setting is set to false + (#496) +- backend: Fix crash when a localized email template is missing (#592) +- backend: Fix language code parsing (#589) +- backend: Improve error handling when sending emails (#595) +- UI: Fix datepicker that was being displayed twice on some browsers + (#221) +- UI: Fix "Submit and add a new one" button that had no effect when + adding a bill (#498) +- UI: Prevent bill cancellation when cancelling autocomplete (#506) +- UI: Fix responsive width of homepage on small screns (#549) +- UI: Fix color of the "Add a member" button (#499) +- UI: Fix missing HTML tag (#583) +- UI: Fix a small typo in the french project-reminder email (#486) +- UI: Fix typo on message displayed when adding a member (#575) +- UI: Fix incorrect tool-tip message about the private code (#623) +- UI : Fix bug on tool-tip message (#635) + +### Added + +- Add translations for German, Spanish (latin-america), Norwegian + (bokmål), Indonesian, Polish, Russian, Chinese, Turkish, Ukrainian +- Update translations for all languages + +## 4.1.3 (2019-09-18) + +### Fixed + +- Fix packaging. Previous (4.1) release wasn\'t pip-installable on all + systems. +- Fix readme and requirements.txt to upload to PyPI. + +### Changed + +- Display password reminder message on a new page rather than on a + flash message (#455, #469) + +## 4.1 (2019-09-08) + +### Added + +- Add a `compress_assets` target in the makefile to compress PNG + (#459) +- Document how to use systemd (#435) +- Add support for python 3.7 +- Add links to documentation, mobile app and git repository in the + footer (#445) +- Use weblate to handle translations +- Add dutch translation +- Add project switcher on login page if already logged (#445) + +### Changed + +- Documentation has been cleaned and reorganised. +- Display a placeholder when no entries are present in the bill list. + (#457) +- Disable the "add bill" action until members are present (#457) +- Improve invitations UX (#451) +- In the bills list, display the "added on" column as a tooltip + (#443) +- Updated bootstrap to latest stable (#440) +- Improved "project already exists" message (#442) +- Improve usability specially for small screen (#441) +- Replace export forms by links (#450) +- Rework homepage design (#445) +- Docker now downloads IHM from PyPI or the reference git repo (#446) +- Arrange navbar items by functions (#445) + +## 4.0 (2019-01-24) + +### Added + +- Add CORS headers in the API (#407) +- Document database migrations (#390) +- Allow basic math operations in amount field (#413) +- Add bill.creation_date field (#327) +- Document PostgreSQL configuration (#415) + +### Fixed + +- Do not allow negative weights on users (#366) +- Fix docker image (#398) +- minor documentation changes + +### Changed + +- Update API project list (#405) + +## 3.0 (2018-11-25) + +### Fixed + +- Fix broken install with pip ≥ 10 (#340) +- Fix the generation of the supervisord template (#309) +- Fix Apache conf template (#359) +- Regenerate translations and improve fr translations (#338) +- Fix the validation of the hashed password (#310) +- Fix infinite loop that happened when accessing / (#358) +- Fix email validation when sending invites +- Fix double-click when deleting a bill (#349) +- Fix error escaping (#388) +- Fix form error on already existing participant (#370) +- Fix documentation for create bills via api (#391) +- Fix docker ADMIN_PASSWORD configuration (#384) +- Fix docker bug where conf is duplicated at each run (#392) +- Fix cffi installation in Dockerfile (#364) + +### Added + +- Document MySQL setup (#357) +- Add a favicon.ico (#381) +- Document external mail server configuration (#278) +- Improve settings documentation styling (#251) +- Add a ihatemoney delete-project command to delete a project (#375) +- Add nice 404 error pages (#379) + +### Changed + +- Enhance translation tooling (#360) +- Improve Makefile (#387) +- Sort members alphabetically in the new bill form. (#374) +- Underline actions links on hover (#377) + +### Removed + +- Remove Sentry, as it\'s not used anymore on prod. (#380) + +## 2.1 (2018-02-16) + +### Changed + +- Use flask-restful instead of deprecated flask-rest for the REST API + (#315) +- Make sidebar scrollable. Usefull for large groups (#316) + +### Fixed + +- Fix the "IOError" crash when running [ihatemoney + generate-config]{.title-ref} (#308) +- Made the left-hand sidebar scrollable (#318) +- Fix and enhanche Docker support (#320, #321) + +### Added + +- Statistics API (#343) +- Allow to disable/enable member via API (#301) +- Enable basic Apache auth passthrough for API (#303) + +## 2.0 (2017-12-27) + +### Breaking changes + +- `ADMIN_PASSWORD` is now stored hashed. The + `ihatemoney generate_password_hash` command can now be used to + generate a proper password HASH (#236) +- Turn the WSGI file into a python module, renamed from + budget/ihatemoney.wsgi to ihatemoney/wsgi.py. Please update your + Apache/Gunicorn configuration! (#218) +- Admin privileges are now required to access the dashboard (#262) +- [password]{.title-ref} field has been removed from project API GET + views (#289) + +### Changed + +- Logged admin can see any project (#262) +- Simpler and safer authentication logic (#270) +- Use token based auth to reset passwords (#269) +- Better install doc (#275) +- Use token based auth in invitation e-mails (#280) +- Use hashed passwords for projects (#286) + +### Added + +- `ihatemoney generate-config` to give working examples of config + files (#275) +- Statistics tab (#257) +- Python3.6 support (#259) +- ALLOW_PUBLIC_PROJECT_CREATION setting (#262) +- Projects can be edited/deleted from the dashboard (#262) +- ACTIVATE_ADMIN_DASHBOARD setting (#262) +- Link to the dashboard in the navigation bar (#262) +- Dockerfile +- Documentation explaining the upgrade process + +### Fixed + +- Fix [PUT api/project/:code/members/:id]{.title-ref} API endpoint + (#295) +- Fix member name uniqueness validation on API (#299) + +### Removed + +- Remove unused option in the setup script + +## 1.0 (2017-06-20) + +### Added + +- Apache WSGI Support (#191) +- Brush up the Makefile (#207, #201) +- Externalize the settings from source folder (#193) +- Makefile: Add new rule to compile translations (#207) +- Project creation can be restricted to admin (#210) +- More responsive layout (#213) + +### Changed + +- Some README enhancements +- Move tests to budget.tests (#205) +- The demo project can be disabled (#209) + +### Fixed + +- Fix sphinx integration (#208) + +## 0.9 (2017-04-04) + +- First release of the project. diff --git a/CHANGELOG.rst b/CHANGELOG.rst deleted file mode 100644 index ceb43ce0..00000000 --- a/CHANGELOG.rst +++ /dev/null @@ -1,409 +0,0 @@ -Changelog -######### - -This document describes changes between each past release. - -5.1.2 (unreleased) -================== - -Changed -------- - -- Minor presentation fixes (901) - - -5.1.1 (2021-10-26) -================== - -- No actual change, fixup release because 5.1.0 did not upload to pypi - - -5.1.0 (2021-10-26) -================== - -Added ------ - -- Add the option to display a "legal link" at the bottom of pages (#883) - -New settings ------------- - -- Add `LEGAL_LINK `_ setting (#883) - -Changed -------- - -- Improve performance of balance and statistics computation (#890) -- Reduce the resolution of showcase pictures by 50% (#880) -- Improve pagination style in the list of bills (#873) - - -5.0.1 (2021-10-20) -================== - -- Include images in the package archives (#872) - - -5.0.0 (2021-10-19) -================== - -Breaking changes ----------------- - -- Include project code into project authentication token. This invalidates all existing API tokens and invitation links from previous versions (#802 #843) -- Drop support for Python 2 (#483) -- Drop support for Python 3.5 (#571) -- Drop support for MySQL (#743) -- Require MariaDB version 10.3.2 or above (#632) -- Enable session cookie security by default (#845) -- Change token path authentication to /{project}/join/{token} (#843) - -The minimum supported version is now Python 3.6, and the project is tested -with up to Python 3.9 - -See `upgrade instructions `_ -to make sure the upgrade goes smoothly. - -Security --------- - -- Add CSRF validation on destructive actions (#796) -- Ask for private code to delete project or project history (#796) -- Add headers to mitigate Clickjacking, XSS, and other attacks: `X-Frame-Options`, `X-XSS-Protection`, `X-Content-Type-Options`, `Content-Security-Policy`, `Referrer-Policy` (#845) -- Add URL validation to external link to prevent XSS (#846) - -Added ------ - -- Allow to import previously exported json data (#518) -- Add new optional field "external link" in bill form (#429) -- Add optional currencies to project and bills (#541, #864) -- Add new statistics showing monthly expenses (#526) -- Add pagination to the list of bills (#480) -- Add sorting, pagination, and searching to the admin dashboard (#538) -- Add Project History page that records all changes (#553) -- Add token-based authentication to the API (#504) -- Add illustrations as a showcase, currently only for French (#544) -- Add a page for downloading mobile application (#688) -- Add optional support for a simple CAPTCHA (#844) -- Add translations for Greek, Esperanto, Italian, Japanese, Portuguese and Swedish -- Publish an `official docker image `_ - -New settings ------------- - -- Add `ENABLE_CAPTCHA `_ setting (#844) -- Use and document `SESSION_COOKIE_SECURE `_ setting (#845) -- Use and document `BABEL_DEFAULT_TIMEZONE `_ setting (#590) - -Changed -------- - -- Use the external debts lib to solve settlements (#476) -- Remove balance column in statistics view (#323) -- Make language choice persistent (#547) -- Localize date strings in the current language (#590) -- Differenciate "flash alerts" notifications (#594) -- Display "flash messages" persistently instead of making them disappear (#856) -- Improve menu bar spacing, put history and settings in a submenu (#739) -- Change Dockerfile to install python dependencies at build time (#793) -- Updating project settings doesn't require to enter or update project code (#774) -- Bump dependencies: WTForms (#768) jinja2 (#753) itsdangerous (#756) flask (#755 #757 #764) -- Remove requirements files in favor of setup.cfg pinning (#558) -- Make language choice persistent (#547) -- Flash messages must be dimissed manually (#856) -- Increased the font size of the logo (#828) - -Fixed ------ - -- Improve input of email addresses when inviting people to join a project (#133) -- Fix order of participants in the statistics page (#608) -- Clarify project edition form: private code is not required (#774) -- Fix Python dependency contraints to be less strict -- Improve documentation (#781 #819 #821) -- Fix datepicker that was displayed twice on some browsers (#221) -- Members weight are now rounded to 2 decimal (#838) - -Documentation -------------- - -- Reorganize "Contributing" documentation to be more accessible to new contributors -- Improve documentation regarding database migrations (#569) -- Added a page about `the security model `_ (#858) - - -4.1.5 (2020-07-26) -================== - -This release fixes a `serious security issue `_. - -All users are encouraged to upgrade. - -Fixed ------ - -- Fix unauthorized access and modification of project data (CVE-2020-15120) (#663) - -Changed -------- - -- Change mobile icon link (#598) -- Improve French translation of email templates (#593) - -Added ------ - -- Add translations for Portuguese (Brazil), Tamil, Hindi - - -4.1.4 (2020-06-07) -================== - -This is a bugfix-only release. It is almost certainly the last release to support Python 2: -you should upgrade to Python 3! - -Fixed ------ - -- Fix failed installation because dependencies were not being pinned (#540, #545, #558) -- backend: Trim usernames to remove leading or trailing spaces. This avoids a situation where different names can be visually identical (#367) -- backend: Fix API to forbid project creation when the `ALLOW_PUBLIC_PROJECT_CREATION` setting is set to false (#496) -- backend: Fix crash when a localized email template is missing (#592) -- backend: Fix language code parsing (#589) -- backend: Improve error handling when sending emails (#595) -- UI: Fix datepicker that was being displayed twice on some browsers (#221) -- UI: Fix "Submit and add a new one" button that had no effect when adding a bill (#498) -- UI: Prevent bill cancellation when cancelling autocomplete (#506) -- UI: Fix responsive width of homepage on small screns (#549) -- UI: Fix color of the "Add a member" button (#499) -- UI: Fix missing HTML tag (#583) -- UI: Fix a small typo in the french project-reminder email (#486) -- UI: Fix typo on message displayed when adding a member (#575) -- UI: Fix incorrect tool-tip message about the private code (#623) -- UI : Fix bug on tool-tip message (#635) - -Added ------ - -- Add translations for German, Spanish (latin-america), Norwegian (bokmål), Indonesian, Polish, Russian, Chinese, Turkish, Ukrainian -- Update translations for all languages - -4.1.3 (2019-09-18) -================== - -Fixed ------ - -- Fix packaging. Previous (4.1) release wasn't pip-installable on all systems. -- Fix readme and requirements.txt to upload to PyPI. - -Changed -------- - -- Display password reminder message on a new page rather than on a flash message (#455, #469) - -4.1 (2019-09-08) -================ - -Added ------ - -- Add a ``compress_assets`` target in the makefile to compress PNG (#459) -- Document how to use systemd (#435) -- Add support for python 3.7 -- Add links to documentation, mobile app and git repository in the - footer (#445) -- Use weblate to handle translations -- Add dutch translation -- Add project switcher on login page if already logged (#445) - -Changed -------- - -- Documentation has been cleaned and reorganised. -- Display a placeholder when no entries are present in the bill - list. (#457) -- Disable the "add bill" action until members are present (#457) -- Improve invitations UX (#451) -- In the bills list, display the "added on" column as a tooltip (#443) -- Updated bootstrap to latest stable (#440) -- Improved "project already exists" message (#442) -- Improve usability specially for small screen (#441) -- Replace export forms by links (#450) -- Rework homepage design (#445) -- Docker now downloads IHM from PyPI or the reference git repo (#446) -- Arrange navbar items by functions (#445) - - -4.0 (2019-01-24) -================ - -Added ------ - -- Add CORS headers in the API (#407) -- Document database migrations (#390) -- Allow basic math operations in amount field (#413) -- Add bill.creation_date field (#327) -- Document PostgreSQL configuration (#415) - -Fixed ------ - -- Do not allow negative weights on users (#366) -- Fix docker image (#398) -- minor documentation changes - -Changed -------- - -- Update API project list (#405) - - -3.0 (2018-11-25) -================ - -Fixed ------ - -- Fix broken install with pip ≥ 10 (#340) -- Fix the generation of the supervisord template (#309) -- Fix Apache conf template (#359) - -- Regenerate translations and improve fr translations (#338) -- Fix the validation of the hashed password (#310) -- Fix infinite loop that happened when accessing / (#358) -- Fix email validation when sending invites -- Fix double-click when deleting a bill (#349) -- Fix error escaping (#388) -- Fix form error on already existing participant (#370) -- Fix documentation for create bills via api (#391) - -- Fix docker ADMIN_PASSWORD configuration (#384) -- Fix docker bug where conf is duplicated at each run (#392) -- Fix cffi installation in Dockerfile (#364) - -Added ------ - -- Document MySQL setup (#357) -- Add a favicon.ico (#381) -- Document external mail server configuration (#278) -- Improve settings documentation styling (#251) -- Add a ihatemoney delete-project command to delete a project (#375) -- Add nice 404 error pages (#379) - -Changed -------- - -- Enhance translation tooling (#360) -- Improve Makefile (#387) -- Sort members alphabetically in the new bill form. (#374) -- Underline actions links on hover (#377) - -Removed -------- - -- Remove Sentry, as it's not used anymore on prod. (#380) - - -2.1 (2018-02-16) -================ - -Changed -------- - -- Use flask-restful instead of deprecated flask-rest for the REST API (#315) -- Make sidebar scrollable. Usefull for large groups (#316) - -Fixed ------ - -- Fix the "IOError" crash when running `ihatemoney generate-config` (#308) -- Made the left-hand sidebar scrollable (#318) -- Fix and enhanche Docker support (#320, #321) - -Added ------ - -- Statistics API (#343) -- Allow to disable/enable member via API (#301) -- Enable basic Apache auth passthrough for API (#303) - - -2.0 (2017-12-27) -================ - -Breaking changes ----------------- - -- ``ADMIN_PASSWORD`` is now stored hashed. The ``ihatemoney generate_password_hash`` command can now be used to generate a proper password HASH (#236) -- Turn the WSGI file into a python module, renamed from budget/ihatemoney.wsgi to ihatemoney/wsgi.py. Please update your Apache/Gunicorn configuration! (#218) -- Admin privileges are now required to access the dashboard (#262) -- `password` field has been removed from project API GET views (#289) - -Changed -------- - -- Logged admin can see any project (#262) -- Simpler and safer authentication logic (#270) -- Use token based auth to reset passwords (#269) -- Better install doc (#275) -- Use token based auth in invitation e-mails (#280) -- Use hashed passwords for projects (#286) - -Added ------ - -- ``ihatemoney generate-config`` to give working examples of config files (#275) -- Statistics tab (#257) -- Python3.6 support (#259) -- ALLOW_PUBLIC_PROJECT_CREATION setting (#262) -- Projects can be edited/deleted from the dashboard (#262) -- ACTIVATE_ADMIN_DASHBOARD setting (#262) -- Link to the dashboard in the navigation bar (#262) -- Dockerfile -- Documentation explaining the upgrade process - -Fixed ------ - -- Fix `PUT api/project/:code/members/:id` API endpoint (#295) -- Fix member name uniqueness validation on API (#299) - -Removed -------- - -- Remove unused option in the setup script - -1.0 (2017-06-20) -================ - -Added ------ - -- Apache WSGI Support (#191) -- Brush up the Makefile (#207, #201) -- Externalize the settings from source folder (#193) -- Makefile: Add new rule to compile translations (#207) -- Project creation can be restricted to admin (#210) -- More responsive layout (#213) - -Changed -------- - -- Some README enhancements -- Move tests to budget.tests (#205) -- The demo project can be disabled (#209) - -Fixed ------ - -- Fix sphinx integration (#208) - -0.9 (2017-04-04) -================ - -- First release of the project. diff --git a/Makefile b/Makefile index e6941975..17676cc0 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,6 @@ SPHINX_BUILDDIR = docs/_build VENV := $(shell realpath $${VIRTUAL_ENV-.venv}) PYTHON = $(VENV)/bin/python3 DEV_STAMP = $(VENV)/.dev_env_installed.stamp -DOC_STAMP = $(VENV)/.doc_env_installed.stamp INSTALL_STAMP = $(VENV)/.install.stamp TEMPDIR := $(shell mktemp -d) ZOPFLIPNG := zopflipng diff --git a/README.md b/README.md new file mode 100644 index 00000000..6e597b5a --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +# I hate money + +[![GitHub Actions Status](https://github.com/spiral-project/ihatemoney/actions/workflows/test-docs.yml/badge.svg)](https://github.com/spiral-project/ihatemoney/actions/workflows/test-docs.yml) + +[![Translation status from Weblate](https://hosted.weblate.org/widgets/i-hate-money/-/i-hate-money/svg-badge.svg)](https://hosted.weblate.org/engage/i-hate-money/?utm_source=widget) + +[![Donate](https://img.shields.io/liberapay/receives/IHateMoney.svg?logo=liberapay)](https://liberapay.com/IHateMoney/donate) + +[![Docker image](https://img.shields.io/badge/-Docker%20image-black?logo=docker)](https://hub.docker.com/r/ihatemoney/ihatemoney/general) + +*I hate money* is a web application made to ease shared budget +management. It keeps track of who bought what, when, and for whom; and +helps to settle the bills. + +- [Online documentation](https://ihatemoney.readthedocs.io) +- [Hosted version](https://ihatemoney.org) +- [Mailing + list](https://mailman.alwaysdata.com/postorius/lists/info.ihatemoney.org/) + (to get updates when needed). + +The code is distributed under a BSD *beerware* derivative: if you meet +the people in person and you want to pay them a craft beer, you are +highly encouraged to do so. + +## Requirements + +- **Python**: version 3.6 to 3.9. +- **Backends**: SQLite, PostgreSQL, MariaDB (version 10.3.2 or above), + Memory. + +## Contributing + +Do you wish to contribute to IHateMoney? Fantastic! There's a lot of +very useful help on the official +[contributing](https://ihatemoney.readthedocs.io/en/latest/contributing.html) +page. + +You can also [donate some +money](https://liberapay.com/IHateMoney/donate). All funds will be used +to maintain the [hosted version](https://ihatemoney.org). + +## Translation status + +[![Translation status for each language](https://hosted.weblate.org/widgets/i-hate-money/-/i-hate-money/multi-blue.svg)](https://hosted.weblate.org/engage/i-hate-money/?utm_source=widget) diff --git a/README.rst b/README.rst deleted file mode 100644 index e1c63a01..00000000 --- a/README.rst +++ /dev/null @@ -1,54 +0,0 @@ -I hate money -############ - -.. image:: https://github.com/spiral-project/ihatemoney/actions/workflows/test-docs.yml/badge.svg - :target: https://github.com/spiral-project/ihatemoney/actions/workflows/test-docs.yml - :alt: GitHub Actions Status - -.. image:: https://hosted.weblate.org/widgets/i-hate-money/-/i-hate-money/svg-badge.svg - :target: https://hosted.weblate.org/engage/i-hate-money/?utm_source=widget - :alt: Translation status from Weblate - -.. image:: https://img.shields.io/liberapay/receives/IHateMoney.svg?logo=liberapay - :target: https://liberapay.com/IHateMoney/donate - :alt: Donate - -.. image:: https://img.shields.io/badge/-Docker%20image-black?logo=docker - :target: https://hub.docker.com/r/ihatemoney/ihatemoney/general - :alt: Docker image - - -*I hate money* is a web application made to ease shared budget management. -It keeps track of who bought what, when, and for whom; and helps to settle the -bills. - -* `Online documentation `_ -* `Hosted version `_ -* `Mailing list `_ - (to get updates when needed). - -The code is distributed under a BSD *beerware* derivative: if you meet the -people in person and you want to pay them a craft beer, you are highly -encouraged to do so. - -Requirements -============ - -* **Python**: version 3.6 to 3.9. -* **Backends**: SQLite, PostgreSQL, MariaDB (version 10.3.2 or above), Memory. - -Contributing -============ - -Do you wish to contribute to IHateMoney? Fantastic! There's a lot of very -useful help on the official `contributing -`_ page. - -You can also `donate some money `_. All funds will be used to maintain the `hosted version `_. - -Translation status -================== - -.. image:: https://hosted.weblate.org/widgets/i-hate-money/-/i-hate-money/multi-blue.svg - :target: https://hosted.weblate.org/engage/i-hate-money/?utm_source=widget - :alt: Translation status for each language diff --git a/docs/api.rst b/docs/api.md similarity index 56% rename from docs/api.rst rename to docs/api.md index 982f828f..a4b91948 100644 --- a/docs/api.rst +++ b/docs/api.md @@ -1,83 +1,83 @@ -The REST API -############ +# The REST API -All of what's possible to do with the website is also possible via a web API. -This document explains how the API is organized and how you can query it. +All of what's possible to do with the website is also possible via a +web API. This document explains how the API is organized and how you can +query it. The main supported data format is JSON. When using POST or PUT, you can -either pass data encoded in JSON or in ``application/x-www-form-urlencoded`` +either pass data encoded in JSON or in `application/x-www-form-urlencoded` format. -Overall organisation -==================== +## Overall organisation -You can access three different things: projects, members and bills. You can -also get the balance for a project. +You can access three different things: projects, members and bills. You +can also get the balance for a project. -The examples here are using curl, feel free to use whatever you want to do the -same thing, curl is not a requirement. +The examples here are using curl, feel free to use whatever you want to +do the same thing, curl is not a requirement. -Authentication --------------- +### Authentication -To interact with bills and members, and for any action other than creating a new -project, you need to be authenticated. The simplest way to authenticate is to use -"basic" HTTP authentication with the project ID and private code. +To interact with bills and members, and for any action other than +creating a new project, you need to be authenticated. The simplest way +to authenticate is to use "basic" HTTP authentication with the project +ID and private code. -For instance, to obtain information about a project, using curl:: +For instance, to obtain information about a project, using curl: $ curl --basic -u demo:demo https://ihatemoney.org/api/projects/demo -It is also possible to generate a token, and then use it later to authenticate -instead of basic auth. -For instance, start by generating the token (of course, you need to authenticate):: +It is also possible to generate a token, and then use it later to +authenticate instead of basic auth. For instance, start by generating +the token (of course, you need to authenticate): $ curl --basic -u demo:demo https://ihatemoney.org/api/projects/demo/token {"token": "WyJ0ZXN0Il0.Rt04fNMmxp9YslCRq8hB6jE9s1Q"} -Make sure to store this token securely: it allows full access to the project. -For instance, use it to obtain information about the project (replace PROJECT_TOKEN with -the actual token):: +Make sure to store this token securely: it allows full access to the +project. For instance, use it to obtain information about the project +(replace PROJECT_TOKEN with the actual token): $ curl --oauth2-bearer "PROJECT_TOKEN" https://ihatemoney.org/api/projects/demo -This works by sending the token in the Authorization header, so doing it "manually" with curl -looks like:: +This works by sending the token in the Authorization header, so doing it +"manually" with curl looks like: $ curl --header "Authorization: Bearer PROJECT_TOKEN" https://ihatemoney.org/api/projects/demo -This token can also be used to authenticate for a project on the web interface, which can be useful -to generate invitation links. You would simply create an URL of the form:: +This token can also be used to authenticate for a project on the web +interface, which can be useful to generate invitation links. You would +simply create an URL of the form: https://ihatemoney.org/demo/join/PROJECT_TOKEN Such a link grants full access to the project associated with the token. -Projects --------- +### Projects -You can't list projects, for security reasons. But you can create, update and -delete one directly from the API. +You can't list projects, for security reasons. But you can create, +update and delete one directly from the API. -The URLs are ``/api/projects`` and ``/api/projects/``. +The URLs are `/api/projects` and `/api/projects/`. -Creating a project -~~~~~~~~~~~~~~~~~~ +#### Creating a project A project needs the following arguments: -* ``name``: the project name (string) -* ``id``: the project identifier (string without special chars or spaces) -* ``password``: the project password / secret code (string) -* ``contact_email``: the contact email (string) +- `name`: the project name (string) +- `id`: the project identifier (string without special chars or + spaces) +- `password`: the project password / secret code (string) +- `contact_email`: the contact email (string) Optional arguments: -* ``default_currency``: the default currency to use for a multi-currency project, - in ISO 4217 format. Bills are converted to this currency for operations like balance - or statistics. Default value: ``XXX`` (no currency). +- `default_currency`: the default currency to use for a multi-currency + project, in ISO 4217 format. Bills are converted to this currency + for operations like balance or statistics. Default value: `XXX` (no + currency). -:: +Here is the command: $ curl -X POST https://ihatemoney.org/api/projects \ -d 'name=yay&id=yay&password=yay&contact_email=yay@notmyidea.org' @@ -85,11 +85,9 @@ Optional arguments: As you can see, the API returns the identifier of the project. -Getting information about the project -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Getting information about the project:: +#### Getting information about the project +Getting information about the project: $ curl --basic -u demo:demo https://ihatemoney.org/api/projects/demo { @@ -97,34 +95,31 @@ Getting information about the project:: "name": "demonstration", "contact_email": "demo@notmyidea.org", "default_currency": "XXX", - "members": [{"id": 11515, "name": "f", "weight": 1.0, "activated": true, "balance": 0}, - {"id": 11531, "name": "g", "weight": 1.0, "activated": true, "balance": 0}, + "members": [{"id": 11515, "name": "f", "weight": 1.0, "activated": true, "balance": 0}, + {"id": 11531, "name": "g", "weight": 1.0, "activated": true, "balance": 0}, {"id": 11532, "name": "peter", "weight": 1.0, "activated": true, "balance": 5.0}, - {"id": 11558, "name": "Monkey", "weight": 1.0, "activated": true, "balance": 0}, + {"id": 11558, "name": "Monkey", "weight": 1.0, "activated": true, "balance": 0}, {"id": 11559, "name": "GG", "weight": 1.0, "activated": true, "balance": -5.0}] } +#### Updating a project -Updating a project -~~~~~~~~~~~~~~~~~~ - -Updating a project is done with the ``PUT`` verb:: +Updating a project is done with the `PUT` verb: $ curl --basic -u yay:yay -X PUT\ https://ihatemoney.org/api/projects/yay -d\ 'name=yay&id=yay&password=yay&contact_email=youpi@notmyidea.org' -Deleting a project -~~~~~~~~~~~~~~~~~~ +#### Deleting a project -Just send a DELETE request ont the project URI :: +Just send a DELETE request ont the project URI : $ curl --basic -u demo:demo -X DELETE https://ihatemoney.org/api/projects/demo -Members -------- +### Members -You can get all the members with a ``GET`` on ``/api/projects//members``:: +You can get all the members with a `GET` on +`/api/projects//members`: $ curl --basic -u demo:demo https://ihatemoney.org/api/projects/demo/members\ [{"weight": 1, "activated": true, "id": 31, "name": "Arnaud"}, @@ -132,35 +127,34 @@ You can get all the members with a ``GET`` on ``/api/projects//members``:: {"weight": 1, "activated": true, "id": 33, "name": "Olivier"}, {"weight": 1, "activated": true, "id": 34, "name": "Fred"}] -Add a member with a ``POST`` request on ``/api/projects//members``:: +Add a member with a `POST` request on `/api/projects//members`: $ curl --basic -u demo:demo -X POST\ https://ihatemoney.org/api/projects/demo/members -d 'name=tatayoyo' 35 -You can also ``PUT`` a new version of a member (changing its name):: +You can also `PUT` a new version of a member (changing its name): $ curl --basic -u demo:demo -X PUT\ https://ihatemoney.org/api/projects/demo/members/36\ -d 'name=yeaaaaah' {"activated": true, "id": 36, "name": "yeaaaaah", "weight": 1} -Delete a member with a ``DELETE`` request on -``/api/projects//members/``:: +Delete a member with a `DELETE` request on +`/api/projects//members/`: $ curl --basic -u demo:demo -X DELETE\ https://ihatemoney.org/api/projects/demo/members/35 "OK -Bills ------ +### Bills -You can get the list of bills by doing a ``GET`` on -``/api/projects//bills`` :: +You can get the list of bills by doing a `GET` on +`/api/projects//bills` : $ curl --basic -u demo:demo https://ihatemoney.org/api/projects/demo/bills -Or get a specific bill by ID:: +Or get a specific bill by ID: $ curl --basic -u demo:demo https://ihatemoney.org/api/projects/demo/bills/42 { @@ -183,55 +177,55 @@ Or get a specific bill by ID:: "converted_amount": 100 } -``amount`` is expressed in the ``original_currency`` of the bill, while -``converted_amount`` is expressed in the project ``default_currency``. -Here, they are the same. +`amount` is expressed in the `original_currency` of the bill, while +`converted_amount` is expressed in the project `default_currency`. Here, +they are the same. -Add a bill with a ``POST`` query on ``/api/projects//bills``. You need the -following required parameters: +Add a bill with a `POST` query on `/api/projects//bills`. You need +the following required parameters: -* ``what``: what has been paid (string) -* ``payer``: paid by who? (id) -* ``payed_for``: for who ? (id). To set multiple id, simply pass - the parameter multiple times (x-www-form-urlencoded) or pass a list of id (JSON). -* ``amount``: amount payed (float) +- `what`: what has been paid (string) +- `payer`: paid by who? (id) +- `payed_for`: for who ? (id). To set multiple id, simply pass the + parameter multiple times (x-www-form-urlencoded) or pass a list of + id (JSON). +- `amount`: amount payed (float) And optional parameters: -* ``date``: the date of the bill (``yyyy-mm-dd`` format). Defaults to current date - if not provided. -* ``original_currency``: the currency in which ``amount`` has been paid (ISO 4217 code). - Only makes sense for a project with currencies. Defaults to the project ``default_currency``. -* ``external_link``: an optional URL associated with the bill. +- `date`: the date of the bill (`yyyy-mm-dd` format). Defaults to + current date if not provided. +- `original_currency`: the currency in which `amount` has been paid + (ISO 4217 code). Only makes sense for a project with currencies. + Defaults to the project `default_currency`. +- `external_link`: an optional URL associated with the bill. -Returns the id of the created bill :: +Returns the id of the created bill : $ curl --basic -u demo:demo -X POST\ https://ihatemoney.org/api/projects/demo/bills\ -d "date=2011-09-10&what=raclette&payer=1&payed_for=3&payed_for=5&amount=200" 80 -You can also ``PUT`` a new version of the bill at -``/api/projects//bills/``:: +You can also `PUT` a new version of the bill at +`/api/projects//bills/`: $ curl --basic -u demo:demo -X PUT\ https://ihatemoney.org/api/projects/demo/bills/80\ -d "date=2011-09-10&what=raclette&payer=1&payed_for=3&payed_for=5&payed_for=1&amount=250" 80 -And you can of course ``DELETE`` them at -``/api/projects//bills/``:: +And you can of course `DELETE` them at +`/api/projects//bills/`: $ curl --basic -u demo:demo -X DELETE\ https://ihatemoney.org/api/projects/demo/bills/80\ "OK" +### Statistics -Statistics ----------- - -You can get some project stats with a ``GET`` on -``/api/projects//statistics``:: +You can get some project stats with a `GET` on +`/api/projects//statistics`: $ curl --basic -u demo:demo https://ihatemoney.org/api/projects/demo/statistics [ diff --git a/docs/conf.py b/docs/conf.py index 8f94cf70..95fa716c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,3 +9,9 @@ version = "5.0" release = "5.0" exclude_patterns = ["_build"] pygments_style = "sphinx" +extensions = ["myst_parser", "sphinx.ext.autosectionlabel"] + +myst_enable_extensions = [ + "colon_fence", +] +autosectionlabel_prefix_document = True diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 00000000..71ae2291 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,181 @@ +(configuration)= +# Configuration + +"ihatemoney" relies on a configuration file. If you run the +application for the first time, you will need to take a few moments to +configure the application properly. + +The default values given here are those for the development mode. To +know defaults on your deployed instance, simply look at your +`ihatemoney.cfg` file. + +"Production values" are the recommended values for use in production. + +## Configuration files + +By default, Ihatemoney loads its configuration from `/etc/ihatemoney/ihatemoney.cfg`. + +If you need to load the configuration from a custom path, you can define +the `IHATEMONEY_SETTINGS_FILE_PATH` environment variable with the path +to the configuration file. For instance : + + export IHATEMONEY_SETTINGS_FILE_PATH="/path/to/your/conf/file.cfg" + +The path should be absolute. A relative path will be interpreted as +being inside `/etc/ihatemoney/`. + +## SQLALCHEMY_DATABASE_URI + +Specifies the type of backend to use and its location. More information +on the format used can be found on [the SQLAlchemy +documentation](http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls). + +- **Default value:** `sqlite:///tmp/ihatemoney.db` +- **Production value:** Set it to some path on your disk. Typically + `sqlite:///home/ihatemoney/ihatemoney.db`. Do *not* store it under + `/tmp` as this folder is cleared at each boot. + +For example, if you're using MariaDB, use a configuration similar to +the following: + + SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://user:pass@localhost/mydb' + +If you're using PostgreSQL, your client must use utf8. Unfortunately, +PostgreSQL default is to use ASCII. Either change your client settings, +or specify the encoding by appending `?client_encoding=utf8` to the +connection string. This will look like: + + SQLALCHEMY_DATABASE_URI = 'postgresql://myuser:mypass@localhost/mydb?client_encoding=utf8' + +## SECRET_KEY + +The secret key used to encrypt cookies and generate secure tokens. They +are used to authenticate access to projects, both through the web +interface and through the API. + +As such, you should never use a predictible secret key: an attacker with +the knowledge of the secret key could easily access any project and +bypass the private code verification. + +- **Production value:** `ihatemoney conf-example ihatemoney.cfg` + sets it to something random, which should be good. + +## SESSION_COOKIE_SECURE + +A boolean that controls whether the session cookie will be marked +"secure". If this is the case, browsers will refuse to send the +session cookie over plain HTTP. + +- **Default value:** `True` +- **Production value:** `True` if you run your service over HTTPS, + `False` if you run your service over plain HTTP. + +Note: this setting is actually interpreted by Flask, see the [Flask +documentation](https://flask.palletsprojects.com/en/2.0.x/config/#SESSION_COOKIE_SECURE) +for details. + +## MAIL_DEFAULT_SENDER + +A python tuple describing the name and email address to use when sending +emails. + +- **Default value:** `("Budget manager", "budget@notmyidea.org")` +- **Production value:** Any tuple you want. + +## ACTIVATE_DEMO_PROJECT + +If set to `True`, a demo project will be available on the frontpage. + +- **Default value:** `True` +- **Production value:** Usually, you will want to set it to `False` + for a private instance. + +## ADMIN_PASSWORD + +Hashed password to access protected endpoints. If left empty, all +administrative tasks are disabled. + +- **Default value:** `""` (empty string) +- **Production value:** To generate the proper password HASH, use + `ihatemoney generate_password_hash` and copy the output into the + value of *ADMIN_PASSWORD*. + +## ALLOW_PUBLIC_PROJECT_CREATION + +If set to `True`, everyone can create a project without entering the +admin password. If set to `False`, the password needs to be entered (and +as such, defined in the settings). + +- **Default value:** `True`. + +## ACTIVATE_ADMIN_DASHBOARD + +If set to `True`, the dashboard will become accessible +entering the admin password, if set to `True`, a non empty +ADMIN_PASSWORD needs to be set. + +- **Default value**: `False` + +## APPLICATION_ROOT + +If empty, ihatemoney will be served at domain root (e.g: +*http://domain.tld*), if set to `"somestring"`, it will be served from a +"folder" (e.g: *http://domain.tld/somestring*). + +- **Default value:** `""` (empty string) + +## BABEL_DEFAULT_TIMEZONE + +The timezone that will be used to convert date and time when displaying +them to the user (all times are always stored in UTC internally). If not +set, it will default to the timezone configured on the Operating System +of the server running ihatemoney, which may or may not be what you want. + +- **Default value:** *unset* (use the timezone of the server Operating + System) +- **Production value:** Set to the timezone of your expected users, + with a format such as `"Europe/Paris"`. See [this list of TZ + database names](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List) + for a complete list. + +Note: this setting is actually interpreted by Flask-Babel, see the +[Flask-Babel guide for formatting +dates](https://pythonhosted.org/Flask-Babel/#formatting-dates) for +details. + +## ENABLE_CAPTCHA + +It is possible to add a simple captcha in order to filter out spammer +bots on the form creation. In order to do so, you just have to set +`ENABLE_CAPTCHA = True`. + +- **Default value:** `False` +- **Production value:** `True` is recommended to get spam-robots away. + + +## LEGAL_LINK + +You may want to point to a special legal page, for instance to give +information about GDPR, or how you handle the data of your users. + +If you want to do this, you can use the `LEGAL_LINK` setting. Set it to the +URL you want. + +- **Default value:** `""` (empty string) +- **Production value:** The URL of your chosing. + +## Configuring email sending + +By default, Ihatemoney sends emails using a local SMTP server, but it's +possible to configure it to act differently, thanks to the great +[Flask-Mail +project](https://pythonhosted.org/flask-mail/#configuring-flask-mail) + +- **MAIL_SERVER** : default **'localhost'** +- **MAIL_PORT** : default **25** +- **MAIL_USE_TLS** : default **False** +- **MAIL_USE_SSL** : default **False** +- **MAIL_DEBUG** : default **app.debug** +- **MAIL_USERNAME** : default **None** +- **MAIL_PASSWORD** : default **None** +- **DEFAULT_MAIL_SENDER** : default **None** diff --git a/docs/configuration.rst b/docs/configuration.rst deleted file mode 100644 index 5106282a..00000000 --- a/docs/configuration.rst +++ /dev/null @@ -1,187 +0,0 @@ -.. _configuration: - -Configuration -============= - -"ihatemoney" relies on a configuration file. If you run the application for the -first time, you will need to take a few moments to configure the application -properly. - -The default values given here are those for the development mode. -To know defaults on your deployed instance, simply look at your -``ihatemoney.cfg`` file. - -"Production values" are the recommended values for use in production. - -Configuration files -------------------- - -By default, Ihatemoney loads its configuration from ``/etc/ihatemoney/ihatemoney.cfg``. - -If you need to load the configuration from a custom path, you can define the -``IHATEMONEY_SETTINGS_FILE_PATH`` environment variable with the path to the configuration -file. -For instance :: - - export IHATEMONEY_SETTINGS_FILE_PATH="/path/to/your/conf/file.cfg" - -The path should be absolute. A relative path will be interpreted as being -inside ``/etc/ihatemoney/``. - -`SQLALCHEMY_DATABASE_URI` -------------------------- - -Specifies the type of backend to use and its location. More information on the -format used can be found on `the SQLAlchemy documentation`_. - -- **Default value:** ``sqlite:///tmp/ihatemoney.db`` -- **Production value:** Set it to some path on your disk. Typically - ``sqlite:///home/ihatemoney/ihatemoney.db``. Do *not* store it under - ``/tmp`` as this folder is cleared at each boot. - -For example, if you're using MariaDB, use a configuration similar to the following:: - - SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://user:pass@localhost/mydb' - -If you're using PostgreSQL, your client must use utf8. Unfortunately, -PostgreSQL default is to use ASCII. Either change your client settings, -or specify the encoding by appending ``?client_encoding=utf8`` to the -connection string. This will look like:: - - SQLALCHEMY_DATABASE_URI = 'postgresql://myuser:mypass@localhost/mydb?client_encoding=utf8' - -.. _the SQLAlchemy documentation: http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls - -`SECRET_KEY` ------------- - -The secret key used to encrypt cookies and generate secure tokens. They are used -to authenticate access to projects, both through the web interface and through the API. - -As such, you should never use a predictible secret key: an attacker with the knowledge -of the secret key could easily access any project and bypass the private code verification. - -- **Production value:** `ihatemoney conf-example ihatemoney.cfg` sets it to - something random, which is good. - -`SESSION_COOKIE_SECURE` ------------------------ - -A boolean that controls whether the session cookie will be marked "secure". -If this is the case, browsers will refuse to send the session cookie over plain HTTP. - -- **Default value:** ``True`` -- **Production value:** ``True`` if you run your service over HTTPS, ``False`` if you run - your service over plain HTTP. - -Note: this setting is actually interpreted by Flask, see the -`Flask documentation`_ for details. - -.. _Flask documentation: https://flask.palletsprojects.com/en/2.0.x/config/#SESSION_COOKIE_SECURE - -`MAIL_DEFAULT_SENDER` ---------------------- - -A python tuple describing the name and email address to use when sending -emails. - -- **Default value:** ``("Budget manager", "budget@notmyidea.org")`` -- **Production value:** Any tuple you want. - -`ACTIVATE_DEMO_PROJECT` ------------------------ - -If set to `True`, a demo project will be available on the frontpage. - -- **Default value:** ``True`` -- **Production value:** Usually, you will want to set it to ``False`` for a - private instance. - -`ADMIN_PASSWORD` ----------------- - -Hashed password to access protected endpoints. If left empty, all -administrative tasks are disabled. - -- **Default value:** ``""`` (empty string) -- **Production value:** To generate the proper password HASH, use - ``ihatemoney generate_password_hash`` and copy the output into the value of - *ADMIN_PASSWORD*. - -`ALLOW_PUBLIC_PROJECT_CREATION` -------------------------------- - -If set to ``True``, everyone can create a project without entering the admin -password. If set to ``False``, the password needs to be entered (and as such, -defined in the settings). - -- **Default value:** : ``True``. - - -`ACTIVATE_ADMIN_DASHBOARD` --------------------------- - -If set to `True`, the dashboard will become accessible entering the admin -password, if set to `True`, a non empty ADMIN_PASSWORD needs to be set. - -- **Default value**: ``False`` - -`APPLICATION_ROOT` ------------------- - -If empty, ihatemoney will be served at domain root (e.g: *http://domain.tld*), -if set to ``"somestring"``, it will be served from a "folder" -(e.g: *http://domain.tld/somestring*). - -- **Default value:** ``""`` (empty string) - -`BABEL_DEFAULT_TIMEZONE` ------------------------- - -The timezone that will be used to convert date and time when displaying them -to the user (all times are always stored in UTC internally). -If not set, it will default to the timezone configured on the Operating System -of the server running ihatemoney, which may or may not be what you want. - -- **Default value:** *unset* (use the timezone of the server Operating System) -- **Production value:** Set to the timezone of your expected users, with a - format such as ``"Europe/Paris"``. See `this list of TZ database names`_ - for a complete list. - -Note: this setting is actually interpreted by Flask-Babel, see the -`Flask-Babel guide for formatting dates`_ for details. - -.. _this list of TZ database name: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List - -.. _Flask-Babel guide for formatting dates: https://pythonhosted.org/Flask-Babel/#formatting-dates - -`ENABLE_CAPTCHA` ---------------- - -It is possible to add a simple captcha in order to filter out spammer bots on the form creation. -In order to do so, you just have to set `ENABLE_CAPTCHA = True`. - -`LEGAL_LINK` ------------- - -You may want to point to a special legal page, for instance to give information -about GDPR, or how you handle the data of your users. - -If you want to do this, you can use the `LEGAL_LINK` setting. Set it to the URL -you want. - -Configuring emails sending --------------------------- - -By default, Ihatemoney sends emails using a local SMTP server, but it's -possible to configure it to act differently, thanks to the great -`Flask-Mail project `_ - -* **MAIL_SERVER** : default **'localhost'** -* **MAIL_PORT** : default **25** -* **MAIL_USE_TLS** : default **False** -* **MAIL_USE_SSL** : default **False** -* **MAIL_DEBUG** : default **app.debug** -* **MAIL_USERNAME** : default **None** -* **MAIL_PASSWORD** : default **None** -* **DEFAULT_MAIL_SENDER** : default **None** diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 00000000..2ed64cff --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,289 @@ +# Contributing + +## How to contribute + +You would like to contribute? First, thanks a bunch! This project is a +small project with just a few people behind it, so any help is +appreciated! + +There are different ways to help us, regarding if you are a designer, a +developer or an user. + +### As a developer + +If you want to contribute code, you can write it and then issue a pull +request on github. To get started, please read {ref}`setup-dev-environment` and +{ref}`contributing-as-a-dev`. + +### As a designer / Front-end developer + +Feel free to provide mockups, or to involve yourself in the discussions +happening on the GitHub issue tracker. All ideas are welcome. Of course, +if you know how to implement them, feel free to fork and make a pull +request. + +### As a translator + +If you're able to translate Ihatemoney in your own language, head over +to [the website we use for +translations](https://hosted.weblate.org/projects/i-hate-money/i-hate-money/) +and start translating. + +All the heavy lifting will be done automatically, and your strings will +eventually be integrated. + +Once a language is ready to be integrated, add it to the +`SUPPORTED_LANGUAGES` list, in `ihatemoney/default_settings.py`. + +### End-user + +You are using the application and found a bug? You have some ideas about +how to improve the project? Please tell us [by filling a new +issue](https://github.com/spiral-project/ihatemoney/issues). + +Thanks again! + +(setup-dev-environment)= +## Set up a dev environment + +You must develop on top of the Git master branch: + + git clone https://github.com/spiral-project/ihatemoney.git + +Then you need to build your dev environment. Choose your way... + +### The quick way + +If System {ref}`installation-requirements` are +fulfilled, you can just issue: + + make serve + +It will setup a [Virtual +environment](https://docs.python.org/3/tutorial/venv.html), install +dependencies, and run the test server. + +### The hard way + +Alternatively, you can use pip to install dependencies yourself. That +would be: + + pip install -e . + +And then run the application: + + cd ihatemoney + python run.py + +### The docker way + +If you prefer to use docker, then you can build your image with: + + docker build -t ihatemoney . + +### Accessing dev server + +In any case, you can point your browser at . +It's as simple as that! + +### Updating + +In case you want to update to newer versions (from Git), you can just +run the "update" command: + + make update + +### Useful settings + +It is better to actually turn the debugging mode on when you\'re +developing. You can create a `settings.cfg` file, with the following +content: + + DEBUG = True + SQLACHEMY_ECHO = DEBUG + +Then before running the application, declare its path with : + + export IHATEMONEY_SETTINGS_FILE_PATH="$(pwd)/settings.cfg" + +You can also set the `TESTING` flag to `True` so no mails are sent (and +no exception is raised) while you\'re on development mode. + +In some cases, you may need to disable secure cookies by setting +`SESSION_COOKIE_SECURE` to `False`. This is needed if you access your +dev server over the network: with the default value of +`SESSION_COOKIE_SECURE`, the browser will refuse to send the session +cookie over insecure HTTP, so many features of Ihatemoney won\'t work +(project login, language change, etc). + +(contributing-as-a-dev)= +## Contributing as a developer + +All code contributions should be submitted as pull requests on the +[github project](https://github.com/spiral-project/ihatemoney). + +Below are some points that you should check to help you prepare your +pull request. + +### Running tests + +Please, think about updating and running the tests before asking for a +pull request as it will help us to maintain the code clean and running. + +To run the tests: + + make test + +Tests can be edited in `ihatemoney/tests/tests.py`. If some test cases +fail because of your changes, first check whether your code correctly +handle these cases. If you are confident that your code is correct and +that the test cases simply need to be updated to match your changes, +update the test cases and send them as part of your pull request. + +If you are introducing a new feature, you need to either add tests to +existing classes, or add a new class (if your new feature is +significantly different from existing code). + +### Formatting code + +We are using [black](https://black.readthedocs.io/en/stable/) and +[isort](https://timothycrosley.github.io/isort/) formatters for all the +Python files in this project. Be sure to run it locally on your files. +To do so, just run: + + make black isort + +You can also integrate them with your dev environment (as a +*format-on-save* hook, for instance). + +### Creating database migrations + +In case you need to modify the database schema, first make sure that you +have an up-to-date database by running the dev server at least once (the +quick way or the hard way, see above). The dev server applies all +existing migrations when starting up. + +You can now update the models in `ihatemoney/models.py`. Then run the +following command to create a new database revision file: + + make create-database-revision + +If your changes are simple enough, the generated script will be +populated with the necessary migrations steps. You can view and edit the +generated script, which is useful to review that the expected model +changes have been properly detected. Usually the auto-detection works +well in most cases, but you can of course edit the script to fix small +issues. You could also edit the script to add data migrations. + +When you are done with your changes, don't forget to add the migration +script to your final git commit! + +If the migration script looks completely wrong, remove the script and +start again with an empty database. The simplest way is to remove or +rename the dev database located at `/tmp/ihatemoney.db`, and run the dev +server at least once. + +For complex migrations, it is recommended to start from an empty +revision file which can be created with the following command: + + make create-empty-database-revision + +You then need to write the migration steps yourself. + +## How to build the documentation ? + +The documentation is using +[sphinx](http://www.sphinx-doc.org/en/stable/) and its source is located +inside the [docs +folder](https://github.com/spiral-project/ihatemoney/tree/master/docs). + +Install doc dependencies (within the virtual environment, if any): + + pip install -e .[doc] + +And to produce a HTML doc in the [docs/_output]{.title-ref} folder: + + cd docs/ + make html + +## How to release? + +### Requirements + +To create a new release, make sure you fullfil all requirements: + +- Are you a maintainer of the pypi package? + +- Are you sure you have no local tags? They will all be published to + the github process as part of the release process + +- Make sure you have a `~/.pypirc` file with the following content, + replacing `YOUR_PYPI_USERNAME` with your real username: + + [distutils] + index-servers = + pypi + + [pypi] + username:YOUR_PYPI_USERNAME + +### Choosing a version number + +The project follows [semantic versioning](https://semver.org/). To sum +things up: + +- **if there is a breaking change since the last release:** increase + the major version number (11.X.Y → 12.0.0). Example of breaking + changes: drop support for an old version of python, new setting + without default value (requires an admin to configure the new + setting), changed URL paths, any other incompatible change. Make + sure to {ref}`document the upgrade process`. +- **if there is a significant new feature or a new setting:** increase + the minor version number (11.4.Y → 11.5.0). Make sure to + {ref}`document any new settings`. +- **if it\'s mostly bugfixes and small changes:** increase the patch + version number (11.4.8 → 11.4.9) + +### Making the release + +In order to issue a new release, follow the following steps: + +- Merge remaining pull requests; + +- Switch to the master branch; + +- Update `CHANGELOG.md` with the last changes; + +- Update `CONTRIBUTORS` (instructions inside the file); + +- If needed, recompress assets. It requires zopflipng and ImageMagick + `mogrify`: + + make compress-assets + +- Build the translations: + + make update-translations + make build-translations + +- If you're not completely sure of yourself at this point, you can + optionally: create a new branch, push it, open a pull request, check + the CI result, and then merge the branch to master. + +Once this is done, make sure your local git repository is on the master +branch, and let's release!: + + make release + +This will publish the new version to [the Python Package +Index](https://pypi.org) (PyPI) and publish a tag in the git repository. + +::: {note} + +The above command will prompt for version number, handle +`CHANGELOG.md` and `setup.cfg` updates, package creation, +pypi upload. It will prompt you before each step to get your consent. +::: + +Finally, create a release on Github and copy the relevant changelog +extract into it. diff --git a/docs/contributing.rst b/docs/contributing.rst deleted file mode 100644 index 6f78c4ff..00000000 --- a/docs/contributing.rst +++ /dev/null @@ -1,295 +0,0 @@ -Contributing -############ - -.. _how-to-contribute: - -How to contribute -================= - -You would like to contribute? First, thanks a bunch! This project is a small -project with just a few people behind it, so any help is appreciated! - -There are different ways to help us, regarding if you are a designer, -a developer or an user. - -As a developer --------------- - -If you want to contribute code, you can write it and then issue a pull request -on github. To get started, please read :ref:`setup-dev-environment` and -:ref:`contributing-developer`. - -As a designer / Front-end developer ------------------------------------ - -Feel free to provide mockups, or to involve yourself in the discussions -happening on the GitHub issue tracker. All ideas are welcome. Of course, if you -know how to implement them, feel free to fork and make a pull request. - -As a translator ---------------- - -If you're able to translate Ihatemoney in your own language, -head over to `the website we use for translations `_ -and start translating. - -All the heavy lifting will be done automatically, and your strings will -eventually be integrated. - -Once a language is ready to be integrated, add it to the -``SUPPORTED_LANGUAGES`` list, in ``ihatemoney/default_settings.py``. - -End-user --------- - -You are using the application and found a bug? You have some ideas about how to -improve the project? Please tell us `by filling a new issue `_. -Or, if you prefer, you can send me an e-mail to `alexis@notmyidea.org` and I -will update the issue tracker with your feedback. - -Thanks again! - -.. _setup-dev-environment: - -Set up a dev environment -======================== - -You must develop on top of the Git master branch:: - - git clone https://github.com/spiral-project/ihatemoney.git - -Then you need to build your dev environment. Choose your way… - -The quick way -------------- - -If System :ref:`installation-requirements` are fulfilled, you can just issue:: - - make serve - -It will setup a `Virtual environment `_, -install dependencies, and run the test server. - -The hard way ------------- - -Alternatively, you can use pip to install dependencies yourself. That would be:: - - pip install -e . - -And then run the application:: - - cd ihatemoney - python run.py - -The docker way --------------- - -If you prefer to use docker, then you can build your image with:: - - docker build -t ihatemoney . - -Accessing dev server --------------------- - -In any case, you can point your browser at `http://localhost:5000 `_. -It's as simple as that! - -Updating --------- - -In case you want to update to newer versions (from Git), you can just run the "update" command:: - - make update - -Useful settings ----------------- - -It is better to actually turn the debugging mode on when you're developing. -You can create a ``settings.cfg`` file, with the following content:: - - DEBUG = True - SQLACHEMY_ECHO = DEBUG - -Then before running the application, declare its path with :: - - export IHATEMONEY_SETTINGS_FILE_PATH="$(pwd)/settings.cfg" - -You can also set the ``TESTING`` flag to ``True`` so no mails are sent -(and no exception is raised) while you're on development mode. - -In some cases, you may need to disable secure cookies by setting -``SESSION_COOKIE_SECURE`` to ``False``. This is needed if you -access your dev server over the network: with the default value -of ``SESSION_COOKIE_SECURE``, the browser will refuse to send -the session cookie over insecure HTTP, so many features of Ihatemoney -won't work (project login, language change, etc). - -.. _contributing-developer: - -Contributing as a developer -=========================== - -All code contributions should be submitted as Pull Requests on the -`github project `_. - -Below are some points that you should check to help you prepare your Pull Request. - -Running tests -------------- - -Please, think about updating and running the tests before asking for a pull request -as it will help us to maintain the code clean and running. - -To run the tests:: - - make test - -Tests can be edited in ``ihatemoney/tests/tests.py``. If some test cases fail because -of your changes, first check whether your code correctly handle these cases. -If you are confident that your code is correct and that the test cases simply need -to be updated to match your changes, update the test cases and send them as part of -your pull request. - -If you are introducing a new feature, you need to either add tests to existing classes, -or add a new class (if your new feature is significantly different from existing code). - -Formatting code ---------------- - -We are using `black `_ and -`isort `_ formatters for all the Python -files in this project. Be sure to run it locally on your files. -To do so, just run:: - - make black isort - -You can also integrate them with your dev environment (as a *format-on-save* -hook, for instance). - -Creating database migrations ----------------------------- - -In case you need to modify the database schema, first make sure that you have -an up-to-date database by running the dev server at least once (the quick way -or the hard way, see above). The dev server applies all existing migrations -when starting up. - -You can now update the models in ``ihatemoney/models.py``. Then run the following -command to create a new database revision file:: - - make create-database-revision - -If your changes are simple enough, the generated script will be populated with -the necessary migrations steps. You can view and edit the generated script, which -is useful to review that the expected model changes have been properly detected. -Usually the auto-detection works well in most cases, but you can of course edit the -script to fix small issues. You could also edit the script to add data migrations. - -When you are done with your changes, don't forget to add the migration script to -your final git commit! - -If the migration script looks completely wrong, remove the script and start again -with an empty database. The simplest way is to remove or rename the dev database -located at ``/tmp/ihatemoney.db``, and run the dev server at least once. - -For complex migrations, it is recommended to start from an empty revision file -which can be created with the following command:: - - make create-empty-database-revision - -You then need to write the migration steps yourself. - - -How to build the documentation ? -================================ - -The documentation is using `sphinx `_ and -its source is located inside the `docs folder -`_. - -Install doc dependencies (within the virtual environment, if any):: - - pip install -e .[doc] - -And to produce a HTML doc in the `docs/_output` folder:: - - cd docs/ - make html - -How to release? -=============== - -Requirements ------------- - -To create a new release, make sure you fullfil all requirements: - -- Are you a maintainer of the pypi package? -- Are you sure you have no local tags? They will all be published - to the github process as part of the release process -- Make sure you have a ``~/.pypirc`` file with the following content, - replacing ``YOUR_PYPI_USERNAME`` with your real username:: - - [distutils] - index-servers = - pypi - - [pypi] - username:YOUR_PYPI_USERNAME - -Choosing a version number -------------------------- - -The project follows `semantic versioning `_. -To sum things up: - -- **if there is a breaking change since the last release:** increase the major - version number (11.X.Y -> 12.0.0). Example of breaking changes: drop support - for an old version of python, new setting without default value (requires - an admin to configure the new setting), changed URL paths, any other incompatible - change. Make sure to :ref:`document the upgrade process`. - -- **if there is a significant new feature or a new setting:** increase the minor - version number (11.4.Y -> 11.5.0). Make sure to :ref:`document any new settings`. - -- **if it's mostly bugfixes and small changes:** increase the patch version number - (11.4.8 -> 11.4.9) - -Making the release ------------------- - -In order to issue a new release, follow the following steps: - -- Merge remaining pull requests; -- Switch to the master branch; -- Update :file:`CHANGELOG.rst` with the last changes; -- Update :file:`CONTRIBUTORS` (instructions inside the file); -- If needed, recompress assets. It requires zopflipng and ImageMagick `mogrify`:: - - make compress-assets - -- Build the translations:: - - make update-translations - make build-translations - -- If you're not completely sure of yourself at this point, you - can optionally: create a new branch, push it, open a pull request, - check the CI result, and then merge the branch to master. - -Once this is done, make sure your local git repository is on the master branch, -and let's release!:: - - make release - -This will publish the new version to `the Python Package Index `_ (PyPI) -and publish a tag in the git repository. - -.. note:: The above command will prompt for version number, handle - :file:`CHANGELOG.rst` and :file:`setup.cfg` updates, package creation, - pypi upload. It will prompt you before each step to get your consent. - -Finally, create a release on Github and copy the relevant changelog extract into it. -Unfortunately, you need to manually convert links to Markdown... -We have a `discussion to automate this step `_. diff --git a/docs/index.rst b/docs/index.rst index 4a9fc6e5..97c654bd 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -15,12 +15,12 @@ Table of contents .. toctree:: :maxdepth: 1 - installation - configuration - upgrade - api - security - contributing + installation.md + configuration.md + upgrade.md + api.md + security.md + contributing.md Indices and tables ================== diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 00000000..405fc63b --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,277 @@ +# Installation + +There are multiple ways to install «Ihatemoney» on your system : + +1. {ref}`docker`. +2. [Via Yunohost](https://github.com/YunoHost-Apps/ihatemoney_ynh) (a + server operating system aiming to make self-hosting accessible to + anyone) +3. {ref}`manual-installation` + + +:::{note} +We lack some knowledge about packaging to make Ihatemoney installable on +mainstream Linux distributions. If you want to give us a hand on the +topic, please check-out [the issue about debian +packaging](https://github.com/spiral-project/ihatemoney/issues/227). +::: + +(docker)= +## With Docker + +Docker images are published [on the Docker +hub](https://hub.docker.com/r/ihatemoney/ihatemoney/). + +This is probably the simplest way to get something running. Once you +have Docker installed on your system, just issue : + + docker run -d -p 8000:8000 ihatemoney/ihatemoney + +Ihatemoney is now available on . + +All {ref}`settings` can be +passed with `-e` parameters e.g. with a secure `SECRET_KEY`, an external +mail server and an external database: + + docker run -d -p 8000:8000 \ + -e SECRET_KEY="supersecure" \ + -e SQLALCHEMY_DATABASE_URI="mysql+pymysql://user:pass@10.42.58.250/ihm" \ + -e MAIL_SERVER=smtp.gmail.com \ + -e MAIL_PORT=465 \ + -e MAIL_USERNAME=your-email@gmail.com \ + -e MAIL_PASSWORD=your-password \ + -e MAIL_USE_SSL=True \ + ihatemoney/ihatemoney + +A volume can also be specified to persist the default database file: + + docker run -d -p 8000:8000 -v /host/path/to/database:/database ihatemoney/ihatemoney + +To enable the Admin dashboard, first generate a hashed password with: + + docker run -it --rm --entrypoint ihatemoney ihatemoney/ihatemoney generate_password_hash + +At the prompt, enter a password to use for the admin dashboard. The +command will print the hashed password string. + +Add these additional environment variables to the docker run invocation: + + -e ACTIVATE_ADMIN_DASHBOARD=True \ + -e ADMIN_PASSWORD= \ + +Additional gunicorn parameters can be passed using the docker `CMD` +parameter. For example, use the following command to add more gunicorn +workers: + + docker run -d -p 8000:8000 ihatemoney/ihatemoney -w 3 + +(manual-installation)= +## Via a manual installation + +(system-requirements)= +### Requirements + +«Ihatemoney» depends on: + +- **Python**: version 3.6 to 3.9 included will work. +- **A Backend**: to choose among SQLite, PostgreSQL, MariaDB (>= + 10.3.2) or Memory. +- **Virtual environment** (recommended): [python3-venv]{.title-ref} + package under Debian/Ubuntu. + +We recommend using [virtual +environments](https://docs.python.org/3/tutorial/venv.html) to isolate +the installation from other softwares on your machine, but it\'s not +mandatory. + +If wondering about the backend, SQLite is the simplest and will work +fine for most small to medium setups. + +::: {note} +If curious, source config templates can be found in the [project git +repository](https://github.com/spiral-project/ihatemoney/tree/master/ihatemoney/conf-templates). +::: + +(virtualenv-preparation)= +### Prepare virtual environment (recommended) + +Choose an installation path, here the current user's home directory +(~). + +Create a virtual environment: + + python3 -m venv ~/ihatemoney + cd ~/ihatemoney + +Activate the virtual environment: + + source bin/activate + +::: {note} +You will have to re-issue that `source` command if you open a new +terminal. +::: + +(pip)= +### Install + +Install the latest release with pip: + + pip install ihatemoney + +### Test it + +Once installed, you can start a test server: + + ihatemoney runserver + +And point your browser at . + +### Generate your configuration + +1. Initialize the ihatemoney directories: + + mkdir /etc/ihatemoney /var/lib/ihatemoney + +2. Generate settings: + + ihatemoney generate-config ihatemoney.cfg > /etc/ihatemoney/ihatemoney.cfg + chmod 740 /etc/ihatemoney/ihatemoney.cfg + +You probably want to adjust `/etc/ihatemoney/ihatemoney.cfg` contents, +you may do it later, see {ref}`configuration`. + +(mariadb)= +### Configure database with MariaDB (optional) + +::: {note} +Only required if you use MariaDB. Make sure to use MariaDB 10.3.2 or +newer. +::: + +1. Install PyMySQL dependencies. On Debian or Ubuntu, that would be: + + apt install python3-dev libssl-dev + +2. Install PyMySQL (within your virtual environment): + + pip install 'PyMySQL>=0.9,<1.1' + +3. Create an empty database and a database user + +4. Configure + {ref}`configuration:SQLALCHEMY_DATABASE_URI` accordingly + +(postresql)= +### Configure database with PostgreSQL (optional) + +::: {note} +Only required if you use Postgresql. +::: + +1. Install python driver for PostgreSQL (from within your virtual + environment): + + pip install psycopg2 + +2. Create the users and tables. On the command line, this looks like: + + sudo -u postgres psql + postgres=# create database mydb; + postgres=# create user myuser with encrypted password 'mypass'; + postgres=# grant all privileges on database mydb to myuser; + +3. Configure + {ref}`configuration:SQLALCHEMY_DATABASE_URI` accordingly. + +### Configure a reverse proxy + +When deploying this service in production, you want to have a reverse +proxy in front of the python application. + +Here are documented two stacks. You can of course use another one if you +want. Don't hesitate to contribute a small tutorial here if you want. + +1. Apache and *mod_wsgi* +2. Nginx, Gunicorn and Supervisord/Systemd + +### With Apache and mod_wsgi + +1. Fix permissions (considering `www-data` is the user running apache): + + chgrp www-data /etc/ihatemoney/ihatemoney.cfg + chown www-data /var/lib/ihatemoney + +2. Install Apache and mod_wsgi : `libapache2-mod-wsgi(-py3)` for Debian + based and `mod_wsgi` for RedHat based distributions + +3. Create an Apache virtual host, the command + `ihatemoney generate-config apache-vhost.conf` will output a good + starting point (read and adapt it). + +4. Activate the virtual host if needed and restart Apache + +### With Nginx, Gunicorn and Supervisord/systemd + +Install Gunicorn: + + pip install gunicorn + +1. Create a dedicated unix user (here called `ihatemoney`), + required dirs, and fix permissions: + + useradd ihatemoney + chown ihatemoney /var/lib/ihatemoney/ + chgrp ihatemoney /etc/ihatemoney/ihatemoney.cfg + +2. Create gunicorn config file : + + ihatemoney generate-config gunicorn.conf.py > /etc/ihatemoney/gunicorn.conf.py + +3. Setup Supervisord or systemd + + - To use Supervisord, create supervisor config file : + + ihatemoney generate-config supervisord.conf > /etc/supervisor/conf.d/ihatemoney.conf + + - To use systemd services, create `ihatemoney.service` in `/etc/systemd/system/ihatemoney.service` [^1]: + + [Unit] + Description=I hate money + Requires=network.target postgresql.service + After=network.target postgresql.service + + [Service] + Type=simple + User=ihatemoney + ExecStart=%h/ihatemoney/bin/gunicorn -c /etc/ihatemoney/gunicorn.conf.py ihatemoney.wsgi:application + SyslogIdentifier=ihatemoney + + [Install] + WantedBy=multi-user.target + + Obviously, adapt the `ExecStart` path for your installation + folder. + + If you use SQLite as database: remove mentions of + `postgresql.service` in `ihatemoney.service`. If you use MariaDB + as database: replace mentions of `postgresql.service` by + `mariadb.service` in `ihatemoney.service`. + + Then reload systemd, enable and start `ihatemoney`: + + systemctl daemon-reload + systemctl enable ihatemoney.service + systemctl start ihatemoney.service + +4. Copy (and adapt) output of `ihatemoney generate-config nginx.conf` + with your nginx vhosts[^2] + +5. Reload nginx (and supervisord if you use it). It should be working + ;) + +[^1]: `/etc/systemd/system/ihatemoney.service` path may change depending + on your distribution. + +[^2]: typically, */etc/nginx/conf.d/* or */etc/nginx/sites-available*, + depending on your distribution. diff --git a/docs/installation.rst b/docs/installation.rst deleted file mode 100644 index bf87232d..00000000 --- a/docs/installation.rst +++ /dev/null @@ -1,265 +0,0 @@ -.. _installation: - -Installation -############ - -There are multiple ways to install «Ihatemoney» on your system : - -1. :ref:`Via Docker`. -2. `Via Yunohost `_ - (a server operating system aiming to make self-hosting accessible to anyone) -3. Do a :ref:`manual installation`. - -.. note:: We lack some knowledge about packaging to make Ihatemoney installable - on mainstream Linux distributions. If you want to give us a hand on the topic, - please check-out `the issue about debian packaging `_. - -.. _docker: - -With Docker -=========== - -Docker images are published `on the Docker hub `_. - -This is probably the simplest way to get something running. Once you have Docker installed -on your system, just issue :: - - docker run -d -p 8000:8000 ihatemoney/ihatemoney - -Ihatemoney is now available on http://localhost:8000. - -All :ref:`settings` can be passed with ``-e`` parameters -e.g. with a secure ``SECRET_KEY``, an external mail server and an -external database:: - - docker run -d -p 8000:8000 \ - -e SECRET_KEY="supersecure" \ - -e SQLALCHEMY_DATABASE_URI="mysql+pymysql://user:pass@10.42.58.250/ihm" \ - -e MAIL_SERVER=smtp.gmail.com \ - -e MAIL_PORT=465 \ - -e MAIL_USERNAME=your-email@gmail.com \ - -e MAIL_PASSWORD=your-password \ - -e MAIL_USE_SSL=True \ - ihatemoney/ihatemoney - -.. note: Connecting to a postgresql database is not supported for now in the - docker container. - -A volume can also be specified to persist the default database file:: - - docker run -d -p 8000:8000 -v /host/path/to/database:/database ihatemoney/ihatemoney - -To enable the Admin dashboard, first generate a hashed password with:: - - docker run -it --rm --entrypoint ihatemoney ihatemoney/ihatemoney generate_password_hash - -At the prompt, enter a password to use for the admin dashboard. The -command will print the hashed password string. - -Add these additional environment variables to the docker run invocation:: - - -e ACTIVATE_ADMIN_DASHBOARD=True \ - -e ADMIN_PASSWORD= \ - -Additional gunicorn parameters can be passed using the docker ``CMD`` -parameter. -For example, use the following command to add more gunicorn workers:: - - docker run -d -p 8000:8000 ihatemoney/ihatemoney -w 3 - - -.. _manual-installation: - -Manual Installation -=================== - -.. _installation-requirements: - -Requirements ------------- - -«Ihatemoney» depends on: - -* **Python**: version 3.6 to 3.9 included will work. -* **A Backend**: to choose among SQLite, PostgreSQL, MariaDB (>= 10.3.2) or Memory. -* **Virtual environment** (recommended): `python3-venv` package under Debian/Ubuntu. - -We recommend using `virtual environments `_ -to isolate the installation from other softwares on your machine, but it's not mandatory. - -If wondering about the backend, SQLite is the simplest and will work fine for -most small to medium setups. - -.. note:: If curious, source config templates can be found in the - `project git repository `_. - -.. _virtualenv-preparation: - -Prepare virtual environment (recommended) ------------------------------------------ - -Choose an installation path, here the current user's home directory (`~`). - -Create a virtual environment:: - - python3 -m venv ~/ihatemoney - cd ~/ihatemoney - -Activate the virtual environment:: - - source bin/activate - -.. note:: You will have to re-issue that ``source`` command if you open a new - terminal. - -Install -------- - -Install the latest release with pip:: - - pip install ihatemoney - -Test it -------- - -Once installed, you can start a test server:: - - ihatemoney runserver - -And point your browser at `http://localhost:5000 `_. - -Generate your configuration ---------------------------- - -1. Initialize the ihatemoney directories:: - - mkdir /etc/ihatemoney /var/lib/ihatemoney - -2. Generate settings:: - - ihatemoney generate-config ihatemoney.cfg > /etc/ihatemoney/ihatemoney.cfg - chmod 740 /etc/ihatemoney/ihatemoney.cfg - -You probably want to adjust ``/etc/ihatemoney/ihatemoney.cfg`` contents, -you may do it later, see :ref:`configuration`. - -Configure database with MariaDB (optional) ------------------------------------------- - -.. note:: Only required if you use MariaDB. Make sure to use MariaDB 10.3.2 or newer. - -1. Install PyMySQL dependencies. On Debian or Ubuntu, that would be:: - - apt install python3-dev libssl-dev - -2. Install PyMySQL (within your virtual environment):: - - pip install 'PyMySQL>=0.9,<1.1' - -3. Create an empty database and a database user -4. Configure :ref:`SQLALCHEMY_DATABASE_URI ` accordingly - -Configure database with PostgreSQL (optional) ---------------------------------------------- - -.. note:: Only required if you use Postgresql. - -1. Install python driver for PostgreSQL (from within your virtual environment):: - - pip install psycopg2 - -2. Create the users and tables. On the command line, this looks like:: - - sudo -u postgres psql - postgres=# create database mydb; - postgres=# create user myuser with encrypted password 'mypass'; - postgres=# grant all privileges on database mydb to myuser; - -3. Configure :ref:`SQLALCHEMY_DATABASE_URI ` accordingly. - -Configure a reverse proxy -------------------------- - -When deploying this service in production, you want to have a reverse proxy -in front of the python application. - -Here are documented two stacks. You can of course use another one if you want. -Don't hesitate to contribute a small tutorial here if you want. - -1. Apache and `mod_wsgi` -2. Nginx, Gunicorn and Supervisord/Systemd - -With Apache and mod_wsgi ------------------------- - -1. Fix permissions (considering `www-data` is the user running apache):: - - chgrp www-data /etc/ihatemoney/ihatemoney.cfg - chown www-data /var/lib/ihatemoney - -2. Install Apache and mod_wsgi : ``libapache2-mod-wsgi(-py3)`` for Debian - based and ``mod_wsgi`` for RedHat based distributions -3. Create an Apache virtual host, the command - ``ihatemoney generate-config apache-vhost.conf`` will output a good - starting point (read and adapt it). -4. Activate the virtual host if needed and restart Apache - -With Nginx, Gunicorn and Supervisord/systemd --------------------------------------------- - -Install Gunicorn:: - - pip install gunicorn - -1. Create a dedicated unix user (here called `ihatemoney`), required dirs, and fix permissions:: - - useradd ihatemoney - chown ihatemoney /var/lib/ihatemoney/ - chgrp ihatemoney /etc/ihatemoney/ihatemoney.cfg - -2. Create gunicorn config file :: - - ihatemoney generate-config gunicorn.conf.py > /etc/ihatemoney/gunicorn.conf.py - -3. Setup Supervisord or systemd - - - To use Supervisord, create supervisor config file :: - - ihatemoney generate-config supervisord.conf > /etc/supervisor/conf.d/ihatemoney.conf - - - To use systemd services, create ``ihatemoney.service`` in [#systemd-services]_:: - - [Unit] - Description=I hate money - Requires=network.target postgresql.service - After=network.target postgresql.service - - [Service] - Type=simple - User=ihatemoney - ExecStart=%h/ihatemoney/bin/gunicorn -c /etc/ihatemoney/gunicorn.conf.py ihatemoney.wsgi:application - SyslogIdentifier=ihatemoney - - [Install] - WantedBy=multi-user.target - - Obviously, adapt the ``ExecStart`` path for your installation folder. - - If you use SQLite as database: remove mentions of ``postgresql.service`` in ``ihatemoney.service``. - If you use MariaDB as database: replace mentions of ``postgresql.service`` by ``mariadb.service`` in ``ihatemoney.service``. - - Then reload systemd, enable and start ``ihatemoney``:: - - systemctl daemon-reload - systemctl enable ihatemoney.service - systemctl start ihatemoney.service - -4. Copy (and adapt) output of ``ihatemoney generate-config nginx.conf`` - with your nginx vhosts [#nginx-vhosts]_ -5. Reload nginx (and supervisord if you use it). It should be working ;) - -.. [#nginx-vhosts] typically, */etc/nginx/conf.d/* or - */etc/nginx/sites-available*, depending on your distribution. - -.. [#systemd-services] ``/etc/systemd/system/ihatemoney.service`` - path may change depending on your distribution. diff --git a/docs/security.md b/docs/security.md new file mode 100644 index 00000000..51944b33 --- /dev/null +++ b/docs/security.md @@ -0,0 +1,96 @@ +# Security + +Ihatemoney does not have user accounts. Instead, authorization is based +around shared projects: this is a bit unusual and deserves some +explanation about the security model. + +First of all, Ihatemoney fundamentally assumes that all members of a +project trust each other. Otherwise, you would probably not share +expenses in the first place! + +That being said, there are a few mechanisms to limit the impact of a +malicious member and to manage changes in membership (e.g. ensuring that +a previous member can no longer access the project). But these +mechanisms don\'t prevent a malicious member from breaking things in +your project! + +## Security model + +A project has three main parameters when it comes to security: + +- **project identifier** (equivalent to a \"login\") +- **private code** (equivalent to a \"password\") +- **token** (cryptographically derived from the private code) + +Somebody with the private code can: + +- access the project through the web interface or the API +- add, modify or remove bills +- view project history +- change basic settings of the project +- change the email address associated to the project +- change the private code of the project + +Somebody with the token can manipulate the project through the API to do +essentially the same thing: + +- access the project +- add, modify or remove bills +- change basic settings of the project +- change the email address associated to the project +- change the private code of the project + +The token can also be used to build \"invitation links\". These links +allow to login on the web interface without knowing the private code, +see below. + +## Giving access to a project + +There are two main ways to give access to a project to a new person: + +- share the project identifier and private code using any out-of-band + communication method +- share an invitation link that allows to login on the web interface + without knowing the private code + +The second method is interesting because it does not reveal the private +code. In particular, somebody that is logged-in through the invitation +link will not be able to change the private code, because the web +interface requires a confirmation of the existing private code to change +it. However, a motivated person could extract the token from the +invitation link, use it to access the project through the API, and +change the private code through the API. + +## Removing access to a project + +If a person should no longer be able to access a project, the only way +is to change the private code. + +This will also automatically change the token: old invitation links +won\'t work anymore, and anybody with the old token will no longer be +able to access the project through the API. + +## Recovering access to a project + +If the private code is no longer known, the creator of the project can +still recover access. He/she must have provided an email address when +creating the project, and Ihatemoney can send a reset link to this email +address (classical \"forgot your password\" functionality). + +Note, however, that somebody with the private code could have changed +the email address in the settings at any time. + +## Recovering lost data + +A member can delete or change bills. There is no way to revert such +actions for now. However, each project has an history page that lists +all actions done on the project. This history can be used to manually +correct previous changes. + +Note, however, that the history feature is primarily meant to protect +against mistakes: a malicious member can easily remove all entries from +the history! + +The best defense against this kind of issues is\... backups! All data +for a project can be exported through the settings page or through the +API. diff --git a/docs/security.rst b/docs/security.rst deleted file mode 100644 index 1132821e..00000000 --- a/docs/security.rst +++ /dev/null @@ -1,97 +0,0 @@ -Security -######## - -Ihatemoney does not have user accounts. Instead, authorization is based around -shared projects: this is a bit unusual and deserves some explanation about -the security model. - -First of all, Ihatemoney fundamentally assumes that all members of a project trust -each other. Otherwise, you would probably not share expenses in the first place! - -That being said, there are a few mechanisms to limit the impact of a malicious -member and to manage changes in membership (e.g. ensuring that a previous member -can no longer access the project). But these mechanisms don't prevent a malicious member -from breaking things in your project! - -Security model -============== - -A project has three main parameters when it comes to security: - -- **project identifier** (equivalent to a "login") -- **private code** (equivalent to a "password") -- **token** (cryptographically derived from the private code) - -Somebody with the private code can: - -- access the project through the web interface or the API -- add, modify or remove bills -- view project history -- change basic settings of the project -- change the email address associated to the project -- change the private code of the project - -Somebody with the token can manipulate the project through the API to -do essentially the same thing: - -- access the project -- add, modify or remove bills -- change basic settings of the project -- change the email address associated to the project -- change the private code of the project - -The token can also be used to build "invitation links". These links allow -to login on the web interface without knowing the private code, see below. - -Giving access to a project -========================== - -There are two main ways to give access to a project to a new person: - -- share the project identifier and private code using any out-of-band - communication method - -- share an invitation link that allows to login on the web interface - without knowing the private code - -The second method is interesting because it does not reveal the private code. -In particular, somebody that is logged-in through the invitation link will not be able -to change the private code, because the web interface requires a confirmation -of the existing private code to change it. -However, a motivated person could extract the token from the invitation link, -use it to access the project through the API, and change the private code through -the API. - -Removing access to a project -============================ - -If a person should no longer be able to access a project, the only way is to change -the private code. - -This will also automatically change the token: old invitation links won't -work anymore, and anybody with the old token will no longer be able to access -the project through the API. - -Recovering access to a project -============================== - -If the private code is no longer known, the creator of the project can still recover -access. He/she must have provided an email address when creating the project, -and Ihatemoney can send a reset link to this email address (classical "forgot -your password" functionality). - -Note, however, that somebody with the private code could have changed the email -address in the settings at any time. - -Recovering lost data -==================== - -A member can delete or change bills. There is no way to revert such actions for now. -However, each project has an history page that lists all actions done on the project. -This history can be used to manually correct previous changes. - -Note, however, that the history feature is primarily meant to protect against mistakes: -a malicious member can easily remove all entries from the history! - -The best defense against this kind of issues is... backups! All data for a project can be -exported through the settings page or through the API. diff --git a/docs/upgrade.md b/docs/upgrade.md new file mode 100644 index 00000000..9d6d2b2e --- /dev/null +++ b/docs/upgrade.md @@ -0,0 +1,156 @@ +# Upgrading + +We keep [a ChangeLog](https://github.com/spiral-project/ihatemoney/blob/master/CHANGELOG.md), +please read it before upgrading. + +Ihatemoney follows [semantic versioning](http://semver.org/). So minor/patch +upgrades can be applied blindly. + +(general-procedure)= +## General procedure + +*(sufficient for minor/patch upgrades)* + +1. From the virtual environment (if any): + + pip install -U ihatemoney + +2. Restart *supervisor*, or *Apache*, depending on your setup. + +You may also want to set new configuration variables (if any). They are +mentioned in the +[ChangeLog](https://github.com/spiral-project/ihatemoney/blob/master/CHANGELOG.rst), +but this is **not required for minor/patch upgrades**, a safe default +will be used automatically. + +## Version-specific instructions + +*(must read for major upgrades)* + +When upgrading from a major version to another, you **must** follow +special instructions: + +### 4.x → 5.x + +#### Switch to a supported version of Python + +::: {note} +If you are already using Python ≥ 3.6, you can skip this section, no +special action is required. +::: + +If you were running IHateMoney using Python < 3.6, you must, **before** +upgrading: + +1. Ensure to have a Python ≥ 3.6 available on your system + +2. Rebuild your virtual environment (if any). It will *not* alter your + database nor configuration. For example, if your virtual environment + is in `/home/john/ihatemoney/`: + + rm -rf /home/john/ihatemoney + pyhton3 -m venv /home/john/ihatemoney + source /home/john/ihatemoney/bin/activate + +> You might need to `pip install` additional dependencies if you are +> using one or several of the following deployment options : +> +> - Gunicorn (Nginx) +> - MariaDB +> - PostgreSQL + +If so, pick the `pip` commands to use in the relevant section(s) of +{ref}`installation`. + +Then follow {ref}`general-procedure` from step 1 in order to complete the update. + +#### Disable session cookie security if running over plain HTTP + +::: {note} +If you are running Ihatemoney over HTTPS, no special action is required. +::: + +Session cookies are now marked "secure" by default to increase +security. + +If you run Ihatemoney over plain HTTP, you need to explicitly disable +this security feature by setting {ref}`configuration:SESSION_COOKIE_SECURE` to `False`. + +#### Switch to MariaDB >= 10.3.2 instead of MySQL + +::: {note} +If you are using SQLite or PostgreSQL, you can skip this section, no +special action is required. +::: + +If you were running IHateMoney with MySQL, you must switch to MariaDB. +MySQL is no longer a supported database option. + +In addition, the minimum supported version of MariaDB is 10.3.2. See +[this MySQL / MariaDB +issue](https://github.com/spiral-project/ihatemoney/issues/632) for +details. + +To upgrade: + +1. Ensure you have a MariaDB server installed and configured, and that + its version is at least 10.3.2. +2. Copy your database from MySQL to MariaDB. +3. Ensure that IHateMoney is correctly configured to use your MariaDB + database, see {ref}`configuration:SQLALCHEMY_DATABASE_URI` + +Then follow {ref}`general-procedure` from step 1 in order to complete the update. + +### 2.x → 3.x + +Sentry support has been removed. Sorry if you used it. + +Appart from that, {ref}`general-procedure` applies. + +### 1.x → 2.x + +#### Switch from git installation to pip installation + +The recommended installation method is now using *pip*. Git is now +intended for development only. + +::: {warning} + +Be extra careful to not remove your sqlite database nor your settings +file, if they are stored inside the cloned folder. +::: + +1. Delete the cloned folder + +::: {note} +If you are using a virtual environment, then the following commands +should be run inside it (see {ref}`virtualenv-preparation`). +::: + +2. Install ihatemoney with pip: + + pip install ihatemoney + +3. Fix your configuration file (paths *have* changed), depending on the + software you use in your setup: + + - **gunicorn**: `ihatemoney generate-config gunicorn.conf.py` + (nothing critical changed, keeping your old config might be + fine) + - **supervisor** : `ihatemoney generate-config supervisord.conf` + (mind the `command=` line) + - **apache**: `ihatemoney generate-config apache-vhost.conf` (mind + the `WSGIDaemonProcess`, `WSGIScriptAlias` and `Alias` lines) + +4. Restart *Apache* or *Supervisor*, depending on your setup. + +#### Upgrade ADMIN_PASSWORD to its hashed form + +::: {note} + +Not required if you are not using the ADMIN_PASSWORD feature. +::: + +`ihatemoney generate_password_hash` will do the hashing job for you, just put +its result in the `ADMIN_PASSWORD` var from your `ihatemoney.cfg` and restart +*apache* or the *supervisor* job. diff --git a/docs/upgrade.rst b/docs/upgrade.rst deleted file mode 100644 index 1ccfdbed..00000000 --- a/docs/upgrade.rst +++ /dev/null @@ -1,157 +0,0 @@ -.. _upgrade: - -Upgrading -######### - -We keep `a ChangeLog -`_. Read -it before upgrading. - -Ihatemoney follows `semantic versioning `_. So minor/patch -upgrades can be done blindly. - -.. _general-procedure: - -General procedure -================= - -*(sufficient for minor/patch upgrades)* - -1. From the virtual environment (if any):: - - pip install -U ihatemoney - -2. Restart *supervisor*, or *Apache*, depending on your setup. - -You may also want to set new configuration variables (if any). They are -mentioned in the `ChangeLog -`_, but -this is **not required for minor/patch upgrades**, a safe default will be used -automatically. - -Version-specific instructions -============================= - -*(must read for major upgrades)* - -When upgrading from a major version to another, you **must** follow special -instructions: - -4.x → 5.x ---------- - -Switch to a supported version of Python -+++++++++++++++++++++++++++++++++++++++ - -.. note:: If you are already using Python ≥ 3.6, you can skip this section, no - special action is required. - -If you were running IHateMoney using Python < 3.6, you must, **before** upgrading: - -1. Ensure to have a Python ≥ 3.6 available on your system -2. Rebuild your virtual environment (if any). It will *not* alter your database nor configuration. For example, if your virtual environment is in `/home/john/ihatemoney/`:: - - rm -rf /home/john/ihatemoney - pyhton3 -m venv /home/john/ihatemoney - source /home/john/ihatemoney/bin/activate - - You might need to ``pip install`` additional dependencies if you are using one - or several of the following deployment options : - - - Gunicorn (Nginx) - - MariaDB - - PostgreSQL - -If so, pick the ``pip`` commands to use in the relevant section(s) of -:ref:`installation`. - -Then follow :ref:`general-procedure` from step 1. in order to complete the update. - -Disable session cookie security if running over plain HTTP -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -.. note:: If you are running Ihatemoney over HTTPS, no special action is required. - -Session cookies are now marked "secure" by default to increase security. - -If you run Ihatemoney over plain HTTP, you need to explicitly disable this security -feature by setting ``SESSION_COOKIE_SECURE`` to ``False``, see :ref:`configuration`. - - -Switch to MariaDB >= 10.3.2 instead of MySQL -++++++++++++++++++++++++++++++++++++++++++++ - -.. note:: If you are using SQLite or PostgreSQL, you can skip this section, no - special action is required. - -If you were running IHateMoney with MySQL, you must switch to MariaDB. -MySQL is no longer a supported database option. - -In addition, the minimum supported version of MariaDB is 10.3.2. -See `this MySQL / MariaDB issue `_ -for details. - -To upgrade: - -1. Ensure you have a MariaDB server installed and configured, and that its - version is at least 10.3.2. - -2. Copy your database from MySQL to MariaDB. - -3. Ensure that IHateMoney is correctly configured to use your MariaDB database, - see :ref:`configuration`. - -Then follow :ref:`general-procedure` from step 1. in order to complete the update. - -2.x → 3.x ---------- - -Sentry support has been removed. Sorry if you used it. - -Appart from that, :ref:`general-procedure` applies. - - -1.x → 2.x ---------- - -Switch from git installation to pip installation -++++++++++++++++++++++++++++++++++++++++++++++++ - -The recommended installation method is now using *pip*. Git is now intended for -development only. - -.. warning:: Be extra careful to not remove your sqlite database nor your - settings file, if they are stored inside the cloned folder. - -1. Delete the cloned folder - - -.. note:: If you are using a virtual environment, then the following commands should be run inside it (see - :ref:`virtualenv-preparation`). - - -2. Install ihatemoney with pip:: - - pip install ihatemoney - -3. Fix your configuration file (paths *have* changed), depending on - the software you use in your setup: - - - **gunicorn**: ``ihatemoney generate-config gunicorn.conf.py`` (nothing - critical changed, keeping your old config might be fine) - - - **supervisor** : ``ihatemoney generate-config supervisord.conf`` (mind the - ``command=`` line) - - - **apache**: ``ihatemoney generate-config apache-vhost.conf`` (mind the - ``WSGIDaemonProcess``, ``WSGIScriptAlias`` and ``Alias`` lines) -4. Restart *Apache* or *Supervisor*, depending on your setup. - -Upgrade ADMIN_PASSWORD to its hashed form -++++++++++++++++++++++++++++++++++++++++++ - -.. note:: Not required if you are not using the ADMIN_PASSWORD feature. - -``ihatemoney generate_password_hash`` will do the hashing job for you, just put - its result in the ``ADMIN_PASSWORD`` var from your `ihatemoney.cfg` and - restart *apache* or the *supervisor* job. diff --git a/setup.cfg b/setup.cfg index 159cdd6c..f2899d7c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -59,6 +59,7 @@ dev = doc = Sphinx==4.2.0 docutils==0.17.1 + myst-parser [options.entry_points] flask.commands =