Compare commits

..

292 Commits

Author SHA1 Message Date
34ed0b3594 new release: 0.6.6-beta 2019-10-11 14:33:36 +02:00
f008a3e20c docker(minor): copy requirements-dev.txt from builder image 2019-10-11 14:33:30 +02:00
9de950220f core(minor): small css adjustment 2019-10-11 14:32:19 +02:00
567c90b4c6 new release: 0.6.5-beta 2019-10-11 14:26:20 +02:00
ae19236366 factors/email(minor): fix default timeout being 0, which breaks task 2019-10-11 14:24:58 +02:00
f9babe7089 core(minor): fix timezone warning when cleaning nonces 2019-10-11 14:23:59 +02:00
78c74cd469 Merge branch 'ldap-rewrite' into 'master'
LDAP rewrite

See merge request BeryJu.org/passbook!28
2019-10-11 12:22:39 +00:00
32abb27e61 sources/ldap(minor): fix lint 2019-10-11 13:43:35 +02:00
8478b03892 sources/ldap(major): implement membership sync, add more settings 2019-10-11 13:41:12 +02:00
e972f2b289 Merge branch 'master' into ldap-rewrite 2019-10-11 12:53:56 +02:00
22c4fb1414 sources/ldap(major): add sync_users and sync_groups, rewrite auth_user method 2019-10-11 12:53:48 +02:00
0154def916 root(minor): allow subapps to define CELERY_BEAT_SCHEDULE 2019-10-11 12:47:29 +02:00
fc69b6851d core(minor): tags -> attributes, add attributes to user, add propertymappings to source 2019-10-11 12:47:06 +02:00
44a3c7fa5f Merge branch 'master' into ldap-rewrite 2019-10-11 10:24:12 +02:00
4e6653e299 ldap(major): start rewrite 2019-10-10 17:36:09 +02:00
c782585287 ci(minor): re-enable pylint 2019-10-10 17:22:56 +02:00
7718b3b3b8 deploy(minor): move celerybeat-schedule to /tmp 2019-10-10 17:13:23 +02:00
8ff9e72972 docker(major): use buster instead of stretch, simplify base image, use pyuwsgi for wheels 2019-10-10 17:13:06 +02:00
ef6ef68a39 ci(minor): only keep latest base and dev images 2019-10-10 16:11:18 +02:00
48a04744e0 new release: 0.6.4-beta 2019-10-10 16:09:38 +02:00
6446ca8bb2 Merge branch '19-lockout-prevention' into 'master'
add lockout prevention

See merge request BeryJu.org/passbook!27
2019-10-10 12:37:14 +00:00
b9991465ee recovery(new): add recovery app to create recovery links 2019-10-10 14:05:16 +02:00
3d8242be06 core(minor): add new, optional description field to nonce 2019-10-10 14:04:58 +02:00
ca3bcc565d ui(minor): simplify top navigation 2019-10-10 10:02:48 +02:00
432176ea2f docker(minor): give user a fixed UID, use --chown flag for docker COPY 2019-10-10 09:36:28 +02:00
c1dae0b599 sources/oauth(minor): fix wrong settings reference 2019-10-09 19:46:23 +02:00
e70d3b6286 new release: 0.6.3-beta 2019-10-09 14:44:50 +02:00
17e6bc921b core(minor): fix import order 2019-10-09 14:37:40 +02:00
46111e7cac deploy(minor): downgrade kombu to fix redis error
https://github.com/celery/kombu/issues/1063
2019-10-09 14:32:20 +02:00
3b7e47dbe2 settings(minor): use cached_db for session, use localhost as domain 2019-10-09 14:30:53 +02:00
fff99f0e3d deploy(minor): use SERVER_TAG, fix static container 2019-10-09 14:29:44 +02:00
2e15b24f0a *(minor): switch has_user_settings to return Optional dataclass instead of tuple 2019-10-09 12:47:14 +02:00
088b9592cd core(minor): remove unused code 2019-10-08 15:04:38 +02:00
b1e4e32b83 providers/oidc(minor): correctly create audit entry on authz 2019-10-08 14:34:59 +02:00
d91a852eda factors/email(minor): start rebuilding email integration as factor 2019-10-08 14:30:17 +02:00
171c5b9759 factors/password(minor): remove form from core 2019-10-08 14:23:02 +02:00
64290b2a37 admin(minor): add view to create user 2019-10-08 11:27:19 +02:00
72769b8a0a lib(minor): cleanup default settings 2019-10-08 10:44:44 +02:00
1018309413 helm(minor): cleanup configmap, move secret_key to k8s secret 2019-10-08 10:44:25 +02:00
6d0ecd228e new release: 0.6.2-beta 2019-10-07 21:24:56 +02:00
40a651e66c docker(minor): ensure passbook user can write 2019-10-07 21:23:38 +02:00
a390bb7b59 factors/otp(minor): fix old URLs 2019-10-07 21:23:25 +02:00
245ec65cbb helm(minor): remove default postgres password 2019-10-07 21:23:15 +02:00
17eea4a10c new release: 0.6.1-beta 2019-10-07 18:53:04 +02:00
862fb0f5d2 deploy(minor): deploy more servers with more resources 2019-10-07 18:41:43 +02:00
ec73b53340 providers/saml(minor): fix last wrong urls names 2019-10-07 18:36:09 +02:00
9110f7fee3 helm(minor): fix worker not starting correctly 2019-10-07 17:41:26 +02:00
54cc1fdeef helm(minor): re-add volumes 2019-10-07 17:22:35 +02:00
8f42a7f0b4 new release: 0.6.0-beta 2019-10-07 17:18:19 +02:00
2c221ea819 providers/oauth(minor): fix import order 2019-10-07 17:14:52 +02:00
93e0441b58 helm(minor): don't directly mount configmap 2019-10-07 17:14:08 +02:00
7f1455cb12 helm(minor): disable redis cluster & persistence by default 2019-10-07 17:01:27 +02:00
59fc223a85 factors/captcha(minor): load correct keys 2019-10-07 16:58:06 +02:00
0a6f555c23 otp(minor): disable autocomplete for code input 2019-10-07 16:57:54 +02:00
6a4233d6fd providers/oauth(minor): fix urls not being mounted in the right path 2019-10-07 16:57:36 +02:00
15fa7e9652 ui(minor): merge menus 2019-10-07 16:50:13 +02:00
f2acc154cd *(minor): small refactor 2019-10-07 16:33:48 +02:00
d21ec6c9a5 root(minor): get rid of duplicate settings 2019-10-04 16:09:35 +02:00
43dd858cd5 ci(minor): fix from in dockerfile 2019-10-04 14:04:51 +02:00
34cbf5f702 new release: 0.5.0-beta 2019-10-04 13:55:13 +02:00
3c6e94b6a8 ci(minor): fix path in bumpversion config 2019-10-04 13:55:12 +02:00
1cd149c815 policy(minor): fix linting 2019-10-04 13:49:27 +02:00
4c6f562805 policy(minor): fix deadlock issue 2019-10-04 13:44:26 +02:00
e59c4ec1c7 root(minor): cleanup, remove unused log 2019-10-04 13:43:47 +02:00
1169db7530 docker(minor): move docker-related files into separate folder 2019-10-04 12:45:19 +02:00
1453008796 wsgi(minor): add proper request logging 2019-10-04 12:44:59 +02:00
2209b6d603 deploy(minor): fix robots.txt not being in the right path
fix path matching in docker compose
2019-10-04 12:01:38 +02:00
ccbc0384f9 deploy(minor): remove app-gw, add robots.txt 2019-10-04 11:57:41 +02:00
a48924c896 docker(minor): switch to debian based image so we can use wheels 2019-10-04 11:50:52 +02:00
dc8d8dd2b6 deploy(minor): add docker-compose file for easy testing 2019-10-04 11:50:26 +02:00
afca94ceb8 policy(minor): improve loading of policy subclasses 2019-10-04 10:22:06 +02:00
0b86231a36 *(minor): make better use of structured logging 2019-10-04 10:21:33 +02:00
c0df1f38b8 *(minor): remove __name__ param from get_logger 2019-10-04 10:08:53 +02:00
2b8fed8f4e saml_idp(minor): rewrite to use defusedxml instead of bs4 2019-10-04 09:50:25 +02:00
c7322a32a0 app_gw(minor): remove current implementation 2019-10-04 09:28:28 +02:00
64b75cab84 policy(minor): add data class for policy request 2019-10-03 10:45:31 +02:00
f58bc61999 new release: 0.4.2-beta 2019-10-02 21:05:51 +00:00
fb8ccc0283 lint(minor): fix import order 2019-10-02 21:05:37 +00:00
c38012f147 new release: 0.4.1-beta 2019-10-02 21:04:16 +00:00
3676ff21c2 helm(minor): use postgres 4.2.2 2019-10-02 21:03:39 +00:00
920e705d75 policy(minor): lookup correct policy subclass 2019-10-02 22:28:58 +02:00
de0b137b1e policy(minor): improve error handling 2019-10-02 22:28:39 +02:00
d44ac6e2a3 static(minor): fix build path for static image 2019-10-02 22:16:48 +02:00
71039a4012 helm(minor): fix p2 to passbook 2019-10-02 22:16:32 +02:00
8745ac7932 new release: 0.4.0-beta 2019-10-01 17:01:30 +02:00
7f70048423 ci(minor): disable pylint since its currently broken upstream 2019-10-01 16:53:09 +02:00
97dbfc8885 req(minor): fix dependency issue by downgrading prospector 2019-10-01 15:54:29 +02:00
149ea22a93 k8s(minor): switch to uwsgi 2019-10-01 15:43:06 +02:00
404ed5406d k8s(minor): remove passwords from configmap 2019-10-01 15:42:55 +02:00
b8656858ec k8s(minor): load secrets as env vars 2019-10-01 15:42:14 +02:00
6b0f0e8993 deploy(minor): use 5.x postgresql chart for psql 10.x 2019-10-01 15:33:43 +02:00
aec1ccd88d root(minor): fix redis password not being loaded 2019-10-01 15:30:35 +02:00
bee5c200b6 docker(minor): fix static build failing 2019-10-01 15:30:22 +02:00
9d640efc88 new release: 0.3.0-beta 2019-10-01 13:50:50 +02:00
f0907841dd docker(minor): remove virtualenv from pipenv 2019-10-01 13:50:37 +02:00
2bffc12ef9 ci(minor): fix default settings so CI works 2019-10-01 13:22:38 +02:00
2ff9ec6522 ci(minor): fix not all packages being installed 2019-10-01 11:34:34 +02:00
43a54f5c54 ci(minor): install pipenv before testing 2019-10-01 11:12:59 +02:00
7bff2734aa lint(minor): fix all remaining pylint and prospector errors 2019-10-01 11:08:56 +02:00
84768c0ec6 helm(minor): remove rabbitmq 2019-10-01 10:48:55 +02:00
f4499a5459 *(minor): stdlib logging to structlog 2019-10-01 10:24:10 +02:00
b3aede5bba policy(minor): Move policy-related code to separate package 2019-10-01 10:17:39 +02:00
531ea1c039 build(minor): rename dockerfiles to be detected correctly 2019-09-30 18:05:42 +02:00
c2c5ff6912 config(minor): CONFIG.get -> CONFIG.y 2019-09-30 18:04:04 +02:00
9cddab8fd5 deploy(minor): switch to pipfile 2019-09-10 17:00:13 +02:00
06d15d8a27 new release: 0.2.8-beta 2019-07-22 17:18:07 +02:00
b5c711854b deploy: fix static deployment and static container 2019-07-22 17:17:53 +02:00
4cf6c36f34 new release: 0.2.7-beta 2019-07-22 15:54:34 +02:00
75a6f6c875 deploy: remove old files from bumpversion 2019-07-22 15:54:10 +02:00
62abe3f256 suspicious_policy: fix Request IP lookup 2019-07-22 15:46:41 +02:00
9296c41650 ci: add missing packaging dependency 2019-07-22 15:35:11 +02:00
7fb48fde6d deploy: add static deployment, add resource reservations/limits 2019-07-22 15:22:10 +02:00
174472bb45 all: get rid of individual requirements file, remove version from every module 2019-07-22 15:20:17 +02:00
17575ed921 deploy: rewrite docker files to be more stackable 2019-07-22 15:18:33 +02:00
b1b1a27444 client-packages: now deprecated 2019-07-22 15:17:58 +02:00
f97a5eeefb api: *actually* fix drf dependency issue 2019-07-15 15:05:54 +00:00
10fd96981e new release: 0.2.6-beta 2019-07-15 13:42:18 +00:00
67e3eb549c api: fix wrong django-rest-framework dependency 2019-07-15 13:42:03 +00:00
30a6d1f0b1 new release: 0.2.5-beta 2019-07-15 13:31:04 +00:00
3d1fa9f048 app_gw: Rewrite redirect responses (replace upstream location with server_name) 2019-07-09 15:28:52 +02:00
1d2be6e68b root: fix sentry sending wrong release 2019-07-05 16:00:01 +02:00
c21e343986 oidc_provider: fix error when creating a new provider 2019-07-05 15:59:52 +02:00
ff37ed095c new release: 0.2.4-beta 2019-07-05 15:30:13 +02:00
8623a2c3fc oidc_provider: fix error trying to create RSA Key before migrations are run 2019-07-05 15:27:04 +02:00
23d277eaf1 remove oidc from OAuth2, add dedicated OIDC provider 2019-07-05 15:21:48 +02:00
75ced59451 helm: fix syntax error 2019-07-05 15:21:12 +02:00
bccf424c5e new release: 0.2.3-beta 2019-07-04 16:25:33 +02:00
2f9ae40d20 client-sentry: fix 400 failing upload 2019-07-04 16:25:17 +02:00
11e1eec3fb ci: fix new dependencies not being installed on the fly 2019-07-04 16:21:35 +02:00
765c5633df helm: add appgw to ingress 2019-07-04 16:07:16 +02:00
6344b1aafb helm: add deployment for appgw 2019-07-04 15:25:36 +02:00
ed25801e6e core: revert to cherrypy for main webserver and use daphne only for app_gw 2019-07-04 15:23:05 +02:00
4d0148193f root: migrate to new sentry instance 2019-07-03 17:35:54 +02:00
804ae15c2e new release: 0.2.2-beta 2019-06-25 18:50:41 +02:00
b35a9fad86 Fix linting errors with current build-base image 2019-06-25 18:50:37 +02:00
a4f83bd28a new release: 0.2.1-beta 2019-06-25 18:25:27 +02:00
796f83c3d0 Fix requirements file importing wrong path 2019-06-25 18:24:07 +02:00
2099bbb713 new release: 0.2.0-beta 2019-06-25 18:16:14 +02:00
67beba8f78 Fix wrong URLConf being loaded 2019-06-25 18:11:08 +02:00
a798412e17 separate passbook.core into passbook.root and passbook.core
Move Main Django Project into passbook.root while passbook.core holds core functionality.

passbook.root contains main settings, ASGI & WSGI, celery and URLs.
2019-06-25 18:00:54 +02:00
3b2c2d781f Fix typo 2019-06-25 17:59:51 +02:00
98c844f3d6 improve OIDC compatibility 2019-06-25 17:57:25 +02:00
2645bd0132 new release: 0.1.38-beta 2019-04-29 23:26:18 +02:00
2c4fc56b49 Merge branch '27-rewrite-oauth-client-as-factor' into 'master'
Resolve "Rewrite OAuth Client as Factor"

Closes #27

See merge request BeryJu.org/passbook!14
2019-04-29 21:25:04 +00:00
0ec1468058 remove unused import 2019-04-29 23:22:54 +02:00
5d1a3043b2 create SSOLoginPolicy, which allows factors to be applied when user comes from SSO login
implement SESSIION_IS_SSO_LOGIN for OAuth Client and core MFA
2019-04-29 23:19:37 +02:00
b46958d1f9 send session to task 2019-04-29 23:18:51 +02:00
5daa8d5fe3 fix missing/wrong widget inputs 2019-04-29 23:16:04 +02:00
31846f1d05 Show redirect URL in <pre> element 2019-04-29 22:32:22 +02:00
1fac964b8b increase application close timeout 2019-04-29 22:19:26 +02:00
dfa6ed8ac2 add help to show how SAML Property Mapping substitutes variables 2019-04-29 22:19:13 +02:00
66fe10299e new release: 0.1.37-beta 2019-04-29 21:43:18 +02:00
e0a3ec033f fix IDP-Initiated SAML Login 2019-04-29 21:39:41 +02:00
7033ec0ab9 remove debug print 2019-04-29 21:39:30 +02:00
4004579905 remove nexus_upload command 2019-04-29 21:39:16 +02:00
9fe9e48a5c new release: 0.1.36-beta 2019-04-29 20:57:57 +02:00
595a6c7fe6 remove guardian completely 2019-04-29 20:57:54 +02:00
11b5860d4a new release: 0.1.35-beta 2019-04-29 20:47:32 +02:00
9bdbff4cda fix gitlab-ci using incorrect variables for docker access 2019-04-29 20:42:24 +02:00
e0d597eeac show cache on admin overview, add modal to clear cache, re-add logging to policy 2019-04-29 20:37:44 +02:00
f576985cc9 remove django guardian and check application access via PolicyEngine 2019-04-29 20:07:18 +02:00
22a6aef60b fix wrong import 2019-04-29 20:06:52 +02:00
ec0a6e7854 new release: 0.1.34-beta 2019-04-29 19:22:20 +02:00
6904608e6f fix clicking on administration always loading admin interface 2019-04-29 19:22:14 +02:00
cb3732cb2b filter out connection errors for sentry 2019-04-29 19:16:49 +02:00
57de6cbafc repo cleanup, switch to new docker registry 2019-04-29 17:05:39 +02:00
b1dda764a9 Merge branch 'master' of git.beryju.org:BeryJu.org/passbook
# Conflicts:
#	debian/etc/passbook/config.yml
#	helm/passbook/templates/passbook-configmap.yaml
2019-04-18 11:34:13 +02:00
5ec2102487 Merge branch '39-saml-audience-as-database-field' into 'master'
Resolve "SAML: Audience as Database field"

Closes #39

See merge request BeryJu.org/passbook!25
2019-04-18 09:31:56 +00:00
9f8fb7378a add audience field, switch base processor, better handle processor loading failure 2019-04-18 11:30:21 +02:00
98cd646044 remove unneeded processors 2019-04-18 11:09:12 +02:00
0cba1b4c45 fix SAML RancherProcessor not being loaded by default 2019-04-18 11:01:44 +02:00
53918462b6 new release: 0.1.33-beta 2019-04-18 10:28:12 +02:00
8a7e74b523 better release commit messages 2019-04-18 10:28:09 +02:00
4dc7065e97 prepare 0.1.33 2019-04-18 10:25:22 +02:00
3c93bb9f9f remove included CI file 2019-04-18 10:18:47 +02:00
8143fae2d6 switch to custom CI base image with dependencies installed 2019-04-18 10:15:44 +02:00
3cfe45d3cb fix broken icon for helm chart 2019-04-17 17:53:56 +02:00
8e5c3f2f31 remove unused import 2019-04-17 17:53:45 +02:00
5a3b2fdd49 add Rancher SAML processor 2019-04-17 17:53:15 +02:00
e47b9f0d57 fix SAML Request not being parsed all the time 2019-04-17 17:53:05 +02:00
146dd747f1 fix EntityID being None in SAML Metadata 2019-04-17 17:52:24 +02:00
f2ce56063b bump version: 0.1.31-beta -> 0.1.32-beta 2019-04-17 14:27:41 +02:00
b26f378e4c prepare 0.1.32 2019-04-17 14:27:03 +02:00
9072b836c6 automatically add response_type if not given in OAuth Request 2019-04-17 14:25:51 +02:00
2fa57d064e bump version: 0.1.30-beta -> 0.1.31-beta 2019-04-13 17:58:09 +02:00
146705c60a prepare 0.1.31-beta 2019-04-13 17:58:03 +02:00
5029a99df6 Merge branch '37-guardian' into 'master'
Resolve "Guardian"

Closes #37

See merge request BeryJu.org/passbook!23
2019-04-13 15:56:54 +00:00
e7129d18f6 fix inconsistent migrations 2019-04-13 17:52:11 +02:00
d2bf9f81d6 remove raven middleware 2019-04-13 17:46:51 +02:00
30acf0660b Merge branch 'master' into 37-guardian 2019-04-13 17:43:02 +02:00
dda41af5c8 remove logging to increase speed, add more caching to policy and rewriter 2019-04-13 17:22:03 +02:00
9b5b03647b move actual proxying logic to separate class 2019-04-13 16:05:11 +02:00
940b3eb943 move logging to separate thread 2019-04-13 16:04:48 +02:00
16eb629b71 only enable sentry when not DEBUG 2019-04-11 15:30:42 +02:00
755045b226 try to fix app_gw being null 2019-04-11 15:30:07 +02:00
61478db94e use global urllib Pools 2019-04-11 15:29:35 +02:00
f69f959bdb allow setting authentication_header to empty string (disabling the header) 2019-04-11 15:29:01 +02:00
146edb45d4 bump version: 0.1.29-beta -> 0.1.30-beta 2019-04-11 14:22:34 +02:00
045a802365 don't use context manager in web command 2019-04-11 14:22:32 +02:00
c90d8ddcff bump version: 0.1.28-beta -> 0.1.29-beta 2019-04-11 14:03:08 +02:00
3ff2ec929f prepare 0.1.29 2019-04-11 14:03:05 +02:00
a3ef26b7ad Run collectstatic before coverage, use autoreload on celery worker 2019-04-11 13:54:11 +02:00
19cd1624c1 replace cherrypy with daphne 2019-04-11 13:43:49 +02:00
366ef352c6 switch to whitenoise for static files 2019-04-11 13:43:08 +02:00
a9031a6abc Add libpq-dev dependency so psycopg2 build works 2019-04-11 12:44:26 +02:00
a1a5223b58 bump version: 0.1.27-beta -> 0.1.28-beta 2019-04-11 10:48:31 +02:00
c723b0233f prepare 0.1.28 2019-04-11 10:48:28 +02:00
b369eb28f1 set default log level to warn, fix clean_nonces not working 2019-04-11 10:43:13 +02:00
9b8f390e31 Merge branch '38-websocket-proxying' into 'master'
Resolve "Websocket Proxying"

Closes #38

See merge request BeryJu.org/passbook!24
2019-04-10 20:42:24 +00:00
11630c9a74 switch kubernetes deployment to daphne server 2019-04-10 22:38:25 +02:00
c9ac10f6f6 Implement websocket proxy 2019-04-10 19:03:42 +02:00
04d613cb28 Move code from django-revproxy to app_gw to fix cookie bug 2019-04-10 19:03:22 +02:00
40866f9ecd Choose upstream more cleverly 2019-04-10 18:49:33 +02:00
d8585eb872 trigger autoreload from config files 2019-04-10 18:48:55 +02:00
15aaeda475 remove unused import 2019-04-10 18:47:21 +02:00
8536ef9e23 Add guardian for Application permissions 2019-04-10 18:46:33 +02:00
35b6bb6b3f fix failing CI 2019-04-09 17:26:53 +02:00
eaa573c715 fully remove raven and switch WSGI and logging to sentry_sdk 2019-04-05 16:11:53 +02:00
660972e303 add ability to have non-expiring nonces, clean up expired nonces 2019-04-04 21:49:10 +02:00
a21012bf0c switch from raven to sentry_sdk 2019-04-04 21:48:50 +02:00
8dbafa4bda fix allauth client's formatting 2019-04-04 21:47:28 +02:00
80049413f0 bump version: 0.1.26-beta -> 0.1.27-beta 2019-03-22 14:51:13 +01:00
2739442d4a prepare 0.1.27 2019-03-22 14:51:09 +01:00
c679f0a67c bump version: 0.1.25-beta -> 0.1.26-beta 2019-03-22 12:48:00 +01:00
d9a952dd03 prepare 0.1.26 2019-03-22 12:47:57 +01:00
9a1a0f0aa8 Merge branch '35-better-error-templates' into 'master'
Resolve "Better Error templates"

Closes #35

See merge request BeryJu.org/passbook!20
2019-03-22 11:19:42 +00:00
4d6bb60134 add custom template views 2019-03-22 12:16:30 +01:00
80e6d59382 Merge branch '34-parsed-url-cached' into 'master'
Resolve "InvalidUpstream: Upstream URL scheme must be either 'http' or 'https' (https://ory1-esxi-prod-1.ory1.beryju.org)."

Closes #34

See merge request BeryJu.org/passbook!19
2019-03-22 09:58:44 +00:00
81ac951872 validate upstream in form 2019-03-22 10:55:26 +01:00
f33e553cfd always parse url instead of once 2019-03-22 10:55:04 +01:00
9b0240dc26 bump version: 0.1.24-beta -> 0.1.25-beta 2019-03-21 16:50:00 +01:00
c327310392 prepare 0.1.24-beta release 2019-03-21 16:49:57 +01:00
457375287c Merge branch '30-application-security-gateway' into 'master'
Resolve "Application Security Gateway (Reverse Proxy)"

Closes #30

See merge request BeryJu.org/passbook!17
2019-03-21 15:41:34 +00:00
7e87bfef5b validate server_name in form 2019-03-21 16:36:38 +01:00
a7af5268de Invalidate cache when ApplicationGateway instance is saved 2019-03-21 16:27:37 +01:00
6d916029bb implement actual Rewriting logic 2019-03-21 16:22:07 +01:00
81fdcbadad add compiled regex to RewriteRule 2019-03-21 16:21:51 +01:00
ec1e25fe71 cleanup property_mapping list 2019-03-21 16:21:11 +01:00
b5306e4a94 Redirect to login on reverse proxy 2019-03-21 15:15:01 +01:00
801b8a1e59 prevent ZeroDivisionError 2019-03-21 15:05:04 +01:00
3a52059793 cleanup post-migration mess 2019-03-21 15:02:33 +01:00
10b7d99b37 Merge branch 'master' into 30-application-security-gateway
# Conflicts:
#	passbook/core/policies.py
#	passbook/core/settings.py
2019-03-21 14:58:10 +01:00
6be8d0cbb2 Better handle policy timeouts 2019-03-21 14:53:57 +01:00
5b8e3689ec Check for policies in app_gw 2019-03-21 14:53:47 +01:00
25a5d8f5da Don't use LoginRequired for PermissionDenied View 2019-03-21 14:53:38 +01:00
883d439544 add timeout field to policy to prevent stuck policies 2019-03-21 14:48:51 +01:00
1c3b5889e5 Merge branch '33-cache-policy-results' into 'master'
Resolve "Cache Policy Results"

Closes #33

See merge request BeryJu.org/passbook!18
2019-03-21 10:40:36 +00:00
87012b65e1 add redis as service in CI for unittests 2019-03-21 11:35:40 +01:00
29913773a7 invalidate cache when policy is saved 2019-03-21 11:29:11 +01:00
0bc6a4fed4 explicitly use redis db 2019-03-21 11:28:57 +01:00
4645d8353f utilise cache in PolicyEngine 2019-03-21 11:08:32 +01:00
260c5555fa add redis dependency back in for caching 2019-03-21 11:08:08 +01:00
6f7b917c38 bump version: 0.1.23-beta -> 0.1.24-beta 2019-03-20 23:00:33 +01:00
1456ee6d3e prepare 0.1.24 2019-03-20 23:00:22 +01:00
ae3d3d0295 fix TypeError: can only concatenate list (not "str") to list 2019-03-20 22:50:09 +01:00
c23ceacd0b initial implementation of reverse proxy, using django-revproxy from within a middleware
add new config entry "primary_domain" which is used to set the cookie domain
2019-03-20 22:42:47 +01:00
5155204283 Merge branch '32-automatically-set-owner-field-when-creating-oauth-provider' into 'master'
Resolve "Automatically set owner field when creating OAuth Provider"

Closes #32

See merge request BeryJu.org/passbook!16
2019-03-20 21:20:54 +00:00
5509ec9b0f Merge branch '29-oauth-provider-add-extra-info-button-to-show-urls' into 'master'
Resolve "OAuth Provider: Add extra info button to show URLs"

Closes #29

See merge request BeryJu.org/passbook!15
2019-03-20 21:17:36 +00:00
d6f9b2e47d remove user field from form. Closes #32 2019-03-20 20:09:27 +01:00
67aa4aef11 add modal for OAuth Providers showing the URLs 2019-03-20 20:03:28 +01:00
9e46c8bfec bump version: 0.1.22-beta -> 0.1.23-beta 2019-03-18 20:54:31 +01:00
1eaa9b9733 prepare 0.1.23 2019-03-18 20:54:23 +01:00
ee05834b69 Merge branch '28-openid-connect-discovery' into 'master'
set issuer to root address instead of well-known path

Closes #28

See merge request BeryJu.org/passbook!13
2019-03-18 19:52:13 +00:00
fccc8f4959 set issuer to root address instead of well-known path 2019-03-18 20:42:32 +01:00
c721620f96 Merge branch '28-openid-connect-discovery' into 'master'
Resolve "OpenID Connect Discovery support"

Closes #28

See merge request BeryJu.org/passbook!12
2019-03-18 19:42:08 +00:00
c9f73d718e start implementing openid connect discovery 2019-03-18 20:35:11 +01:00
bfa58be721 bump version: 0.1.21-beta -> 0.1.22-beta 2019-03-14 21:22:15 +01:00
4bb602149e perapre 0.1.22 2019-03-14 21:20:55 +01:00
81ab9092fc Fix OAuth Client's disconnect view having invalid URL names 2019-03-14 21:19:14 +01:00
29d5962c4c add Azure AD Source 2019-03-14 21:18:55 +01:00
5c75339946 point to correct icons 2019-03-14 21:18:13 +01:00
4774d9a46c fix delete form not working 2019-03-14 21:17:41 +01:00
dbe16ba4fd fix layout when on mobile viewport and scrolling 2019-03-14 21:17:28 +01:00
6972cf00a0 move icons to single folder, cleanup 2019-03-14 21:17:07 +01:00
0445be9712 fix missing debug template 2019-03-14 21:16:27 +01:00
89dbdd9585 bump version: 0.1.20-beta -> 0.1.21-beta 2019-03-14 18:08:02 +01:00
da88ce7150 prepare 0.1.21 2019-03-14 18:02:13 +01:00
5f50fcfcf5 detect HTTPS from reverse proxy 2019-03-14 18:01:41 +01:00
96be087221 add request debug view 2019-03-14 18:01:27 +01:00
a53a269a8c bump version: 0.1.19-beta -> 0.1.20-beta 2019-03-13 16:51:43 +01:00
59565a5286 prepare 0.1.20 2019-03-13 16:51:38 +01:00
ae3c092238 add user settings for Sources 2019-03-13 16:49:30 +01:00
e98e5e4e3e fix GitHub Pretend again 2019-03-13 15:52:05 +01:00
d50c7ec8d4 bump version: 0.1.18-beta -> 0.1.19-beta 2019-03-13 15:16:48 +01:00
c0fdf377d1 prepare 0.1.18 2019-03-13 15:14:36 +01:00
70c11c8988 fix GitHub Pretend throwing a 500 error 2019-03-13 15:12:13 +01:00
67b19becc1 fix API Call for sentry-client, add missing template 2019-03-13 14:27:34 +01:00
ae64024ef4 bump version: 0.1.17-beta -> 0.1.18-beta 2019-03-13 11:31:05 +01:00
e6571826cb adjust versions for client packages, auto build client-packages 2019-03-12 17:30:57 +01:00
c621e61978 fix included yaml file 2019-03-12 17:19:13 +01:00
3626fa4b98 add sentry client 2019-03-12 17:18:08 +01:00
01b0eb159a fix Server Error when downloading metadata 2019-03-12 17:08:53 +01:00
503 changed files with 6523 additions and 4685 deletions

View File

@ -1,10 +1,10 @@
[bumpversion]
current_version = 0.1.17-beta
current_version = 0.6.6-beta
tag = True
commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-(?P<release>.*)
serialize = {major}.{minor}.{patch}-{release}
message = bump version: {current_version} -> {new_version}
message = new release: {new_version}
tag_name = version/{new_version}
[bumpversion:part:release]
@ -23,29 +23,5 @@ values =
[bumpversion:file:passbook/__init__.py]
[bumpversion:file:passbook/api/__init__.py]
[bumpversion:file:passbook/core/__init__.py]
[bumpversion:file:passbook/admin/__init__.py]
[bumpversion:file:passbook/captcha_factor/__init__.py]
[bumpversion:file:passbook/oauth_client/__init__.py]
[bumpversion:file:passbook/ldap/__init__.py]
[bumpversion:file:passbook/lib/__init__.py]
[bumpversion:file:passbook/hibp_policy/__init__.py]
[bumpversion:file:passbook/password_expiry_policy/__init__.py]
[bumpversion:file:passbook/saml_idp/__init__.py]
[bumpversion:file:passbook/audit/__init__.py]
[bumpversion:file:passbook/oauth_provider/__init__.py]
[bumpversion:file:passbook/otp/__init__.py]
[bumpversion:file:docker/nginx.conf]

View File

@ -1,12 +1,10 @@
[run]
source = passbook
omit =
env/
*/wsgi.py
manage.py
*/migrations/*
*/apps.py
passbook/management/commands/nexus_upload.py
passbook/management/commands/web.py
passbook/management/commands/worker.py
docs/

View File

@ -2,3 +2,4 @@ env
helm
passbook-ui
static
*.env.yml

View File

@ -9,3 +9,6 @@ insert_final_newline = true
[html]
indent_size = 2
[yaml]
indent_size = 2

1
.gitignore vendored
View File

@ -191,3 +191,4 @@ pip-selfcheck.json
# End of https://www.gitignore.io/api/python,django
/static/
local.env.yml
.vscode/

View File

@ -1,129 +1,135 @@
# Global Variables
before_script:
- "python3 -m pip install -U virtualenv"
- "virtualenv env"
- "source env/bin/activate"
- "pip3 install -U -r requirements-dev.txt"
stages:
- build-base-image
- build-dev-image
- test
- build
- docs
- deploy
image: python:3.6
services:
- postgres:latest
- package
image: docker.beryju.org/passbook/dev:latest
variables:
POSTGRES_DB: passbook
POSTGRES_USER: passbook
POSTGRES_PASSWORD: 'EK-5jnKfjrGRm<77'
POSTGRES_PASSWORD: "EK-5jnKfjrGRm<77"
before_script:
- pip install pipenv
# Ensure all dependencies are installed, even those not included in passbook/dev
# According to pipenv docs, -d outputs all packages, however it actually does not
- pipenv lock -r > requirements-all.txt
- pipenv lock -rd >> requirements-all.txt
- pip install -r requirements-all.txt
create-base-image:
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/base.Dockerfile --destination docker.beryju.org/passbook/base:latest
stage: build-base-image
only:
refs:
- tags
- /^version/.*$/
build-dev-image:
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/dev.Dockerfile --destination docker.beryju.org/passbook/dev:latest
stage: build-dev-image
only:
refs:
- tags
- /^version/.*$/
include:
- /allauth/.gitlab-ci.yml
isort:
script:
- isort -c -sg env
stage: test
services:
- postgres:latest
- redis:latest
migrations:
script:
- python manage.py migrate
stage: test
prospector:
script:
- prospector
stage: test
services:
- postgres:latest
- redis:latest
# prospector:
# script:
# - prospector
# stage: test
# services:
# - postgres:latest
# - redis:latest
pylint:
script:
- pylint passbook
stage: test
services:
- postgres:latest
- redis:latest
coverage:
script:
- coverage run manage.py test
- coverage report
- coverage html
stage: test
bandit:
script:
- bandit -r passbook
stage: test
services:
- postgres:latest
- redis:latest
package-docker:
build-passbook-server:
stage: build
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
before_script:
- echo "{\"auths\":{\"docker.$NEXUS_URL\":{\"auth\":\"$NEXUS_AUTH\"}}}" > /kaniko/.docker/config.json
- echo "{\"auths\":{\"docker.beryju.org\":{\"auth\":\"$DOCKER_AUTH\"}}}" > /kaniko/.docker/config.json
script:
- /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination docker.pkg.beryju.org/passbook:latest --destination docker.pkg.beryju.org/passbook:0.1.17-beta
stage: build
- /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination docker.beryju.org/passbook/server:latest --destination docker.beryju.org/passbook/server:0.6.6-beta
only:
- tags
- /^version/.*$/
package-helm:
build-passbook-static:
stage: build
script:
- curl https://raw.githubusercontent.com/helm/helm/master/scripts/get | bash
- helm init --client-only
- helm package helm/passbook
- ./manage.py nexus_upload --method put --url $NEXUS_URL --auth $NEXUS_AUTH --repo helm *.tgz
only:
- tags
- /^version/.*$/
package-debian:
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
before_script:
- apt update
- apt install -y --no-install-recommends build-essential debhelper devscripts equivs python3 python3-dev python3-pip libsasl2-dev libldap2-dev
- mk-build-deps debian/control
- apt install ./*build-deps*deb -f -y
- python3 -m pip install -U virtualenv pip
- virtualenv env
- source env/bin/activate
- pip3 install -U -r requirements.txt -r requirements-dev.txt
- ./manage.py collectstatic --no-input
image: ubuntu:18.04
- echo "{\"auths\":{\"docker.beryju.org\":{\"auth\":\"$DOCKER_AUTH\"}}}" > /kaniko/.docker/config.json
script:
- debuild -us -uc
- cp ../passbook*.deb .
- ./manage.py nexus_upload --method post --url $NEXUS_URL --auth $NEXUS_AUTH --repo apt passbook*deb
- /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/static.Dockerfile --destination docker.beryju.org/passbook/static:latest --destination docker.beryju.org/passbook/static:0.6.6-beta
only:
- tags
- /^version/.*$/
# running collectstatic fully initialises django, hence we need that databases
services:
- postgres:latest
- redis:latest
package-helm:
image: debian:stretch-slim
stage: package
before_script:
- apt update && apt install -y curl
- curl https://raw.githubusercontent.com/helm/helm/master/scripts/get | bash
script:
- helm init --client-only
- helm dependency update helm/passbook
- helm package helm/passbook
artifacts:
paths:
- passbook*deb
expire_in: 2 days
stage: build
- passbook-*.tgz
expire_in: 1 week
only:
- tags
- /^version/.*$/
# docs:
# stage: docs
# only:
# - master
# - tags
# - /^debian/.*$/
# environment:
# name: docs
# url: "https://passbook.beryju.org/docs/"
# script:
# - apt update
# - apt install -y rsync
# - "mkdir ~/.ssh"
# - "cp .gitlab/known_hosts ~/.ssh/"
# - "pip3 install -U -r requirements-docs.txt"
# - "eval $(ssh-agent -s)"
# - "echo \"${CI_SSH_PRIVATE}\" | ssh-add -"
# - mkdocs build
# - 'rsync -avh --delete web/* "beryjuorg@ory1-web-prod-1.ory1.beryju.org:passbook.beryju.org/"'
# - 'rsync -avh --delete site/* "beryjuorg@ory1-web-prod-1.ory1.beryju.org:passbook.beryju.org/docs/"'
# deploy:
# environment:
# name: production
# url: https://passbook-prod.default.k8s.beryju.org/
# stage: deploy
# only:
# - tags
# - /^version/.*$/
# script:
# - curl https://raw.githubusercontent.com/helm/helm/master/scripts/get | bash
# - helm init
# - helm upgrade passbook-prod helm/passbook --devel
- tags
- /^version/.*$/

View File

@ -3,7 +3,6 @@ test-warnings: true
doc-warnings: false
ignore-paths:
- env
- migrations
- docs
- node_modules

View File

@ -2,9 +2,10 @@
disable=redefined-outer-name,arguments-differ,no-self-use,cyclic-import,fixme,locally-disabled,unpacking-non-sequence,too-many-ancestors,too-many-branches,too-few-public-methods
load-plugins=pylint_django,pylint.extensions.bad_builtin
#,pylint.extensions.docparams
extension-pkg-whitelist=lxml
const-rgx=[a-zA-Z0-9_]{1,40}$
ignored-modules=django-otp
jobs=4
[SIMILARITIES]

View File

@ -1,114 +0,0 @@
# The default ``config.py``
# flake8: noqa
def set_prefs(prefs):
"""This function is called before opening the project"""
# Specify which files and folders to ignore in the project.
# Changes to ignored resources are not added to the history and
# VCSs. Also they are not returned in `Project.get_files()`.
# Note that ``?`` and ``*`` match all characters but slashes.
# '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
# 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
# '.svn': matches 'pkg/.svn' and all of its children
# 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
# 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
'.hg', '.svn', '_svn', '.git', '.tox']
# Specifies which files should be considered python files. It is
# useful when you have scripts inside your project. Only files
# ending with ``.py`` are considered to be python files by
# default.
# prefs['python_files'] = ['*.py']
# Custom source folders: By default rope searches the project
# for finding source folders (folders that should be searched
# for finding modules). You can add paths to that list. Note
# that rope guesses project source folders correctly most of the
# time; use this if you have any problems.
# The folders should be relative to project root and use '/' for
# separating folders regardless of the platform rope is running on.
# 'src/my_source_folder' for instance.
# prefs.add('source_folders', 'src')
# You can extend python path for looking up modules
# prefs.add('python_path', '~/python/')
# Should rope save object information or not.
prefs['save_objectdb'] = True
prefs['compress_objectdb'] = False
# If `True`, rope analyzes each module when it is being saved.
prefs['automatic_soa'] = True
# The depth of calls to follow in static object analysis
prefs['soa_followed_calls'] = 0
# If `False` when running modules or unit tests "dynamic object
# analysis" is turned off. This makes them much faster.
prefs['perform_doa'] = True
# Rope can check the validity of its object DB when running.
prefs['validate_objectdb'] = True
# How many undos to hold?
prefs['max_history_items'] = 32
# Shows whether to save history across sessions.
prefs['save_history'] = True
prefs['compress_history'] = False
# Set the number spaces used for indenting. According to
# :PEP:`8`, it is best to use 4 spaces. Since most of rope's
# unit-tests use 4 spaces it is more reliable, too.
prefs['indent_size'] = 4
# Builtin and c-extension modules that are allowed to be imported
# and inspected by rope.
prefs['extension_modules'] = []
# Add all standard c-extensions to extension_modules list.
prefs['import_dynload_stdmods'] = True
# If `True` modules with syntax errors are considered to be empty.
# The default value is `False`; When `False` syntax errors raise
# `rope.base.exceptions.ModuleSyntaxError` exception.
prefs['ignore_syntax_errors'] = False
# If `True`, rope ignores unresolvable imports. Otherwise, they
# appear in the importing namespace.
prefs['ignore_bad_imports'] = False
# If `True`, rope will insert new module imports as
# `from <package> import <module>` by default.
prefs['prefer_module_from_imports'] = False
# If `True`, rope will transform a comma list of imports into
# multiple separate import statements when organizing
# imports.
prefs['split_imports'] = False
# If `True`, rope will remove all top-level import statements and
# reinsert them at the top of the module when making changes.
prefs['pull_imports_to_top'] = True
# If `True`, rope will sort imports alphabetically by module name instead
# of alphabetically by import statement, with from imports after normal
# imports.
prefs['sort_imports_alphabetically'] = False
# Location of implementation of
# rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general
# case, you don't have to change this value, unless you're an rope expert.
# Change this value to inject you own implementations of interfaces
# listed in module rope.base.oi.type_hinting.providers.interfaces
# For example, you can add you own providers for Django Models, or disable
# the search type-hinting in a class hierarchy, etc.
prefs['type_hinting_factory'] = (
'rope.base.oi.type_hinting.factory.default_type_hinting_factory')
def project_opened(project):
"""This function is called after opening the project"""
# Do whatever you like here!

Binary file not shown.

11
.vscode/settings.json vendored
View File

@ -1,11 +0,0 @@
{
"python.pythonPath": "env/bin/python",
"editor.tabSize": 4,
"[html]": {
"editor.tabSize": 2
},
"cSpell.words": [
"SAML",
"passbook"
]
}

View File

@ -1,34 +1,9 @@
FROM python:3.6-slim-stretch as build
FROM docker.beryju.org/passbook/base:latest
COPY ./passbook/ /app/passbook
COPY ./manage.py /app/
COPY ./requirements.txt /app/
COPY ./docker/uwsgi.ini /app/
WORKDIR /app/
RUN apt-get update && apt-get install build-essential libssl-dev libffi-dev -y && \
mkdir /app/static/ && \
pip install -r requirements.txt && \
pip install psycopg2 && \
./manage.py collectstatic --no-input && \
apt-get remove --purge -y build-essential && \
apt-get autoremove --purge -y
FROM python:3.6-slim-stretch
COPY ./passbook/ /app/passbook
COPY ./manage.py /app/
COPY ./requirements.txt /app/
COPY --from=build /app/static /app/static/
WORKDIR /app/
RUN apt-get update && apt-get install build-essential libssl-dev libffi-dev -y && \
pip install -r requirements.txt && \
pip install psycopg2 && \
adduser --system --home /app/ passbook && \
chown -R passbook /app/ && \
apt-get remove --purge -y build-essential && \
apt-get autoremove --purge -y
USER passbook

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2018 BeryJu.org
Copyright (c) 2019 BeryJu.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

54
Pipfile Normal file
View File

@ -0,0 +1,54 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[packages]
celery = "*"
cherrypy = "*"
defusedxml = "*"
django = "*"
kombu = "==4.5.0"
django-cors-middleware = "*"
django-filters = "*"
django-ipware = "*"
django-model-utils = "*"
django-oauth-toolkit = "*"
django-oidc-provider = "*"
django-otp = "*"
django-recaptcha = "*"
django-redis = "*"
django-rest-framework = "*"
drf-yasg = "*"
ldap3 = "*"
lxml = "*"
markdown = "*"
oauthlib = "*"
packaging = "*"
psycopg2-binary = "*"
pycryptodome = "*"
pyyaml = "*"
qrcode = "*"
requests-oauthlib = "*"
sentry-sdk = "*"
service_identity = "*"
signxml = "*"
urllib3 = {extras = ["secure"],version = "*"}
structlog = "*"
pyuwsgi = "*"
[requires]
python_version = "3.7"
[dev-packages]
coverage = "*"
isort = "*"
pylint = "==2.3.1"
pylint-django = "*"
prospector = "*"
django-debug-toolbar = "*"
bumpversion = "*"
unittest-xml-reporting = "*"
autopep8 = "*"
bandit = "*"
colorama = "*"

1101
Pipfile.lock generated Normal file

File diff suppressed because it is too large Load Diff

11
README.md Normal file
View File

@ -0,0 +1,11 @@
# passbook
## Quick instance
```
export PASSBOOK_DOMAIN=domain.tld
docker-compose pull
docker-compose up -d
docker-compose exec server ./manage.py migrate
docker-compose exec server ./manage.py createsuperuser
```

View File

@ -1,27 +0,0 @@
# Global Variables
before_script:
- cd allauth/
- "python3 -m pip install -U virtualenv"
- "virtualenv env"
- "source env/bin/activate"
- "pip3 install -U -r requirements-dev.txt"
stages:
- test-allauth
image: python:3.6
isort:
script:
- isort -c -sg env
stage: test-allauth
prospector:
script:
- prospector
stage: test-allauth
pylint:
script:
- pylint passbook
stage: test-allauth
bandit:
script:
- bandit -r allauth_passbook
stage: test-allauth

View File

@ -1,35 +0,0 @@
"""passbook provider"""
from allauth.socialaccount.providers.base import ProviderAccount
from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider
class PassbookAccount(ProviderAccount):
"""passbook account"""
def to_str(self):
dflt = super().to_str()
return self.account.extra_data.get('username', dflt)
class PassbookProvider(OAuth2Provider):
"""passbook provider"""
id = 'passbook'
name = 'passbook'
account_class = PassbookAccount
def extract_uid(self, data):
return str(data['sub'])
def extract_common_fields(self, data):
return {
'email': data.get('email'),
'username': data.get('preferred_username'),
'name': data.get('name'),
}
def get_default_scope(self):
return ['openid:userinfo']
provider_classes = [PassbookProvider] # noqa

View File

@ -1,5 +0,0 @@
"""passbook provider"""
from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns
from allauth_passbook.provider import PassbookProvider
urlpatterns = default_urlpatterns(PassbookProvider)

View File

@ -1,37 +0,0 @@
"""passbook adapter"""
import requests
from allauth.socialaccount import app_settings
from allauth.socialaccount.providers.oauth2.views import (OAuth2Adapter,
OAuth2CallbackView,
OAuth2LoginView)
from allauth_passbook.provider import PassbookProvider
class PassbookOAuth2Adapter(OAuth2Adapter):
"""passbook OAuth2 Adapter"""
provider_id = PassbookProvider.id
# pylint: disable=no-member
settings = app_settings.PROVIDERS.get(provider_id, {}) # noqa
provider_base_url = settings.get("PASSBOOK_URL", 'https://id.beryju.org')
access_token_url = '{0}/application/oauth/token/'.format(provider_base_url)
authorize_url = '{0}/application/oauth/authorize/'.format(provider_base_url)
profile_url = '{0}/api/v1/openid/'.format(
provider_base_url)
def complete_login(self, request, app, access_token, **kwargs):
headers = {
'Authorization': 'Bearer {0}'.format(access_token.token),
'Content-Type': 'application/json',
}
extra_data = requests.get(self.profile_url, headers=headers)
return self.get_provider().sociallogin_from_response(
request,
extra_data.json()
)
oauth2_login = OAuth2LoginView.adapter_view(PassbookOAuth2Adapter) # noqa
oauth2_callback = OAuth2CallbackView.adapter_view(PassbookOAuth2Adapter) # noqa

View File

@ -1 +0,0 @@
django-allauth

View File

@ -1,33 +0,0 @@
"""passbook allauth setup.py"""
from setuptools import setup
setup(
name='django-allauth-passbook',
version='1.0.0',
description='passbook support for django-allauth',
# long_description='\n'.join(read_simple('docs/index.md')[2:]),
long_description_content_type='text/markdown',
author='BeryJu.org',
author_email='hello@beryju.org',
packages=['allauth_passbook'],
include_package_data=True,
install_requires=['django-allauth'],
keywords='django allauth passbook',
license='MIT',
classifiers=[
'Intended Audience :: Developers',
'Topic :: Software Development :: Libraries :: Python Modules',
'Environment :: Web Environment',
'Topic :: Internet',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Framework :: Django',
'Framework :: Django :: 1.11',
'Framework :: Django :: 2.0',
'Framework :: Django :: 2.1',
],
)

20
base.Dockerfile Normal file
View File

@ -0,0 +1,20 @@
FROM python:3.7-slim-buster as locker
COPY ./Pipfile /app/
COPY ./Pipfile.lock /app/
WORKDIR /app/
RUN pip install pipenv && \
pipenv lock -r > requirements.txt && \
pipenv lock -rd > requirements-dev.txt
FROM python:3.7-slim-buster
COPY --from=locker /app/requirements.txt /app/
COPY --from=locker /app/requirements-dev.txt /app/
WORKDIR /app/
RUN pip install -r requirements.txt --no-cache-dir && \
adduser --system --no-create-home --uid 1000 --group --home /app passbook

89
debian/changelog vendored
View File

@ -1,89 +0,0 @@
passbook (0.1.17) stable; urgency=medium
* bump version: 0.1.15-beta -> 0.1.16-beta
* remove Application.user_is_authorized
* don't use celery heartbeat, use TCP keepalive instead
* switch to vertical navigation
-- Jens Langhammer <jens.langhammer@beryju.org> Tue, 12 Mar 2019 14:54:27 +0000
passbook (0.1.16) stable; urgency=medium
* Replace redis with RabbitMQ
* updated debian package to suggest RabbitMQ
* update helm chart to require RabbitMQ
* fix invalid default config in debian package
-- Jens Langhammer <jens.langhammer@beryju.org> Mon, 11 Mar 2019 10:28:36 +0000
passbook (0.1.14) stable; urgency=medium
* bump version: 0.1.11-beta -> 0.1.12-beta
* Fix DoesNotExist error when running PolicyEngine against None user
* allow custom email server for helm installs
* fix UserChangePasswordView not requiring Login
-- Jens Langhammer <jens.langhammer@beryju.org> Mon, 11 Mar 2019 10:28:36 +0000
passbook (0.1.12) stable; urgency=medium
* bump version: 0.1.10-beta -> 0.1.11-beta
* rewrite PasswordFactor to use backends setting instead of trying all backends
* install updated helm release from local folder
* disable automatic k8s deployment for now
* fix OAuth Authorization View not requiring authentication
-- Jens Langhammer <jens.langhammer@beryju.org> Mon, 11 Mar 2019 08:50:29 +0000
passbook (0.1.11) stable; urgency=medium
* add group administration
* bump version: 0.1.9-beta -> 0.1.10-beta
* fix helm labels being on deployments and not pods
* automatically deploy after release
* use Django's Admin FilteredSelectMultiple for Group Membership
* always use FilteredSelectMultiple for many-to-many fields
* Add Group Member policy
* add LDAP Group Membership Policy
-- Jens Langhammer <jens.langhammer@beryju.org> Sun, 10 Mar 2019 18:55:31 +0000
passbook (0.1.10) stable; urgency=high
* bump version: 0.1.7-beta -> 0.1.8-beta
* consistently using PolicyEngine
* add more Verbosity to PolicyEngine, rewrite SAML Authorisation check
* slightly refactor Factor View, add more unittests
* add impersonation middleware, add to templates
* bump version: 0.1.8-beta -> 0.1.9-beta
* fix k8s service routing http traffic to workers
* Fix button on policy test page
* better show loading state when testing a policy
-- Jens Langhammer <jens.langhammer@beryju.org> Sun, 10 Mar 2019 14:52:40 +0000
passbook (0.1.7) stable; urgency=medium
* bump version: 0.1.3-beta -> 0.1.4-beta
* implicitly add kubernetes-healthcheck-host in helm configmap
* fix debian build (again)
* add PropertyMapping Model, add Subclass for SAML, test with AWS
* add custom DynamicArrayField to better handle arrays
* format data before inserting it
* bump version: 0.1.4-beta -> 0.1.5-beta
* fix static files missing for debian package
* fix password not getting set on user import
* remove audit's login attempt
* add passing property to PolicyEngine
* fix captcha factor not loading keys from Factor class
* bump version: 0.1.5-beta -> 0.1.6-beta
* fix MATCH_EXACT not working as intended
* Improve access control for saml
-- Jens Langhammer <jens.langhammer@beryju.org> Fri, 08 Mar 2019 20:37:05 +0000
passbook (0.1.4) stable; urgency=medium
* initial debian package release
-- Jens Langhammer <jens.langhammer@beryju.org> Wed, 06 Mar 2019 18:22:41 +0000

1
debian/compat vendored
View File

@ -1 +0,0 @@
10

20
debian/config vendored
View File

@ -1,20 +0,0 @@
#!/bin/sh
# config maintainer script for passbook
set -e
# source debconf stuff
. /usr/share/debconf/confmodule
dbc_first_version=1.0.0
dbc_dbuser=passbook
dbc_dbname=passbook
# source dbconfig-common shell library, and call the hook function
if [ -f /usr/share/dbconfig-common/dpkg/config.pgsql ]; then
. /usr/share/dbconfig-common/dpkg/config.pgsql
dbc_go passbook "$@"
fi
#DEBHELPER#
exit 0

14
debian/control vendored
View File

@ -1,14 +0,0 @@
Source: passbook
Section: admin
Priority: optional
Maintainer: BeryJu.org <support@beryju.org>
Uploaders: Jens Langhammer <jens@beryju.org>, BeryJu.org <support@beryju.org>
Build-Depends: debhelper (>= 10), dh-systemd (>= 1.5), dh-exec, wget, dh-exec, python3 (>= 3.5) | python3.6 | python3.7
Standards-Version: 3.9.6
Package: passbook
Architecture: all
Recommends: mysql-server, rabbitmq-server
Pre-Depends: adduser, libldap2-dev, libsasl2-dev
Depends: python3 (>= 3.5) | python3.6 | python3.7, python3-pip, dbconfig-pgsql | dbconfig-no-thanks, ${misc:Depends}
Description: Authentication Provider/Proxy supporting protocols like SAML, OAuth, LDAP and more.

22
debian/copyright vendored
View File

@ -1,22 +0,0 @@
MIT License
Copyright (c) 2019 BeryJu.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

4
debian/dirs vendored
View File

@ -1,4 +0,0 @@
etc/passbook/
etc/passbook/config.d/
var/log/passbook/
usr/share/passbook/

View File

@ -1,77 +0,0 @@
http:
host: 0.0.0.0
port: 8000
secret_key_file: /etc/passbook/secret_key
log:
level:
console: INFO
file: DEBUG
file: /var/log/passbook/passbook.log
debug: false
secure_proxy_header:
HTTP_X_FORWARDED_PROTO: https
rabbitmq: guest:guest@localhost/passbook
# Error reporting, sends stacktrace to sentry.services.beryju.org
error_report_enabled: true
passbook:
sign_up:
# Enables signup, created users are stored in internal Database and created in LDAP if ldap.create_users is true
enabled: true
password_reset:
# Enable password reset, passwords are reset in internal Database and in LDAP if ldap.reset_password is true
enabled: true
# Verification the user has to provide in order to be able to reset passwords. Can be any combination of `email`, `2fa`, `security_questions`
verification:
- email
# Text used in title, on login page and multiple other places
branding: passbook
login:
# Override URL used for logo
logo_url: null
# Override URL used for Background on Login page
bg_url: null
# Optionally add a subtext, placed below logo on the login page
subtext: null
footer:
links:
# Optionally add links to the footer on the login page
# - name: test
# href: https://test
# Specify which fields can be used to authenticate. Can be any combination of `username` and `email`
uid_fields:
- username
- email
session:
remember_age: 2592000 # 60 * 60 * 24 * 30, one month
# Provider-specific settings
ldap:
# Which field from `uid_fields` maps to which LDAP Attribute
login_field_map:
username: sAMAccountName
email: mail # or userPrincipalName
user_attribute_map:
active_directory:
username: "%(sAMAccountName)s"
email: "%(mail)s"
name: "%(displayName)"
oauth_client:
# List of python packages with sources types to load.
types:
- passbook.oauth_client.source_types.discord
- passbook.oauth_client.source_types.facebook
- passbook.oauth_client.source_types.github
- passbook.oauth_client.source_types.google
- passbook.oauth_client.source_types.reddit
- passbook.oauth_client.source_types.supervisr
- passbook.oauth_client.source_types.twitter
saml_idp:
# List of python packages with provider types to load.
types:
- passbook.saml_idp.processors.generic
- passbook.saml_idp.processors.aws
- passbook.saml_idp.processors.gitlab
- passbook.saml_idp.processors.nextcloud
- passbook.saml_idp.processors.salesforce
- passbook.saml_idp.processors.shibboleth
- passbook.saml_idp.processors.wordpress_orange

2
debian/gbp.conf vendored
View File

@ -1,2 +0,0 @@
[buildpackage]
export-dir=../build-area

8
debian/install vendored
View File

@ -1,8 +0,0 @@
passbook /usr/share/passbook/
static /usr/share/passbook/
manage.py /usr/share/passbook/
passbook.sh /usr/share/passbook/
vendor /usr/share/passbook/
debian/etc/passbook /etc/
debian/templates/database.yml /usr/share/passbook/

View File

@ -1,14 +0,0 @@
[Unit]
Description=passbook - Authentication Provider/Proxy (Background worker)
After=network.target
Requires=network.target
[Service]
User=passbook
Group=passbook
WorkingDirectory=/usr/share/passbook
Type=simple
ExecStart=/usr/share/passbook/passbook.sh worker
[Install]
WantedBy=multi-user.target

View File

@ -1,14 +0,0 @@
[Unit]
Description=passbook - Authentication Provider/Proxy
After=network.target
Requires=network.target
[Service]
User=passbook
Group=passbook
WorkingDirectory=/usr/share/passbook
Type=simple
ExecStart=/usr/share/passbook/passbook.sh web
[Install]
WantedBy=multi-user.target

36
debian/postinst vendored
View File

@ -1,36 +0,0 @@
#!/bin/bash
set -e
. /usr/share/debconf/confmodule
. /usr/share/dbconfig-common/dpkg/postinst.pgsql
# you can set the default database encoding to something else
dbc_pgsql_createdb_encoding="UTF8"
dbc_generate_include=template:/etc/passbook/config.d/database.yml
dbc_generate_include_args="-o template_infile=/usr/share/passbook/database.yml"
dbc_go passbook "$@"
if [ -z "`getent group passbook`" ]; then
addgroup --quiet --system passbook
fi
if [ -z "`getent passwd passbook`" ]; then
echo " * Creating user and group passbook..."
adduser --quiet --system --home /usr/share/passbook --shell /bin/false --ingroup passbook --disabled-password --disabled-login --gecos "passbook User" passbook >> /var/log/passbook/passbook.log 2>&1
fi
echo " * Updating binary packages (psycopg2)"
python3 -m pip install --target=/usr/share/passbook/vendor/ --no-cache-dir --upgrade --force-reinstall psycopg2 >> /var/log/passbook/passbook.log 2>&1
if [ ! -f '/etc/passbook/secret_key' ]; then
echo " * Generating Secret Key"
python3 -c 'import random; result = "".join([random.choice("abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)") for i in range(50)]); print(result)' > /etc/passbook/secret_key 2> /dev/null
fi
chown -R passbook: /usr/share/passbook/
chown -R passbook: /etc/passbook/
chown -R passbook: /var/log/passbook/
chmod 440 /etc/passbook/secret_key
echo " * Running Database Migration"
/usr/share/passbook/passbook.sh migrate
echo " * A superuser can be created with this command '/usr/share/passbook/passbook.sh createsuperuser'"
echo " * You should probably also adjust your settings in '/etc/passbook/config.yml'"
#DEBHELPER#

24
debian/postrm vendored
View File

@ -1,24 +0,0 @@
#!/bin/sh
set -e
if [ -f /usr/share/debconf/confmodule ]; then
. /usr/share/debconf/confmodule
fi
if [ -f /usr/share/dbconfig-common/dpkg/postrm.pgsql ]; then
. /usr/share/dbconfig-common/dpkg/postrm.pgsql
dbc_go passbook "$@"
fi
if [ "$1" = "purge" ]; then
if which ucf >/dev/null 2>&1; then
ucf --purge /etc/passbook/config.d/database.yml
ucfr --purge passbook /etc/passbook/config.d/database.yml
fi
rm -rf /etc/passbook/
rm -rf /usr/share/passbook/
fi
#DEBHELPER#

10
debian/prerm vendored
View File

@ -1,10 +0,0 @@
#!/bin/sh
set -e
. /usr/share/debconf/confmodule
. /usr/share/dbconfig-common/dpkg/prerm.pgsql
dbc_go passbook "$@"
#DEBHELPER#

27
debian/rules vendored
View File

@ -1,27 +0,0 @@
#!/usr/bin/make -f
# Uncomment this to turn on verbose mode.
# export DH_VERBOSE=1
%:
dh $@ --with=systemd
build-arch:
python3 -m pip install setuptools
python3 -m pip install --target=vendor/ -r requirements.txt
override_dh_strip:
dh_strip --exclude=psycopg2
override_dh_shlibdeps:
dh_shlibdeps --exclude=psycopg2
override_dh_installinit:
dh_installinit --name=passbook
dh_installinit --name=passbook-worker
dh_systemd_enable --name=passbook
dh_systemd_enable --name=passbook-worker
dh_systemd_start
# override_dh_usrlocal to do nothing
override_dh_usrlocal:

View File

@ -1 +0,0 @@
3.0 (native)

View File

@ -1,8 +0,0 @@
databases:
default:
engine: django.db.backends.postgresql
name: _DBC_DBNAME_
user: _DBC_DBUSER_
password: _DBC_DBPASS_
host: _DBC_DBSERVER_
port: _DBC_DBPORT_

3
dev.Dockerfile Normal file
View File

@ -0,0 +1,3 @@
FROM docker.beryju.org/passbook/base:latest
RUN pip install -r /app/requirements-dev.txt --no-cache-dir

90
docker-compose.yml Normal file
View File

@ -0,0 +1,90 @@
---
version: '3.2'
services:
postgresql:
image: postgres
volumes:
- database:/var/lib/postgresql/data
networks:
- internal
environment:
- POSTGRES_PASSWORD=${PG_PASS:-thisisnotagoodpassword}
- POSTGRES_USER=passbook
- POSTGRES_DB=passbook
labels:
- traefik.enable=false
redis:
image: redis
networks:
- internal
labels:
- traefik.enable=false
server:
build:
context: .
image: docker.beryju.org/passbook/server:${SERVER_TAG:-latest}
command:
- uwsgi
- uwsgi.ini
environment:
- PASSBOOK_DOMAIN=${PASSBOOK_DOMAIN}
- PASSBOOK_REDIS__HOST=redis
- PASSBOOK_POSTGRESQL__HOST=postgresql
- PASSBOOK_POSTGRESQL__PASSWORD=${PG_PASS:-thisisnotagoodpassword}
ports:
- 8000
networks:
- internal
labels:
- traefik.port=8000
- traefik.docker.network=internal
- traefik.frontend.rule=PathPrefix:/
worker:
image: docker.beryju.org/passbook/server:${SERVER_TAG:-latest}
command:
- celery
- worker
- --autoscale=10,3
- -E
- -B
- -A=passbook.root.celery
- -s=/tmp/celerybeat-schedule
networks:
- internal
labels:
- traefik.enable=false
environment:
- PASSBOOK_DOMAIN=${PASSBOOK_DOMAIN}
- PASSBOOK_REDIS__HOST=redis
- PASSBOOK_POSTGRESQL__HOST=postgresql
- PASSBOOK_POSTGRESQL__PASSWORD=${PG_PASS:-thisisnotagoodpassword}
static:
build:
context: .
dockerfile: static.Dockerfile
image: docker.beryju.org/passbook/static:latest
networks:
- internal
labels:
- traefik.frontend.rule=PathPrefix:/static, /robots.txt
- traefik.port=80
- traefik.docker.network=internal
traefik:
image: traefik:1.7
command: --api --docker
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "0.0.0.0:80:80"
- "0.0.0.0:443:443"
- "0.0.0.0:8080:8080"
networks:
- internal
volumes:
database:
driver: local
networks:
internal: {}

66
docker/nginx.conf Normal file
View File

@ -0,0 +1,66 @@
user nginx;
worker_processes 1;
error_log stderr warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format json_combined escape=json
'{'
'"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request":"$request",'
'"status": "$status",'
'"body_bytes_sent":"$body_bytes_sent",'
'"request_time":"$request_time",'
'"http_referrer":"$http_referer",'
'"http_user_agent":"$http_user_agent"'
'}';
access_log /dev/stdout json_combined;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
server {
server_name _;
gzip on;
gzip_types application/javascript image/* text/css;
gunzip on;
add_header X-passbook-Version 0.6.6-beta;
add_header Vary X-passbook-Version;
root /data/;
location /_/healthz {
return 204;
}
location ~* \.(jpg|jpeg|png|gif|ico)$ {
expires 30d;
}
location ~* \.(css|js)$ {
expires 7d;
}
}
server {
listen 8080;
location = /stub_status {
stub_status;
}
}
}

10
docker/uwsgi.ini Normal file
View File

@ -0,0 +1,10 @@
[uwsgi]
http = 0.0.0.0:8000
chdir = /app
wsgi-file = passbook/root/wsgi.py
processes = 2
master = true
threads = 2
enable-threads = true
uid = passbook
gid = passbook

9
helm/passbook/Chart.lock Normal file
View File

@ -0,0 +1,9 @@
dependencies:
- name: postgresql
repository: https://kubernetes-charts.storage.googleapis.com/
version: 6.3.10
- name: redis
repository: https://kubernetes-charts.storage.googleapis.com/
version: 9.2.1
digest: sha256:bdde250e1401dccdd5161e39c807f9e88b05e3e8e72e74df767a1bbb5fc39a4a
generated: "2019-10-01T10:46:06.542706+02:00"

View File

@ -1,6 +1,6 @@
apiVersion: v1
appVersion: "0.1.17-beta"
appVersion: "0.6.6-beta"
description: A Helm chart for passbook.
name: passbook
version: "0.1.17-beta"
icon: https://passbook.beryju.org/images/logo.png
version: "0.6.6-beta"
icon: https://git.beryju.org/uploads/-/system/project/avatar/108/logo.png

Binary file not shown.

Binary file not shown.

View File

@ -1,9 +1,9 @@
dependencies:
- name: rabbitmq
repository: https://kubernetes-charts.storage.googleapis.com/
version: 4.3.2
- name: postgresql
repository: https://kubernetes-charts.storage.googleapis.com/
version: 3.10.1
digest: sha256:c36e054785f7d706d7d3f525eb1b167dbc89b42f84da7fc167a18bbb6542c999
generated: 2019-03-11T20:36:35.125079+01:00
version: 4.2.2
- name: redis
repository: https://kubernetes-charts.storage.googleapis.com/
version: 9.2.1
digest: sha256:8782e974a1094eaeecf1d68f093ca4fb84977217b2bd38b09790a05ec289aec2
generated: "2019-10-02T21:03:25.90491153Z"

View File

@ -1,7 +1,7 @@
dependencies:
- name: rabbitmq
version: 4.3.2
repository: https://kubernetes-charts.storage.googleapis.com/
- name: postgresql
version: 3.10.1
version: 4.2.2
repository: https://kubernetes-charts.storage.googleapis.com/
- name: redis
version: 9.2.1
repository: https://kubernetes-charts.storage.googleapis.com/

View File

@ -0,0 +1,16 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "passbook.fullname" . }}-config
data:
config.yml: |
postgresql:
host: "{{ .Release.Name }}-postgresql"
name: "{{ .Values.postgresql.postgresqlDatabase }}"
user: postgres
redis:
host: "{{ .Release.Name }}-redis-master"
cache_db: 0
message_queue_db: 1
error_report_enabled: {{ .Values.config.error_reporting }}
domain: ".{{ .Values.ingress.hosts[0] }}"

View File

@ -1,6 +1,5 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "passbook.fullname" . -}}
{{- $ingressPath := .Values.ingress.path -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
@ -30,9 +29,17 @@ spec:
- host: {{ . | quote }}
http:
paths:
- path: {{ $ingressPath }}
- path: /
backend:
serviceName: {{ $fullName }}
serviceName: {{ $fullName }}-web
servicePort: http
- path: /static/
backend:
serviceName: {{ $fullName }}-static
servicePort: http
- path: /robots.txt
backend:
serviceName: {{ $fullName }}-static
servicePort: http
{{- end }}
{{- end }}

View File

@ -1,139 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "passbook.fullname" . }}-config
data:
config.yml: |
# Env for Docker images
databases:
default:
engine: django.db.backends.postgresql
name: {{ .Values.postgresql.postgresqlDatabase }}
user: postgres
password: {{ .Values.postgresql.postgresqlPassword }}
host: {{ .Release.Name }}-postgresql
port: ''
log:
level:
console: DEBUG
file: DEBUG
file: /dev/null
syslog:
host: 127.0.0.1
port: 514
email:
host: {{ .Values.config.email.host }}
port: 25
user: ''
password: ''
use_tls: false
use_ssl: false
from: passbook <passbook@domain.tld>
web:
listen: 0.0.0.0
port: 8000
threads: 30
debug: false
secure_proxy_header:
HTTP_X_FORWARDED_PROTO: https
rabbitmq: "user:{{ .Values.rabbitmq.rabbitmq.password }}@{{ .Release.Name }}-rabbitmq"
# Error reporting, sends stacktrace to sentry.services.beryju.org
error_report_enabled: {{ .Values.config.error_reporting }}
{{- if .Values.config.secret_key }}
secret_key: {{ .Values.config.secret_key }}
{{- else }}
secret_key: {{ randAlphaNum 50 }}
{{- end }}
domains:
{{- range .Values.ingress.hosts }}
- {{ . | quote }}
{{- end }}
- kubernetes-healthcheck-host
passbook:
sign_up:
# Enables signup, created users are stored in internal Database and created in LDAP if ldap.create_users is true
enabled: true
password_reset:
# Enable password reset, passwords are reset in internal Database and in LDAP if ldap.reset_password is true
enabled: true
# Verification the user has to provide in order to be able to reset passwords. Can be any combination of `email`, `2fa`, `security_questions`
verification:
- email
# Text used in title, on login page and multiple other places
branding: passbook
login:
# Override URL used for logo
logo_url: null
# Override URL used for Background on Login page
bg_url: null
# Optionally add a subtext, placed below logo on the login page
subtext: null
footer:
links:
# Optionally add links to the footer on the login page
# - name: test
# href: https://test
# Specify which fields can be used to authenticate. Can be any combination of `username` and `email`
uid_fields:
- username
- email
session:
remember_age: 2592000 # 60 * 60 * 24 * 30, one month
# Provider-specific settings
ldap:
# # Completely enable or disable LDAP provider
# enabled: false
# # AD Domain, used to generate `userPrincipalName`
# domain: corp.contoso.com
# # Base DN in which passbook should look for users
# base_dn: dn=corp,dn=contoso,dn=com
# # LDAP field which is used to set the django username
# username_field: sAMAccountName
# # LDAP server to connect to, can be set to `<domain_name>`
# server:
# name: corp.contoso.com
# use_tls: false
# # Bind credentials, used for account creation
# bind:
# username: Administraotr@corp.contoso.com
# password: VerySecurePassword!
# Which field from `uid_fields` maps to which LDAP Attribute
login_field_map:
username: sAMAccountName
email: mail # or userPrincipalName
user_attribute_map:
active_directory:
username: "%(sAMAccountName)s"
email: "%(mail)s"
name: "%(displayName)"
# # Create new users in LDAP upon sign-up
# create_users: true
# # Reset LDAP password when user reset their password
# reset_password: true
oauth_client:
# List of python packages with sources types to load.
types:
- passbook.oauth_client.source_types.discord
- passbook.oauth_client.source_types.facebook
- passbook.oauth_client.source_types.github
- passbook.oauth_client.source_types.google
- passbook.oauth_client.source_types.reddit
- passbook.oauth_client.source_types.supervisr
- passbook.oauth_client.source_types.twitter
saml_idp:
signing: true
autosubmit: false
issuer: passbook
assertion_valid_for: 86400
# List of python packages with provider types to load.
types:
- passbook.saml_idp.processors.generic
- passbook.saml_idp.processors.aws
- passbook.saml_idp.processors.gitlab
- passbook.saml_idp.processors.nextcloud
- passbook.saml_idp.processors.salesforce
- passbook.saml_idp.processors.shibboleth
- passbook.saml_idp.processors.wordpress_orange

View File

@ -1,67 +0,0 @@
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: {{ include "passbook.fullname" . }}-web
labels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
helm.sh/chart: {{ include "passbook.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
passbook.io/component: web
spec:
volumes:
- name: config-volume
configMap:
name: {{ include "passbook.fullname" . }}-config
containers:
- name: {{ .Chart.Name }}
image: "docker.pkg.beryju.org/passbook:{{ .Values.image.tag }}"
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c"]
args: ["./manage.py migrate && ./manage.py web"]
ports:
- name: http
containerPort: 8000
protocol: TCP
volumeMounts:
- mountPath: /etc/passbook
name: config-volume
livenessProbe:
httpGet:
path: /
port: http
httpHeaders:
- name: Host
value: kubernetes-healthcheck-host
readinessProbe:
httpGet:
path: /
port: http
httpHeaders:
- name: Host
value: kubernetes-healthcheck-host
resources:
{{ toYaml .Values.resources | indent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}

View File

@ -1,52 +0,0 @@
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: {{ include "passbook.fullname" . }}-worker
labels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
helm.sh/chart: {{ include "passbook.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
passbook.io/component: worker
spec:
volumes:
- name: config-volume
configMap:
name: {{ include "passbook.fullname" . }}-config
containers:
- name: {{ .Chart.Name }}
image: "docker.pkg.beryju.org/passbook:{{ .Values.image.tag }}"
imagePullPolicy: IfNotPresent
command: ["./manage.py", "worker"]
ports:
- name: http
containerPort: 8000
protocol: TCP
volumeMounts:
- mountPath: /etc/passbook
name: config-volume
resources:
{{ toYaml .Values.resources | indent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: {{ include "passbook.fullname" . }}-secret-key
data:
{{- if .Values.config.secret_key }}
secret_key: {{ .Values.config.secret_key | b64enc | quote }}
{{- else }}
secret_key: {{ randAlphaNum 50 | b64enc | quote}}
{{- end }}

View File

@ -0,0 +1,55 @@
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: {{ include "passbook.fullname" . }}-static
labels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
helm.sh/chart: {{ include "passbook.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
selector:
matchLabels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
k8s.passbook.io/component: static
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: '9113'
field.cattle.io/workloadMetrics: '[{"path":"/metrics","port":9113,"schema":"HTTP"}]'
spec:
containers:
- name: {{ .Chart.Name }}-static
image: "docker.beryju.org/passbook/static:{{ .Values.image.tag }}"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
initialDelaySeconds: 10
timeoutSeconds: 5
httpGet:
path: /_/healthz
port: http
readinessProbe:
initialDelaySeconds: 10
timeoutSeconds: 5
httpGet:
path: /_/healthz
port: http
resources:
requests:
cpu: 10m
memory: 10M
limits:
cpu: 20m
memory: 20M
- name: {{ .Chart.Name }}-static-prometheus
image: nginx/nginx-prometheus-exporter:0.4.1
imagePullPolicy: IfNotPresent

View File

@ -0,0 +1,21 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "passbook.fullname" . }}-static
labels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
helm.sh/chart: {{ include "passbook.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
k8s.passbook.io/component: static
spec:
type: ClusterIP
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: {{ include "passbook.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
k8s.passbook.io/component: static

View File

@ -0,0 +1,112 @@
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: {{ include "passbook.fullname" . }}-web
labels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
helm.sh/chart: {{ include "passbook.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
passbook.io/component: web
spec:
volumes:
- name: config-volume
configMap:
name: {{ include "passbook.fullname" . }}-config
initContainers:
- name: passbook-database-migrations
image: "docker.beryju.org/passbook/server:{{ .Values.image.tag }}"
command:
- ./manage.py
args:
- migrate
volumeMounts:
- mountPath: /etc/passbook
name: config-volume
envFrom:
- configMapRef:
name: {{ include "passbook.fullname" . }}-config
prefix: PASSBOOK_
env:
- name: PASSBOOK_SECRET_KEY
valueFrom:
secretKeyRef:
name: {{ include "passbook.fullname" . }}-secret-key
key: secret_key
- name: PASSBOOK_REDIS__PASSWORD
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-redis"
key: redis-password
- name: PASSBOOK_POSTGRESQL__PASSWORD
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-postgresql"
key: postgresql-password
containers:
- name: {{ .Chart.Name }}
image: "docker.beryju.org/passbook/server:{{ .Values.image.tag }}"
imagePullPolicy: IfNotPresent
command:
- uwsgi
args:
- uwsgi.ini
volumeMounts:
- mountPath: /etc/passbook
name: config-volume
envFrom:
- configMapRef:
name: {{ include "passbook.fullname" . }}-config
prefix: PASSBOOK_
env:
- name: PASSBOOK_SECRET_KEY
valueFrom:
secretKeyRef:
name: {{ include "passbook.fullname" . }}-secret-key
key: secret_key
- name: PASSBOOK_REDIS__PASSWORD
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-redis"
key: redis-password
- name: PASSBOOK_POSTGRESQL__PASSWORD
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-postgresql"
key: postgresql-password
ports:
- name: http
containerPort: 8000
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
httpHeaders:
- name: Host
value: kubernetes-healthcheck-host
readinessProbe:
httpGet:
path: /
port: http
httpHeaders:
- name: Host
value: kubernetes-healthcheck-host
resources:
requests:
cpu: 100m
memory: 200M
limits:
cpu: 300m
memory: 350M

View File

@ -1,7 +1,7 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "passbook.fullname" . }}
name: {{ include "passbook.fullname" . }}-web
labels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
helm.sh/chart: {{ include "passbook.chart" . }}

View File

@ -0,0 +1,69 @@
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: {{ include "passbook.fullname" . }}-worker
labels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
helm.sh/chart: {{ include "passbook.chart" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "passbook.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
passbook.io/component: worker
spec:
volumes:
- name: config-volume
configMap:
name: {{ include "passbook.fullname" . }}-config
containers:
- name: {{ .Chart.Name }}
image: "docker.beryju.org/passbook/server:{{ .Values.image.tag }}"
imagePullPolicy: IfNotPresent
command:
- celery
args:
- worker
- --autoscale=10,3
- -E
- -B
- -A=passbook.root.celery
- -s=/tmp/celerybeat-schedule
volumeMounts:
- mountPath: /etc/passbook
name: config-volume
envFrom:
- configMapRef:
name: {{ include "passbook.fullname" . }}-config
prefix: PASSBOOK_
env:
- name: PASSBOOK_SECRET_KEY
valueFrom:
secretKeyRef:
name: {{ include "passbook.fullname" . }}-secret-key
key: secret_key
- name: PASSBOOK_REDIS__PASSWORD
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-redis"
key: redis-password
- name: PASSBOOK_POSTGRESQL__PASSWORD
valueFrom:
secretKeyRef:
name: "{{ .Release.Name }}-postgresql"
key: postgresql-password
resources:
requests:
cpu: 150m
memory: 300M
limits:
cpu: 300m
memory: 500M

View File

@ -1,11 +1,8 @@
# Default values for passbook.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
tag: 0.1.17-beta
tag: 0.6.6-beta
nameOverride: ""
@ -19,11 +16,13 @@ config:
postgresql:
postgresqlDatabase: passbook
postgresqlPassword: foo
rabbitmq:
rabbitmq:
password: foo
redis:
cluster:
enabled: false
master:
persistence:
enabled: false
service:
type: ClusterIP
@ -37,26 +36,7 @@ ingress:
path: /
hosts:
- passbook.k8s.local
defaultHost: passbook.k8s.local
tls: []
# - secretName: chart-example-tls
# hosts:
# - passbook.k8s.local
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}

View File

@ -4,7 +4,7 @@ import os
import sys
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'passbook.core.settings')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'passbook.root.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:

View File

@ -1,7 +0,0 @@
#!/bin/bash
# Check if this file is a symlink, if so, read real base dir
BASE_DIR=$(dirname $(readlink -f ${BASH_SOURCE[0]}))
cd $BASE_DIR
PYTHONPATH="${BASE_DIR}/vendor/" python3 manage.py $@

View File

@ -1,2 +1,2 @@
"""passbook"""
__version__ = '0.1.17-beta'
__version__ = '0.6.6-beta'

View File

@ -1,2 +0,0 @@
"""passbook admin"""
__version__ = '0.1.17-beta'

View File

@ -11,7 +11,7 @@ class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'name', 'email', 'is_staff', 'is_active']
fields = ['username', 'name', 'email', 'is_staff', 'is_active', 'attributes']
widgets = {
'name': forms.TextInput
}

View File

@ -1,2 +0,0 @@
django-rest-framework
drf_yasg

View File

@ -0,0 +1,31 @@
{% extends "administration/base.html" %}
{% load i18n %}
{% load utils %}
{% block title %}
{% title %}
{% endblock %}
{% block content %}
<div class="container">
<h1><span class="pficon-applications"></span> {% trans "Request" %}</h1>
<hr>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>{% trans 'Key' %}</th>
<th>{% trans 'Value' %}</th>
</tr>
</thead>
<tbody>
{% for key, value in request_dict.items %}
<tr>
<td>{{ key }}</td>
<td>{{ value }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

View File

@ -152,10 +152,8 @@
<div class="col-xs-6 col-sm-2 col-md-2">
<div class="card-pf card-pf-accented card-pf-aggregate-status">
<h2 class="card-pf-title">
<a href="#">
<span class="pficon-bundle"></span>
<span class="card-pf-aggregate-status-count"></span> {% trans 'Version' %}
</a>
<span class="pficon-bundle"></span>
<span class="card-pf-aggregate-status-count"></span> {% trans 'Version' %}
</h2>
<div class="card-pf-body">
<p class="card-pf-aggregate-status-notifications">
@ -181,8 +179,8 @@
<span class="card-pf-aggregate-status-notification">
<a href="#">
{% if worker_count < 1%}
<span class="pficon-error-circle-o" data-toggle="tooltip" data-placement="right"
title="{% trans 'No workers connected. Policies will not work and you may expect other issues.' %}"></span> {{ worker_count }}
<span class="pficon-warning-triangle-o" data-toggle="tooltip" data-placement="right"
title="{% trans 'No workers connected.' %}"></span> {{ worker_count }}
{% else %}
<span class="pficon pficon-ok"></span>{{ worker_count }}
{% endif %}
@ -192,5 +190,59 @@
</div>
</div>
</div>
<div class="col-xs-6 col-sm-2 col-md-2">
<div class="card-pf card-pf-accented card-pf-aggregate-status">
<h2 class="card-pf-title">
<span class="pficon-server"></span>
<span class="card-pf-aggregate-status-count"></span> {% trans 'Cached Policies' %}
</h2>
<div class="card-pf-body">
<p class="card-pf-aggregate-status-notifications">
<span class="card-pf-aggregate-status-notification">
<a href="#" data-toggle="modal" data-target="#clearCacheMOdal">
{% if cached_policies < 1 %}
<span class="pficon-warning-triangle-o" data-toggle="tooltip" data-placement="right"
title="{% trans 'No policies cached. Users may experience slow response times.' %}"></span> {{ cached_policies }}
{% else %}
<span class="pficon pficon-ok"></span>{{ cached_policies }}
{% endif %}
</a>
</span>
</p>
</div>
</div>
</div>
</div>
<div class="modal fade" id="clearCacheMOdal" tabindex="-1" role="dialog" aria-labelledby="clearCacheMOdalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
<span class="pficon pficon-close"></span>
</button>
<h4 class="modal-title" id="clearCacheMOdalLabel">{% trans 'Clear Cache' %}</h4>
</div>
<div class="modal-body">
<form method="post" id="clearForm">
{% csrf_token %}
<input type="hidden" name="clear">
<p>
{% blocktrans %}
Are you sure you want to clear the cache? This includes all user sessions and all cached Policy results.
{% endblocktrans %}
</p>
<h3>
{% blocktrans %}
This will also log you out.
{% endblocktrans %}
</h3>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button form="clearForm" type="submit" type="button" class="btn btn-danger">{% trans 'Clear' %}</button>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -36,7 +36,7 @@
<tbody>
{% for property_mapping in object_list %}
<tr>
<td>{{ property_mapping.name }} ({{ property_mapping.slug }})</td>
<td>{{ property_mapping.name }}</td>
<td>{{ property_mapping|verbose_name }}</td>
<td>
<a class="btn btn-default btn-sm"

View File

@ -57,6 +57,10 @@
<a class="btn btn-default btn-sm"
href="{{ href }}?back={{ request.get_full_path }}">{% trans name %}</a>
{% endfor %}
{% get_htmls provider as htmls %}
{% for html in htmls %}
{{ html|safe }}
{% endfor %}
</td>
</tr>
{% endfor %}

View File

@ -36,7 +36,7 @@
<tr>
<td>{{ source.name }}</td>
<td>{{ source|fieldtype }}</td>
<td>{{ source.additional_info }}</td>
<td>{{ source.additional_info|safe }}</td>
<td>
<a class="btn btn-default btn-sm"
href="{% url 'passbook_admin:source-update' pk=source.uuid %}?back={{ request.get_full_path }}">{% trans 'Edit' %}</a>

View File

@ -7,6 +7,10 @@
<div class="container">
<h1><span class="pficon-users"></span> {% trans "Users" %}</h1>
<hr>
<a href="{% url 'passbook_admin:user-create' %}?back={{ request.get_full_path }}" class="btn btn-primary">
{% trans 'Create...' %}
</a>
<hr>
<table class="table table-striped table-bordered">
<thead>
<tr>

View File

@ -1,12 +1,14 @@
"""passbook admin templatetags"""
import inspect
from logging import getLogger
from django import template
from django.db.models import Model
from structlog import get_logger
from passbook.lib.utils.template import render_to_string
register = template.Library()
LOGGER = getLogger(__name__)
LOGGER = get_logger()
@register.simple_tag()
def get_links(model_instance):
@ -29,3 +31,24 @@ def get_links(model_instance):
pass
return links
@register.simple_tag(takes_context=True)
def get_htmls(context, model_instance):
"""Find all html_ methods on an object instance, run them and return as dict"""
prefix = 'html_'
htmls = []
if not isinstance(model_instance, Model):
LOGGER.warning("Model %s is not instance of Model", model_instance)
return htmls
try:
for name, method in inspect.getmembers(model_instance, predicate=inspect.ismethod):
if name.startswith(prefix):
template, _context = method(context.get('request'))
htmls.append(render_to_string(template, _context))
except NotImplementedError:
pass
return htmls

View File

@ -1,7 +1,7 @@
"""passbook URL Configuration"""
from django.urls import include, path
from passbook.admin.views import (applications, audit, factors, groups,
from passbook.admin.views import (applications, audit, debug, factors, groups,
invitations, overview, policy,
property_mapping, providers, sources, users)
@ -61,6 +61,7 @@ urlpatterns = [
# Users
path('users/', users.UserListView.as_view(),
name='users'),
path('users/create/', users.UserCreateView.as_view(), name='user-create'),
path('users/<int:pk>/update/',
users.UserUpdateView.as_view(), name='user-update'),
path('users/<int:pk>/delete/',
@ -77,5 +78,7 @@ urlpatterns = [
# Groups
path('groups/', groups.GroupListView.as_view(), name='groups'),
# API
path('api/', include('passbook.admin.api.urls'))
path('api/', include('passbook.admin.api.urls')),
# Debug
path('debug/request/', debug.DebugRequestView.as_view(), name='debug-request'),
]

View File

@ -0,0 +1,17 @@
"""passbook administration debug views"""
from django.views.generic import TemplateView
from passbook.admin.mixins import AdminRequiredMixin
class DebugRequestView(AdminRequiredMixin, TemplateView):
"""Show debug info about request"""
template_name = 'administration/debug/request.html'
def get_context_data(self, **kwargs):
kwargs['request_dict'] = {}
for key in dir(self.request):
kwargs['request_dict'][key] = getattr(self.request, key)
return super().get_context_data(**kwargs)

View File

@ -1,11 +1,13 @@
"""passbook administration overview"""
from django.core.cache import cache
from django.shortcuts import redirect, reverse
from django.views.generic import TemplateView
from passbook import __version__
from passbook.admin.mixins import AdminRequiredMixin
from passbook.core import __version__
from passbook.core.celery import CELERY_APP
from passbook.core.models import (Application, Factor, Invitation, Policy,
Provider, Source, User)
from passbook.root.celery import CELERY_APP
class AdministrationOverviewView(AdminRequiredMixin, TemplateView):
@ -13,6 +15,13 @@ class AdministrationOverviewView(AdminRequiredMixin, TemplateView):
template_name = 'administration/overview.html'
def post(self, *args, **kwargs):
"""Handle post (clear cache from modal)"""
if 'clear' in self.request.POST:
cache.clear()
return redirect(reverse('passbook_core:auth-login'))
return self.get(*args, **kwargs)
def get_context_data(self, **kwargs):
kwargs['application_count'] = len(Application.objects.all())
kwargs['policy_count'] = len(Policy.objects.all())
@ -25,4 +34,5 @@ class AdministrationOverviewView(AdminRequiredMixin, TemplateView):
kwargs['worker_count'] = len(CELERY_APP.control.ping(timeout=0.5))
kwargs['providers_without_application'] = Provider.objects.filter(application=None)
kwargs['policies_without_attachment'] = len(Policy.objects.filter(policymodel__isnull=True))
kwargs['cached_policies'] = len(cache.keys('policy_*'))
return super().get_context_data(**kwargs)

View File

@ -11,8 +11,8 @@ from django.views.generic.detail import DetailView
from passbook.admin.forms.policies import PolicyTestForm
from passbook.admin.mixins import AdminRequiredMixin
from passbook.core.models import Policy
from passbook.core.policies import PolicyEngine
from passbook.lib.utils.reflection import path_to_class
from passbook.policies.engine import PolicyEngine
class PolicyListView(AdminRequiredMixin, ListView):

View File

@ -5,7 +5,7 @@ from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse, reverse_lazy
from django.utils.translation import ugettext as _
from django.views import View
from django.views.generic import DeleteView, ListView, UpdateView
from django.views.generic import CreateView, DeleteView, ListView, UpdateView
from passbook.admin.forms.users import UserForm
from passbook.admin.mixins import AdminRequiredMixin
@ -19,6 +19,17 @@ class UserListView(AdminRequiredMixin, ListView):
template_name = 'administration/user/list.html'
class UserCreateView(SuccessMessageMixin, AdminRequiredMixin, CreateView):
"""Create user"""
model = User
form_class = UserForm
template_name = 'generic/create.html'
success_url = reverse_lazy('passbook_admin:users')
success_message = _('Successfully created User')
class UserUpdateView(SuccessMessageMixin, AdminRequiredMixin, UpdateView):
"""Update user"""

View File

@ -1,2 +0,0 @@
"""passbook api"""
__version__ = '0.1.17-beta'

View File

@ -1,3 +0,0 @@
django-rest-framework
drf_yasg
django-filters

View File

@ -1,2 +0,0 @@
"""passbook audit Header"""
__version__ = '0.1.17-beta'

View File

@ -1,7 +1,8 @@
# Generated by Django 2.1.7 on 2019-02-16 09:13
# Generated by Django 2.2.6 on 2019-10-07 14:07
import uuid
import django.contrib.postgres.fields.jsonb
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
@ -23,7 +24,7 @@ class Migration(migrations.Migration):
('action', models.TextField(choices=[('login', 'login'), ('login_failed', 'login_failed'), ('logout', 'logout'), ('authorize_application', 'authorize_application'), ('suspicious_request', 'suspicious_request'), ('sign_up', 'sign_up'), ('password_reset', 'password_reset'), ('invitation_created', 'invitation_created'), ('invitation_used', 'invitation_used')])),
('date', models.DateTimeField(auto_now_add=True)),
('app', models.TextField()),
('_context', models.TextField()),
('context', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict)),
('request_ip', models.GenericIPAddressField()),
('created', models.DateTimeField(auto_now_add=True)),
('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
@ -33,19 +34,4 @@ class Migration(migrations.Migration):
'verbose_name_plural': 'Audit Entries',
},
),
migrations.CreateModel(
name='LoginAttempt',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateField(auto_now_add=True)),
('last_updated', models.DateTimeField(auto_now=True)),
('target_uid', models.CharField(max_length=254)),
('request_ip', models.GenericIPAddressField()),
('attempts', models.IntegerField(default=1)),
],
),
migrations.AlterUniqueTogether(
name='loginattempt',
unique_together={('target_uid', 'request_ip', 'created')},
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 2.1.7 on 2019-02-21 12:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('passbook_audit', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='loginattempt',
name='created',
field=models.DateTimeField(auto_now_add=True),
),
]

View File

@ -1,23 +0,0 @@
# Generated by Django 2.1.7 on 2019-02-21 12:40
import django.contrib.postgres.fields.jsonb
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('passbook_audit', '0002_auto_20190221_1201'),
]
operations = [
migrations.RemoveField(
model_name='auditentry',
name='_context',
),
migrations.AddField(
model_name='auditentry',
name='context',
field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict),
),
]

View File

@ -1,16 +0,0 @@
# Generated by Django 2.1.7 on 2019-03-08 14:53
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('passbook_audit', '0003_auto_20190221_1240'),
]
operations = [
migrations.DeleteModel(
name='LoginAttempt',
),
]

View File

@ -1,6 +1,4 @@
"""passbook audit models"""
from logging import getLogger
from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from django.contrib.postgres.fields import JSONField
@ -8,10 +6,11 @@ from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import gettext as _
from ipware import get_client_ip
from structlog import get_logger
from passbook.lib.models import UUIDModel
LOGGER = getLogger(__name__)
LOGGER = get_logger()
class AuditEntry(UUIDModel):
"""An individual audit log entry"""
@ -22,7 +21,7 @@ class AuditEntry(UUIDModel):
ACTION_AUTHORIZE_APPLICATION = 'authorize_application'
ACTION_SUSPICIOUS_REQUEST = 'suspicious_request'
ACTION_SIGN_UP = 'sign_up'
ACTION_PASSWORD_RESET = 'password_reset' # noqa
ACTION_PASSWORD_RESET = 'password_reset' # noqa # nosec
ACTION_INVITE_CREATED = 'invitation_created'
ACTION_INVITE_USED = 'invitation_used'
ACTIONS = (
@ -61,7 +60,8 @@ class AuditEntry(UUIDModel):
# User 255.255.255.255 as fallback if IP cannot be determined
request_ip=client_ip or '255.255.255.255',
context=kwargs)
LOGGER.debug("Logged %s from %s (%s)", action, user, client_ip)
LOGGER.debug("Created Audit entry", action=action,
user=user, from_ip=client_ip, context=kwargs)
return entry
def save(self, *args, **kwargs):

View File

@ -1,2 +0,0 @@
"""passbook captcha_factor Header"""
__version__ = '0.1.17-beta'

View File

@ -1,10 +0,0 @@
"""passbook captcha app"""
from django.apps import AppConfig
class PassbookCaptchaFactorConfig(AppConfig):
"""passbook captcha app"""
name = 'passbook.captcha_factor'
label = 'passbook_captcha_factor'
verbose_name = 'passbook Captcha'

View File

@ -1 +0,0 @@
django-recaptcha

View File

@ -1,2 +0,0 @@
"""passbook core"""
__version__ = '0.1.17-beta'

View File

@ -1,12 +1,6 @@
"""passbook core app config"""
from importlib import import_module
from logging import getLogger
from django.apps import AppConfig
from passbook.lib.config import CONFIG
LOGGER = getLogger(__name__)
class PassbookCoreConfig(AppConfig):
"""passbook core app config"""
@ -14,13 +8,4 @@ class PassbookCoreConfig(AppConfig):
name = 'passbook.core'
label = 'passbook_core'
verbose_name = 'passbook Core'
def ready(self):
import_module('passbook.core.policies')
factors_to_load = CONFIG.y('passbook.factors', [])
for factors_to_load in factors_to_load:
try:
import_module(factors_to_load)
LOGGER.info("Loaded %s", factors_to_load)
except ImportError as exc:
LOGGER.debug(exc)
mountpoint = ''

View File

@ -1,72 +0,0 @@
"""passbook core celery"""
import logging
import os
import celery
from django.conf import settings
from raven import Client
from raven.contrib.celery import register_logger_signal, register_signal
# set the default Django settings module for the 'celery' program.
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "passbook.core.settings")
LOGGER = logging.getLogger(__name__)
class Celery(celery.Celery):
"""Custom Celery class with Raven configured"""
# pylint: disable=method-hidden
def on_configure(self):
"""Update raven client"""
try:
client = Client(settings.RAVEN_CONFIG.get('dsn'))
# register a custom filter to filter out duplicate logs
register_logger_signal(client)
# hook into the Celery error handler
register_signal(client)
except RecursionError: # This error happens when pdoc is running
pass
# pylint: disable=unused-argument
@celery.signals.setup_logging.connect
def config_loggers(*args, **kwags):
"""Apply logging settings from settings.py to celery"""
logging.config.dictConfig(settings.LOGGING)
# pylint: disable=unused-argument
@celery.signals.after_task_publish.connect
def after_task_publish(sender=None, headers=None, body=None, **kwargs):
"""Log task_id after it was published"""
info = headers if 'task' in headers else body
LOGGER.debug('%-40s published (name=%s)', info.get('id'), info.get('task'))
# pylint: disable=unused-argument
@celery.signals.task_prerun.connect
def task_prerun(task_id, task, *args, **kwargs):
"""Log task_id on worker"""
LOGGER.debug('%-40s started (name=%s)', task_id, task.__name__)
# pylint: disable=unused-argument
@celery.signals.task_postrun.connect
def task_postrun(task_id, task, *args, retval=None, state=None, **kwargs):
"""Log task_id on worker"""
LOGGER.debug('%-40s finished (name=%s, state=%s)',
task_id, task.__name__, state)
CELERY_APP = Celery('passbook')
# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
CELERY_APP.config_from_object(settings, namespace='CELERY')
# Load task modules from all registered Django app configs.
CELERY_APP.autodiscover_tasks()

View File

@ -16,7 +16,7 @@ class ApplicationForm(forms.ModelForm):
model = Application
fields = ['name', 'slug', 'launch_url', 'icon_url',
'policies', 'provider', 'skip_authorization']
'provider', 'policies', 'skip_authorization']
widgets = {
'name': forms.TextInput(),
'launch_url': forms.TextInput(),

View File

@ -1,16 +1,15 @@
"""passbook core authentication forms"""
from logging import getLogger
from django import forms
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from django.utils.translation import gettext_lazy as _
from structlog import get_logger
from passbook.core.models import User
from passbook.lib.config import CONFIG
from passbook.lib.utils.ui import human_list
LOGGER = getLogger(__name__)
LOGGER = get_logger()
class LoginForm(forms.Form):
"""Allow users to login"""
@ -82,13 +81,3 @@ class SignUpForm(forms.Form):
if password != password_repeat:
raise ValidationError(_("Passwords don't match"))
return self.cleaned_data.get('password_repeat')
class PasswordFactorForm(forms.Form):
"""Password authentication form"""
password = forms.CharField(widget=forms.PasswordInput(attrs={
'placeholder': _('Password'),
'autofocus': 'autofocus',
'autocomplete': 'current-password'
}))

View File

@ -26,7 +26,7 @@ class GroupForm(forms.ModelForm):
class Meta:
model = Group
fields = ['name', 'parent', 'members', 'tags']
fields = ['name', 'parent', 'members', 'attributes']
widgets = {
'name': forms.TextInput(),
}

View File

@ -3,40 +3,8 @@
from django import forms
from django.utils.translation import gettext as _
from passbook.core.models import (DebugPolicy, FieldMatcherPolicy,
GroupMembershipPolicy, PasswordPolicy,
WebhookPolicy)
GENERAL_FIELDS = ['name', 'action', 'negate', 'order', ]
class FieldMatcherPolicyForm(forms.ModelForm):
"""FieldMatcherPolicy Form"""
class Meta:
model = FieldMatcherPolicy
fields = GENERAL_FIELDS + ['user_field', 'match_action', 'value', ]
widgets = {
'name': forms.TextInput(),
'value': forms.TextInput(),
}
class WebhookPolicyForm(forms.ModelForm):
"""WebhookPolicyForm Form"""
class Meta:
model = WebhookPolicy
fields = GENERAL_FIELDS + ['url', 'method', 'json_body', 'json_headers',
'result_jsonpath', 'result_json_value', ]
widgets = {
'name': forms.TextInput(),
'json_body': forms.TextInput(),
'json_headers': forms.TextInput(),
'result_jsonpath': forms.TextInput(),
'result_json_value': forms.TextInput(),
}
from passbook.core.models import DebugPolicy
from passbook.policies.forms import GENERAL_FIELDS
class DebugPolicyForm(forms.ModelForm):
@ -52,36 +20,3 @@ class DebugPolicyForm(forms.ModelForm):
labels = {
'result': _('Allow user')
}
class GroupMembershipPolicyForm(forms.ModelForm):
"""GroupMembershipPolicy Form"""
class Meta:
model = GroupMembershipPolicy
fields = GENERAL_FIELDS + ['group', ]
widgets = {
'name': forms.TextInput(),
}
class PasswordPolicyForm(forms.ModelForm):
"""PasswordPolicy Form"""
class Meta:
model = PasswordPolicy
fields = GENERAL_FIELDS + ['amount_uppercase', 'amount_lowercase',
'amount_symbols', 'length_min', 'symbol_charset',
'error_message']
widgets = {
'name': forms.TextInput(),
'symbol_charset': forms.TextInput(),
'error_message': forms.TextInput(),
}
labels = {
'amount_uppercase': _('Minimum amount of Uppercase Characters'),
'amount_lowercase': _('Minimum amount of Lowercase Characters'),
'amount_symbols': _('Minimum amount of Symbols Characters'),
'length_min': _('Minimum Length'),
}

Some files were not shown because too many files have changed in this diff Show More