Merge branch 'docs' into 'master'

Docs

See merge request BeryJu.org/passbook!33
This commit is contained in:
Jens Langhammer 2019-12-12 22:06:20 +00:00
commit 82cf482fba
19 changed files with 479 additions and 12 deletions

View File

@ -49,42 +49,41 @@ build-dev-image:
- tags - tags
- /^version/.*$/ - /^version/.*$/
isort: isort:
script: script:
- isort -c -sg env - isort -c -sg env
stage: test stage: test
services: services:
- postgres:latest - postgres:latest
- redis:latest - redis:latest
migrations: migrations:
script: script:
- python manage.py migrate - python manage.py migrate
stage: test stage: test
services: services:
- postgres:latest - postgres:latest
- redis:latest - redis:latest
prospector: prospector:
script: script:
- prospector - prospector
stage: test stage: test
services: services:
- postgres:latest - postgres:latest
- redis:latest - redis:latest
pylint: pylint:
script: script:
- pylint passbook - pylint passbook
stage: test stage: test
services: services:
- postgres:latest - postgres:latest
- redis:latest - redis:latest
coverage: coverage:
script: script:
- ./scripts/coverage.sh - ./scripts/coverage.sh
stage: test stage: test
services: services:
- postgres:latest - postgres:latest
- redis:latest - redis:latest
build-passbook-server: build-passbook-server:
stage: build stage: build
@ -98,6 +97,18 @@ build-passbook-server:
only: only:
- tags - tags
- /^version/.*$/ - /^version/.*$/
build-docs:
stage: build
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
before_script:
- echo "{\"auths\":{\"docker.beryju.org\":{\"auth\":\"$DOCKER_AUTH\"}}}" > /kaniko/.docker/config.json
script:
- /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/docs/Dockerfile --destination docker.beryju.org/passbook/docs:latest --destination docker.beryju.org/passbook/docs:0.7.4-beta
only:
- tags
- /^version/.*$/
build-passbook-static: build-passbook-static:
stage: build stage: build
image: image:

14
docs/Dockerfile Normal file
View File

@ -0,0 +1,14 @@
FROM python:3.7-slim-buster as builder
WORKDIR /mkdocs
RUN pip install mkdocs mkdocs-material
COPY docs/ docs
COPY mkdocs.yml .
RUN mkdocs build
FROM nginx
COPY --from=builder /mkdocs/site /usr/share/nginx/html

23
docs/factors.md Normal file
View File

@ -0,0 +1,23 @@
# Factors
A factor represents a single authenticating factor for a user. Common examples of this would be a password or an OTP. These factors can be combined in any order, and can be dynamically enabled using policies.
## Password Factor
This is the standard Password Factor. It allows you to select which Backend the password is checked with. here you can also specify which Policies are used to check the password. You can also specify which Factors a User has to pass to recover their account.
## Dummy Factor
This factor waits a random amount of time. Mostly used for debugging.
## E-Mail Factor
This factor is mostly for recovery, and used in conjunction with the Password Factor.
## OTP Factor
This is your typical One-Time Password implementation, compatible with Authy and Google Authenticator. You can enfore this Factor so that every user has to configure it, or leave it optional.
## Captcha Factor
While this factor doesn't really authenticate a user, it is part of the Authentication Flow. passbook uses Google's reCaptcha implementation.

55
docs/images/logo.svg Normal file
View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path style="fill:#57565C;" d="M407,512H105C47.103,512,0,464.897,0,407V105C0,47.103,47.103,0,105,0h302
c57.897,0,105,47.103,105,105v302C512,464.897,464.897,512,407,512z"/>
<path style="fill:#3E3D42;" d="M407,0H256v512h151c57.897,0,105-47.103,105-105V105C512,47.103,464.897,0,407,0z"/>
<rect x="91" y="141" style="fill:#00C3FF;" width="330" height="44"/>
<rect x="256" y="141" style="fill:#00AAF0;" width="165" height="44"/>
<rect x="91" y="176" style="fill:#FFDC40;" width="330" height="44"/>
<rect x="256" y="176" style="fill:#FFAB15;" width="165" height="44"/>
<rect x="91" y="206" style="fill:#87E694;" width="330" height="44"/>
<rect x="256" y="206" style="fill:#66CC70;" width="165" height="44"/>
<path style="fill:#F2F2F2;" d="M421,381c0,8.284-6.716,15-15,15H106c-8.284,0-15-6.716-15-15v-85h89.997
c9.31,0,17.688,4.938,21.868,12.888C213.277,328.695,233.638,341,256,341s42.723-12.305,53.135-32.111
c4.18-7.95,12.559-12.889,21.868-12.889H421V381z"/>
<path style="fill:#FF6849;" d="M421,266h-89.997c-20.487,0-39.041,11.085-48.423,28.929C277.369,304.842,267.185,311,256,311
s-21.369-6.158-26.58-16.071C220.038,277.085,201.484,266,180.997,266H91v-30h330V266z"/>
<path style="fill:#F2F2F2;" d="M421,146H91v-15c0-8.284,6.716-15,15-15h300c8.284,0,15,6.716,15,15V146z"/>
<path style="fill:#E5E5E5;" d="M331.003,296c-9.31,0-17.688,4.938-21.868,12.889C298.723,328.695,278.362,341,256,341v55h150
c8.284,0,15-6.716,15-15v-85H331.003z"/>
<path style="fill:#FD4B2D;" d="M256,236v75c11.185,0,21.369-6.158,26.58-16.071C291.962,277.085,310.516,266,331.003,266H421v-30
H256z"/>
<path style="fill:#E5E5E5;" d="M406,116H256v30h165v-15C421,122.716,414.284,116,406,116z"/>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

31
docs/index.md Executable file
View File

@ -0,0 +1,31 @@
# Welcome
Welcome to the passbook Documentation. passbook is an open-source Identity Provider and Usermanagement software. It can be used as a central directory for users or customers and it can integrate with your existing Directory.
passbook can also be used as part of an Application to facilitate User Enrollment, Password recovery and Social Login.
passbook uses the following Terminology:
### Policy
A Policy is at a base level a yes/no gate. It will either evaluate to True or False depending on the Policy Kind and settings. For example, a "Group Membership Policy" evaluates to True if the User is member of the specified Group and False if not. This can be used to conditionally apply Factors and grant/deny access.
### Provider
A Provider is a way for other Applications to authenticate against passbook. Common Providers are OpenID Connect (OIDC) and SAML.
### Source
Sources are ways to get users into passbook. This might be an LDAP Connection to import Users from Active Directory, or an OAuth2 Connection to allow Social Logins.
### Application
An application links together Policies with a Provider, allowing you to control access. It also holds Information like UI Name, Icon and more.
### Factors
Factors represent Authentication Factors, like a Password or OTP. These Factors can be dynamically enabled using policies. This allows you to, for example, force users from a certain IP ranges to complete a Captcha to authenticate.
### Property Mappings
Property Mappings allow you to make Information available for external Applications. For example, if you want to login to AWS with passbook, you'd use Property Mappings to set the User's Roles based on their Groups.

View File

@ -0,0 +1,26 @@
# docker-compose
This installation Method is for test-setups and small-scale productive setups.
## Prerequisites
- docker
- docker-compose
## Install
Download the latest `docker-compose.yml` from [here](https://git.beryju.org/BeryJu.org/passbook/raw/master/docker-compose.yml). Place it in a directory of your choice.
passbook needs to know it's primary URL to create links in E-Mails and set cookies, so you have to run the following command:
```
export PASSBOOK_DOMAIN=domain.tld # this can be any domain or IP, it just needs to point to passbook.
```
The compose file references the current latest version, which can be overridden with the `SERVER_TAG` Environment variable.
If you plan to use this setup for production, it is also advised to change the PostgreSQL Password by setting `PG_PASS` to a password of your choice.
Now you can pull the Docker images needed by running `docker-compose pull`. After this has finished, run `docker-compose up -d` to start passbook.
passbook will then be reachable on Port 80. You can optionally configure the packaged traefik to use Let's Encrypt for TLS Encryption.

6
docs/installation/install.md Executable file
View File

@ -0,0 +1,6 @@
# Installation
There are two supported ways to install passbook:
- [docker-compose](docker-compose.md) for test- or small productive setups
- [Kubernetes](./kubernetes.md) for larger Productive setups

View File

@ -0,0 +1,3 @@
# Kubernetes
For a mid to high-load Installation, Kubernetes is recommended. passbook is installed using a helm-chart.

View File

@ -0,0 +1,53 @@
# GitLab Integration
GitLab can authenticate against passbook using SAML.
## Preparation
The following placeholders will be used:
- `gitlab.company` is the FQDN of the GitLab Install
- `passbook.company` is the FQDN of the passbook Install
Create an application in passbook and note the slug, as this will be used later. Create a SAML Provider with the following Parameters:
- `ACS URL`: https://gitlab.company/users/auth/saml/callback
- `Audience`: https://gitlab.company
- `Issuer`: https://gitlab.company
You can of course use a custom Signing Certificate, and adjust the Assertion Length. To get the value for `idp_cert_fingerprint`, you can use a tool like [this](https://www.samltool.com/fingerprint.php).
## GitLab Configuration
Paste the following block in your `gitlab.rb` file, after replacing the placeholder values from above. The file is located in `/etc/gitlab`.
```ruby
gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = ['saml']
gitlab_rails['omniauth_sync_email_from_provider'] = 'saml'
gitlab_rails['omniauth_sync_profile_from_provider'] = ['saml']
gitlab_rails['omniauth_sync_profile_attributes'] = ['email']
gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'saml'
gitlab_rails['omniauth_block_auto_created_users'] = false
gitlab_rails['omniauth_auto_link_saml_user'] = true
gitlab_rails['omniauth_providers'] = [
{
name: 'saml',
args: {
assertion_consumer_service_url: 'https://gitlab.company/users/auth/saml/callback',
idp_cert_fingerprint: '4E:1E:CD:67:4A:67:5A:E9:6A:D0:3C:E6:DD:7A:F2:44:2E:76:00:6A',
idp_sso_target_url: 'https://passbook.company/application/saml/<passbook application slug>/login/',
issuer: 'https://gitlab.company',
name_identifier_format: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
attribute_statements: {
email: ['urn:oid:1.3.6.1.4.1.5923.1.1.1.6'],
first_name: ['urn:oid:2.5.4.3'],
nickname: ['urn:oid:2.16.840.1.113730.3.1.241']
}
},
label: 'passbook'
}
]
```
Afterwards, either run `gitlab-ctl reconfigure` if you're running GitLab Omnibus, or restart the container if you're using the container.

33
docs/k8s/deployment.yml Normal file
View File

@ -0,0 +1,33 @@
---
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: passbook-docs
namespace: prod-passbook-docs
labels:
app.kubernetes.io/name: passbook-docs
app.kubernetes.io/managed-by: passbook-docs
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: passbook-docs
template:
metadata:
labels:
app.kubernetes.io/name: passbook-docs
spec:
containers:
- name: passbook-docs
image: "docker.beryju.org/passbook/docs:latest"
ports:
- name: http
containerPort: 80
protocol: TCP
resources:
limits:
cpu: 10m
memory: 20Mi
requests:
cpu: 10m
memory: 20Mi

21
docs/k8s/ingress.yml Normal file
View File

@ -0,0 +1,21 @@
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
labels:
app.kubernetes.io/name: passbook-docs
name: passbook-docs
namespace: prod-passbook-docs
spec:
rules:
- host: docs.passbook.beryju.org
http:
paths:
- backend:
serviceName: passbook-docs-http
servicePort: http
path: /
tls:
- hosts:
- docs.passbook.beryju.org
secretName: passbook-docs-acme

17
docs/k8s/service.yml Normal file
View File

@ -0,0 +1,17 @@
---
apiVersion: v1
kind: Service
metadata:
name: passbook-docs-http
namespace: prod-passbook-docs
labels:
app.kubernetes.io/name: passbook-docs
spec:
type: ClusterIP
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: passbook-docs

68
docs/policies.md Normal file
View File

@ -0,0 +1,68 @@
# Policies
## Kinds
There are two different Kind of policies, a Standard Policy and a Password Policy. Normal Policies just evaluate to True or False, and can be used everywhere. Password Policies apply when a Password is set (during User enrollment, Recovery or anywhere else). These policies can be used to apply Password Rules like length, etc. The can also be used to expire passwords after a certain amount of time.
## Standard Policies
---
### Group-Membership Policy
This policy evaluates to True if the current user is a Member of the selected group.
### Reputation Policy
passbook keeps track of failed login attempts by Source IP and Attempted Username. These values are saved as scores. Each failed login decreases the Score for the Client IP as well as the targeted Username by one.
This policy can be used to for example prompt Clients with a low score to pass a Captcha before they can continue.
### Field matcher Policy
This policy allows you to evaluate arbitrary comparisons against the User instance. Currently supported fields are:
- Username
- E-Mail
- Name
- Is_active
- Date joined
Any of the following operations are supported:
- Starts with
- Ends with
- Contains
- Regexp (standard Python engine)
- Exact
### SSO Policy
This policy evaluates to True if the current Authentication Flow has been initiated through an external Source, like OAuth and SAML.
### Webhook Policy
This policy allows you to send an arbitrary HTTP Request to any URL. You can then use JSONPath to extract the result you need.
## Password Policies
---
### Password Policy
This Policy allows you to specify Password rules, like Length and required Characters.
The following rules can be set:
- Minimum amount of Uppercase Characters
- Minimum amount of Lowercase Characters
- Minimum amount of Symbols Characters
- Minimum Length
- Symbol charset (define which characters are counted as symbols)
### Have I Been Pwned Policy
This Policy checks the hashed Password against the [Have I Been Pwned](https://haveibeenpwned.com/) API. This only sends the first 5 characters of the hashed password. The remaining comparison is done within passbook.
### Password-Expiry Policy
This policy can enforce regular password rotation by expiring set Passwords after a finite amount of time. This forces users to set a new password.

21
docs/property-mappings.md Normal file
View File

@ -0,0 +1,21 @@
# Property Mappings
Property Mappings allow you to pass information to external Applications. For example, pass the current user's Groups as a SAML Parameter. Property Mappings are also used to map Source fields to passbook fields, for example when using LDAP.
## SAML Property Mapping
SAML Property Mappings allow you embed Information into the SAML AuthN Request. THis Information can then be used by the Application to assign permissions for example.
You can find examples [here](integrations/)
## LDAP Property Mapping
LDAP Property Mappings are used when you define a LDAP Source. These Mappings define which LDAP Property maps to which passbook Property. By default, these mappings are created:
- Autogenerated LDAP Mapping: givenName -> first_name
- Autogenerated LDAP Mapping: mail -> email
- Autogenerated LDAP Mapping: name -> name
- Autogenerated LDAP Mapping: sAMAccountName -> username
- Autogenerated LDAP Mapping: sn -> last_name
These are configured for the most common LDAP Setups.

16
docs/providers.md Normal file
View File

@ -0,0 +1,16 @@
# Providers
Providers allow external Applications to authenticate against passbook and use its User Information.
## OpenID Provider
This provider uses the commonly used OpenID Connect variation of OAuth2.
## OAuth2 Provider
This provider is slightly different than the OpenID Provider. While it uses the same basic OAuth2 Protocol, it provides a GitHub-compatible Endpoint. This allows you to integrate Applications, which don't support Custom OpenID Providers.
The API exposes Username, E-Mail, Name and Groups in a GitHub-compatible format.
## SAML Provider
This provider allows you to integrate Enterprise Software using the SAML2 Protocol. It supports signed Requests. This Provider also has [Property Mappings](property-mappings.md#saml-property-mapping), which allows you to expose Vendor-specific Fields.

39
docs/sources.md Normal file
View File

@ -0,0 +1,39 @@
# Sources
Sources allow you to connect passbook to an existing User directory. They can also be used for Social-Login, using external Providers like Facebook, Twitter, etc.
## Generic OAuth Source
**All Integration-specific Sources are documented in the Integrations Section**
This source allows users to enroll themselves with an External OAuth-based Identity Provider. The Generic Provider expects the Endpoint to return OpenID-Connect compatible Information. Vendor specific Implementations have their own OAuth Source.
- Policies: Allow/Forbid Users from linking their Accounts with this Provider
- Request Token URL: This field is used for OAuth v1 Implementations and will be provided by the Provider.
- Authorization URL: This value will be provided by the Provider.
- Access Token URL: This value will be provided by the Provider.
- Profile URL: This URL is called by passbook to retrieve User information upon successful authentication.
- Consumer key/Consumer secret: These values will be provided by the Provider.
## SAML Source
This source allows passbook to act as a SAML Service Provider. Just like the SAML Provider, it supports signed Requests. Vendor specific documentation can be found in the Integrations Section
## LDAP Source
This source allows you to import Users and Groups from an LDAP Server
- Server URI: URI to your LDAP Server/Domain Controller
- Bind CN: CN to bind as, this can also be a UPN in the format of `user@domain.tld`
- Bind password: Password used during the bind process
- Enable Start TLS: Enables StartTLS functionality. To use SSL instead, use port `636`
- Base DN: Base DN used for all LDAP queries
- Addition User DN: Prepended to Base DN for User-queries.
- Addition Group DN: Prepended to Base DN for Group-queries.
- User object filter: Consider Objects matching this filter to be Users.
- Group object filter: Consider Objects matching this filter to be Groups.
- User group membership field: Field which contains Groups of user.
- Object uniqueness field: Field which contains a unique Identifier.
- Sync groups: Enable/disable Group synchronization. Groups are synced in the background every 5 minutes.
- Sync parent group: Optionally set this Group as parent Group for all synced Groups (allows you to, for example, import AD Groups under a root `imported-from-ad` group.)
- Property mappings: Define which LDAP Properties map to which passbook Properties. The default set of Property Mappings is generated for Active Directory. See also [LDAP Property Mappings](property-mappings.md#ldap-property-mapping)

28
mkdocs.yml Normal file
View File

@ -0,0 +1,28 @@
site_name: passbook Docs
site_url: https://docs.passbook.beryju.org
copyright: "Copyright &copy; 2019 - 2020 BeryJu.org"
nav:
- Home: index.md
- Installation:
- Installation: installation/install.md
- docker-compose: installation/docker-compose.md
- Kubernetes: installation/kubernetes.md
- Sources: sources.md
- Providers: providers.md
- Property Mappings: property-mappings.md
- Factors: factors.md
- Policies: policies.md
- Integrations:
- as Provider:
- GitLab: integrations/as-sp/gitlab/index.md
repo_name: "BeryJu.org/passbook"
repo_url: https://git.beryju.org/BeryJu.org/passbook
theme:
name: "material"
logo: "images/logo.svg"
markdown_extensions:
- toc:
permalink: "¶"

View File

@ -1,4 +1,4 @@
"""p2 form helpers""" """passbook form helpers"""
from django import forms from django import forms
from passbook.admin.fields import YAMLField from passbook.admin.fields import YAMLField

View File

@ -25,11 +25,13 @@ def update_score(request, username, amount):
user_score.save() user_score.save()
LOGGER.debug("Updated score", amount=amount, for_user=username) LOGGER.debug("Updated score", amount=amount, for_user=username)
@receiver(user_login_failed) @receiver(user_login_failed)
def handle_failed_login(sender, request, credentials, **kwargs): def handle_failed_login(sender, request, credentials, **kwargs):
"""Lower Score for failed loging attempts""" """Lower Score for failed loging attempts"""
update_score(request, credentials.get('username'), -1) update_score(request, credentials.get('username'), -1)
@receiver(user_logged_in) @receiver(user_logged_in)
def handle_successful_login(sender, request, user, **kwargs): def handle_successful_login(sender, request, user, **kwargs):
"""Raise score for successful attempts""" """Raise score for successful attempts"""