From af7d32ce0d59175292925ad10a740c32e9e4e036 Mon Sep 17 00:00:00 2001
From: Art Lukyanchyk <artiom.lukyanchyk@hs-hannover.de>
Date: Sun, 29 Aug 2021 20:42:29 +0200
Subject: [PATCH] Update the documentation

---
 README.md                        | 60 ++++++++++++++++++--------------
 setup.py                         |  4 +--
 ssoauth/app_settings/defaults.py |  7 ++--
 ssoauth/extras/hsh_compat.py     |  2 +-
 4 files changed, 42 insertions(+), 31 deletions(-)

diff --git a/README.md b/README.md
index c02d4f3..650c39d 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,19 @@
-#### Minimal Intro:
+#### ssoauth:
+- Manages users and permissions
+- Authenticates users using SAML2 (Shibboleth)
+- Authorizes users based on groups:
+  - Groups are normally received via SAML2
+  - Groups can also be fetched locally: this is enabled automatically if the `hsh` app is available, skipping multiple software layers for additional security
+- Suppresses direct permission assignment (`django.contrib.auth` `User`<->`Permission`), use groups instead
+
+
+#### Minimal SSO Intro:
 - [SSO](https://lmddgtfy.net/?q=SSO): Single Sign On
 - SLO: Single Log Out
 - SP: Service Provider (your web app)
-- IdP: Identity Provider (server with some dreadful software like Shibboleth)
-- Metadata/Meta: an XML that describes SP or IdP (or some other entity)
-- SAML/SAML2: It's just another XML-based enterprise-grade standard that will make you cry blood and shit bricks
+- IDP: Identity Provider (e.g. Shibboleth)
+- Metadata: an XML that describes SP or IDP (or some other relying party)
+- SAML/SAML2: yet another XML-based enterprise-grade standard that will make you cry blood
 
 
 #### Necessary Stuff
@@ -21,7 +30,7 @@
 #### Development Setup
 
 - Should work with zero additional configuration.
-- You can use `localhost:8000/dev/` _(might change depending on your configuration)_ to access the dev view with all its helper features.
+- You can use `localhost:8000/dev/` _(might change depending on your url configuration)_ to access the dev view with all its helper features.
 
 #### Advanced development setup
 If you are not sure whether you need it: you don't need it.
@@ -49,19 +58,19 @@ There are some apps like `django.contrib.admin` or `wagtail` that will simply ig
 ```python3
 re_path(r"^(?:\w+/)?login/?$", ssoauth_views.LogInView.as_view(already_authenticated_403=True)),
 ```
-  - Adjust the path if required
-  - Optional argument `already_authenticated_403=True` is used to avoid redirect loops (e.g. caused by `django.contrib.admin`). You can also use `already_authenticated_redirect="url-name"`.
+  - Adjust the path if needed
+  - Optional argument `already_authenticated_403=True` is used to avoid redirect loops (e.g. those caused by `django.contrib.admin`). You can also use `already_authenticated_redirect="url-name"`.
 
 
 #### Regarding Logging Out
 
-After logging out locally, user will be redirected to one of the following (with this priority):
+After logging out locally, user will be redirected to one of the following (in this order):
   - `?next=` GET value (Note: instead of `next` use use `django.contrib.auth.REDIRECT_FIELD_NAME`)  
   - `LOGOUT_REDIRECT_URL` (vanilla django setting), recommended values are:
     - `LOGOUT_REDIRECT_URL = None` for the default behavior
     - `LOGOUT_REDIRECT_URL = urls.reverse_lazy("sso-logout-idp")` if you want to instantly initiate IDP log out, possibly triggering SLO
     - `LOGOUT_REDIRECT_URL = urls.reverse_lazy("sso-logged-out-locally")`
-  - Default: redirect to the view that asks users what to do next. Don't forget to override template `ssoauth/logged_out_locally.html`
+  - Default: redirect to the view that asks users what to do next. You might want to override template `ssoauth/logged_out_locally.html`
 
 #### Advanced Logging Out and SLO
 
@@ -69,18 +78,18 @@ If unsure, ignore this section.
 
 **SLO**: SLO/SLS is disabled by default. If you want to try your luck with SLO you should add to your project settings `SP_SLS_ENABLED = True`
 
-Currently only IdP-initiated SLO is supported by this app. The only supported binding type is HTTP-Redirect due to the limitations of the underlying library used.
+Currently only IDP-initiated SLO is supported by this app. The only supported binding type is HTTP-Redirect due to the limitations of the underlying library used.
 
 For SLO with HTTP-Redirect to work, the SLS page must be included as `<iframe>`. Your server and/or browser might restrict such behavior. Start with setting `SP_SLS_X_FRAME_OPTIONS` (check `ssoauth.app_settings.defaults`). 
-If you have `nginx` serving pages to users, you might need to configure `x-frame-options` for the SLS view (Only the SLS view, nowhere else!). Additionally you might need to configure CSP on the web server on the IdP side. Anyways it will most likely be a lot of [fun](https://duckduckgo.com/?q=dwarf+fortress+fun) for you.
+If you have `nginx` serving pages to users, you might need to configure `x-frame-options` for the SLS view (Only the SLS view, nowhere else!). Additionally you might need to configure CSP on the web server on the IDP side. Anyways it will most likely be a lot of [fun](https://duckduckgo.com/?q=dwarf+fortress+fun) for you.
 
 
 #### Groups and Permissions
 
 With `ssoauth` the only way to assign permissions is with groups:
-  - when user logs in, `ssoauth` receives group names from the IDP
-  - if your project has `django.contrib.admin` `Groups` with exactly the same names, as received from the IDP, these groups are assigned to the user.
-  - all other groups and permissions are automatically removed from the user (so it's not possible to "patch" what IDP says with some extra rules in the project)
+  - when user logs in, `ssoauth` receives group names from the IDP, or fetches them from the `hsh` app if it's present
+  - if your project has local groups (`django.contrib.auth` `Group`) with exactly the same names, these groups are assigned to the user
+  - all other groups and permissions are removed from the user for security reasons (better don't workaround this behaviour in your project)
 
 You can predefine some groups in  project settings (see `ssoauth` default config for details). These predefined groups will be created automatically (when migrating). For example, a superuser group:
 
@@ -95,12 +104,12 @@ PREDEFINED_GROUPS = {
 This example might be incomplete. See `ssoauth.app_settings.defaults` for additional info
 
 ```python
-""" settings/prod.py """
+""" settings.py """
 from django import urls
 
 SP_HOST = "foobar.it.hs-hannover.de"  # FQDN of your SP
 IDP_META_URL = "https://idp.hs-hannover.de/idp/shibboleth"  # production
-IDP_LOGOUT_URL = "https://idp.it.hs-hannover.de/idp/profile/Logout"  # web page for IdP logout (might initiate SLO)
+IDP_LOGOUT_URL = "https://idp.it.hs-hannover.de/idp/profile/Logout"  # web page for IDP logout (might initiate SLO)
 
 LOGIN_URL = urls.reverse_lazy("sso-login")  # django setting
 ```
@@ -119,16 +128,16 @@ openssl req -newkey rsa:16384 -x509 -days 3650 -nodes -out sp.pem -keyout sp.key
 - if you prefer your keys somewhere else, set `SP_KEY` and `SP_CERT` settings
 
 
-#### Add an SP to an IdP
+#### Add your SP to an IDP
 
-- Ask for assistance. Seriously.
-- Please try on the test IdP before you brick the production!
-- Grab your meta
-  - Run your project.
-  - Find meta of your SP (relative path `/saml2/meta`)
+- Ask for assistance if not sure
+- The project should be running with production settings
+- Take the metadata of your project:
+  - Run your project
+  - The metadata of your SP is generated and shown on a web page, default path is `/saml2/meta`
   - Use Ctrl+U ("view source") to get the actual XML, otherwise your browser could mess it up
-- IdP:
-  - `SSH` to the IdP and locate the Shibboleth directory, most likely `/opt/shibboleth-idp/`
+- Shibboleth IDP:
+  - `SSH` to the IDP and locate the Shibboleth directory, e.g. `/opt/shibboleth-idp/`
   - put your meta into a new file in `./metadata/` and give it a nice verbose name
   - edit `./conf/metadata-providers.xml`
     - create a new `<MetadataProvider .../>` element, your best guess is to copy an existing line that belongs to some existing Django project
@@ -136,5 +145,4 @@ openssl req -newkey rsa:16384 -x509 -days 3650 -nodes -out sp.pem -keyout sp.key
     - `metadataFile` should point on your new metadata
     - edit `./conf/attribute-filter.xml`
   - `systemctl restart tomcat8`
-  - make sure that IDP works
-    - if IDP does not work, rollback your changes and restart the IDP again
+  - make sure the IDP still works, it can be super picky regarding its config files
diff --git a/setup.py b/setup.py
index d46e7c4..152d069 100644
--- a/setup.py
+++ b/setup.py
@@ -36,5 +36,5 @@ setup(
     ],
 )
 
-# binary dependencies:
-# sudo apt install libxml2-dev libxslt1-dev xmlsec1 libxmlsec1-dev pkg-config
+# debian dependencies:
+# sudo apt install libxml2-dev libxslt1-dev xmlsec1 libxmlsec1-dev pkg-config python3-dev
diff --git a/ssoauth/app_settings/defaults.py b/ssoauth/app_settings/defaults.py
index 4b9aad1..733a7d9 100644
--- a/ssoauth/app_settings/defaults.py
+++ b/ssoauth/app_settings/defaults.py
@@ -3,9 +3,12 @@ from django.conf import settings as django_settings
 
 
 """
-If you want to change something:
+Changing settings in Django:
+  - put the setting it into your project settings
   - optionally prefix the setting with "SSOAUTH_"
-  - put it into your project settings
+Changing settings outside of Django:
+  - import ssoauth.app_settings
+  - ssoauth.app_settings.SETTING_NAME = "your new value"
 """
 
 
diff --git a/ssoauth/extras/hsh_compat.py b/ssoauth/extras/hsh_compat.py
index 87872e3..9daf1fc 100644
--- a/ssoauth/extras/hsh_compat.py
+++ b/ssoauth/extras/hsh_compat.py
@@ -1,5 +1,5 @@
 """
-Compatibility features with the `hsh` app.
+Compatibility features with the `hsh` app
 """
 
 from .. import logger
-- 
GitLab