Skip to content

Commit e85e8a3

Browse files
authored
Merge branch 'master' into get-users
2 parents 137d02f + ba8caa8 commit e85e8a3

File tree

21 files changed

+639
-487
lines changed

21 files changed

+639
-487
lines changed

.pre-commit-config.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
repos:
2+
- repo: https://github.com/pre-commit/pre-commit-hooks
3+
rev: v4.1.0
4+
hooks:
5+
- id: trailing-whitespace
6+
- id: end-of-file-fixer
7+
- id: mixed-line-ending
8+
args: ['--fix=lf']
9+
description: Forces to replace line ending by the UNIX 'lf' character.
10+
- repo: https://github.com/psf/black
11+
rev: 22.1.0
12+
hooks:
13+
- id: black
14+
language_version: python3
15+
args: [-t, py310]

.travis.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
language: python
22
sudo: required
3-
dist: bionic
3+
dist: focal
44
python:
5-
- "3.5"
6-
- "3.6"
75
- "3.7"
86
- "3.8"
97
- "3.9"
108
env:
11-
- FLASK=1.1.2
9+
- FLASK=2.0.2
10+
- FLASK=1.1.4
1211
- FLASK=1.0.4
13-
- FLASK=0.12.5
1412
install:
1513
- pip install Flask==$FLASK
1614
- pip install -r dev_requirements.txt

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2019 Alexandre Ferland
3+
Copyright (c) 2022 Alexandre Ferland
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

Makefile

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
.PHONY: help dev clean update test lint pre-commit
2+
3+
VENV_NAME?=venv
4+
VENV_ACTIVATE=. $(VENV_NAME)/bin/activate
5+
PYTHON=${VENV_NAME}/bin/python3
6+
7+
.DEFAULT: help
8+
help:
9+
@echo "make dev"
10+
@echo " prepare development environment, use only once"
11+
@echo "make clean"
12+
@echo " delete development environment"
13+
@echo "make update"
14+
@echo " update dependencies"
15+
@echo "make test"
16+
@echo " run tests"
17+
@echo "make lint"
18+
@echo " run black"
19+
@echo "make pre-commit"
20+
@echo " run pre-commit hooks"
21+
22+
dev:
23+
make venv
24+
25+
venv: $(VENV_NAME)/bin/activate
26+
$(VENV_NAME)/bin/activate:
27+
test -d $(VENV_NAME) || virtualenv -p python3 $(VENV_NAME)
28+
${PYTHON} -m pip install -U pip
29+
${PYTHON} -m pip install -r dev_requirements.txt
30+
$(VENV_NAME)/bin/pre-commit install
31+
touch $(VENV_NAME)/bin/activate
32+
33+
clean:
34+
rm -rf venv
35+
36+
update:
37+
${PYTHON} -m pip install -U -r dev_requirements.txt
38+
$(VENV_NAME)/bin/pre-commit install
39+
40+
test: venv
41+
${PYTHON} -m pytest
42+
43+
lint: venv
44+
$(VENV_NAME)/bin/black -t py310 --exclude $(VENV_NAME) .
45+
46+
pre-commit: venv
47+
$(VENV_NAME)/bin/pre-commit

README.md

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
Flask-SimpleLDAP
1+
Flask-SimpleLDAP [![Build Status](https://app.travis-ci.com/alexferl/flask-simpleldap.svg?branch=master)](https://app.travis-ci.com/alexferl/flask-simpleldap)
22
================
33

4-
[![Build Status](https://travis-ci.com/alexferl/flask-simpleldap.svg?branch=master)](https://travis-ci.com/alexferl/flask-simpleldap)
5-
64
Flask-SimpleLDAP provides LDAP authentication for Flask.
75

8-
Flask-SimpleLDAP is compatible with and tested on Python 3.5, 3.6 and 3.7.
6+
Flask-SimpleLDAP is compatible with and tested on Python 3.7+.
97

108
Quickstart
119
----------
1210

1311
First, install Flask-SimpleLDAP:
14-
15-
$ pip install flask-simpleldap
16-
12+
13+
```shell
14+
pip install flask-simpleldap
15+
```
16+
17+
1718
Flask-SimpleLDAP depends, and will install for you, recent versions of Flask
1819
(0.12.4 or later) and [python-ldap](https://python-ldap.org/).
1920
Please consult the [python-ldap installation instructions](https://www.python-ldap.org/en/latest/installing.html) if you get an error during installation.
@@ -27,19 +28,19 @@ from flask import Flask, g
2728
from flask_simpleldap import LDAP
2829

2930
app = Flask(__name__)
30-
#app.config['LDAP_HOST'] = 'ldap.example.org' # defaults to localhost
31-
app.config['LDAP_BASE_DN'] = 'OU=users,dc=example,dc=org'
32-
app.config['LDAP_USERNAME'] = 'CN=user,OU=Users,DC=example,DC=org'
33-
app.config['LDAP_PASSWORD'] = 'password'
31+
# app.config["LDAP_HOST"] = "ldap.example.org" # defaults to localhost
32+
app.config["LDAP_BASE_DN"] = "OU=users,dc=example,dc=org"
33+
app.config["LDAP_USERNAME"] = "CN=user,OU=Users,DC=example,DC=org"
34+
app.config["LDAP_PASSWORD"] = "password"
3435

3536
ldap = LDAP(app)
3637

37-
@app.route('/')
38+
@app.route("/")
3839
@ldap.basic_auth_required
3940
def index():
40-
return 'Welcome, {0}!'.format(g.ldap_username)
41+
return "Welcome, {0}!".format(g.ldap_username)
4142

42-
if __name__ == '__main__':
43+
if __name__ == "__main__":
4344
app.run()
4445
```
4546

@@ -54,16 +55,16 @@ Once you get the basic example working, check out the more complex ones:
5455
* [examples/groups](examples/groups) demostrates using:
5556
* `@ldap.login_required` for form/cookie-based auth, instead of basic HTTP authentication.
5657
* `@ldap.group_required()` to restrict access to pages based on the user's LDAP groups.
57-
* [examples/blueprints](examples/blueprints) implements the same functionality, but uses Flask's
58-
[application factories](http://flask.pocoo.org/docs/patterns/appfactories/)
58+
* [examples/blueprints](examples/blueprints) implements the same functionality, but uses Flask's
59+
[application factories](http://flask.pocoo.org/docs/patterns/appfactories/)
5960
and [blueprints](http://flask.pocoo.org/docs/blueprints/).
6061

6162

6263
OpenLDAP
6364
--------
6465

6566
Add the ``LDAP`` instance to your code and depending on your OpenLDAP
66-
configuration, add the following at least LDAP_USER_OBJECT_FILTER and
67+
configuration, add the following at least LDAP_USER_OBJECT_FILTER and
6768
LDAP_USER_OBJECT_FILTER.
6869

6970
```python
@@ -73,31 +74,31 @@ from flask_simpleldap import LDAP
7374
app = Flask(__name__)
7475

7576
# Base
76-
app.config['LDAP_REALM_NAME'] = 'OpenLDAP Authentication'
77-
app.config['LDAP_HOST'] = 'openldap.example.org'
78-
app.config['LDAP_BASE_DN'] = 'dc=users,dc=openldap,dc=org'
79-
app.config['LDAP_USERNAME'] = 'cn=user,ou=servauth-users,dc=users,dc=openldap,dc=org'
80-
app.config['LDAP_PASSWORD'] = 'password'
77+
app.config["LDAP_REALM_NAME"] = "OpenLDAP Authentication"
78+
app.config["LDAP_HOST"] = "openldap.example.org"
79+
app.config["LDAP_BASE_DN"] = "dc=users,dc=openldap,dc=org"
80+
app.config["LDAP_USERNAME"] = "cn=user,ou=servauth-users,dc=users,dc=openldap,dc=org"
81+
app.config["LDAP_PASSWORD"] = "password"
8182

82-
# OpenLDAP
83-
app.config['LDAP_OBJECTS_DN'] = 'dn'
84-
app.config['LDAP_OPENLDAP'] = True
85-
app.config['LDAP_USER_OBJECT_FILTER'] = '(&(objectclass=inetOrgPerson)(uid=%s))'
83+
# OpenLDAP
84+
app.config["LDAP_OBJECTS_DN"] = "dn"
85+
app.config["LDAP_OPENLDAP"] = True
86+
app.config["LDAP_USER_OBJECT_FILTER"] = "(&(objectclass=inetOrgPerson)(uid=%s))"
8687

8788
# Groups
88-
app.config['LDAP_GROUP_MEMBERS_FIELD'] = "uniquemember"
89-
app.config['LDAP_GROUP_OBJECT_FILTER'] = "(&(objectclass=groupOfUniqueNames)(cn=%s))"
90-
app.config['LDAP_GROUP_MEMBER_FILTER'] = "(&(cn=*)(objectclass=groupOfUniqueNames)(uniquemember=%s))"
91-
app.config['LDAP_GROUP_MEMBER_FILTER_FIELD'] = "cn"
89+
app.config["LDAP_GROUP_MEMBERS_FIELD"] = "uniquemember"
90+
app.config["LDAP_GROUP_OBJECT_FILTER"] = "(&(objectclass=groupOfUniqueNames)(cn=%s))"
91+
app.config["LDAP_GROUP_MEMBER_FILTER"] = "(&(cn=*)(objectclass=groupOfUniqueNames)(uniquemember=%s))"
92+
app.config["LDAP_GROUP_MEMBER_FILTER_FIELD"] = "cn"
9293

9394
ldap = LDAP(app)
9495

95-
@app.route('/')
96+
@app.route("/")
9697
@ldap.basic_auth_required
9798
def index():
98-
return 'Welcome, {0}!'.format(g.ldap_username)
99+
return "Welcome, {0}!".format(g.ldap_username)
99100

100-
if __name__ == '__main__':
101+
if __name__ == "__main__":
101102
app.run()
102103
```
103104

dev_requirements.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
python-ldap==3.2.0 # here instead of requirements.txt so rtfd can build
1+
black==24.3.0
2+
pre-commit==2.17.0
3+
python-ldap==3.4.0 # here instead of requirements.txt so rtfd can build
24
Sphinx==2.1.2
35

46
-r requirements.txt
Lines changed: 75 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
# flasky extensions. flasky pygments style based on tango style
22
from pygments.style import Style
3-
from pygments.token import Keyword, Name, Comment, String, Error, \
4-
Number, Operator, Generic, Whitespace, Punctuation, Other, Literal
3+
from pygments.token import (
4+
Keyword,
5+
Name,
6+
Comment,
7+
String,
8+
Error,
9+
Number,
10+
Operator,
11+
Generic,
12+
Whitespace,
13+
Punctuation,
14+
Other,
15+
Literal,
16+
)
517

618

719
class FlaskyStyle(Style):
@@ -10,77 +22,68 @@ class FlaskyStyle(Style):
1022

1123
styles = {
1224
# No corresponding class for the following:
13-
#Text: "", # class: ''
14-
Whitespace: "underline #f8f8f8", # class: 'w'
15-
Error: "#a40000 border:#ef2929", # class: 'err'
16-
Other: "#000000", # class 'x'
17-
18-
Comment: "italic #8f5902", # class: 'c'
19-
Comment.Preproc: "noitalic", # class: 'cp'
20-
21-
Keyword: "bold #004461", # class: 'k'
22-
Keyword.Constant: "bold #004461", # class: 'kc'
23-
Keyword.Declaration: "bold #004461", # class: 'kd'
24-
Keyword.Namespace: "bold #004461", # class: 'kn'
25-
Keyword.Pseudo: "bold #004461", # class: 'kp'
26-
Keyword.Reserved: "bold #004461", # class: 'kr'
27-
Keyword.Type: "bold #004461", # class: 'kt'
28-
29-
Operator: "#582800", # class: 'o'
30-
Operator.Word: "bold #004461", # class: 'ow' - like keywords
31-
32-
Punctuation: "bold #000000", # class: 'p'
33-
25+
# Text: "", # class: ''
26+
Whitespace: "underline #f8f8f8", # class: 'w'
27+
Error: "#a40000 border:#ef2929", # class: 'err'
28+
Other: "#000000", # class 'x'
29+
Comment: "italic #8f5902", # class: 'c'
30+
Comment.Preproc: "noitalic", # class: 'cp'
31+
Keyword: "bold #004461", # class: 'k'
32+
Keyword.Constant: "bold #004461", # class: 'kc'
33+
Keyword.Declaration: "bold #004461", # class: 'kd'
34+
Keyword.Namespace: "bold #004461", # class: 'kn'
35+
Keyword.Pseudo: "bold #004461", # class: 'kp'
36+
Keyword.Reserved: "bold #004461", # class: 'kr'
37+
Keyword.Type: "bold #004461", # class: 'kt'
38+
Operator: "#582800", # class: 'o'
39+
Operator.Word: "bold #004461", # class: 'ow' - like keywords
40+
Punctuation: "bold #000000", # class: 'p'
3441
# because special names such as Name.Class, Name.Function, etc.
3542
# are not recognized as such later in the parsing, we choose them
3643
# to look the same as ordinary variables.
37-
Name: "#000000", # class: 'n'
38-
Name.Attribute: "#c4a000", # class: 'na' - to be revised
39-
Name.Builtin: "#004461", # class: 'nb'
40-
Name.Builtin.Pseudo: "#3465a4", # class: 'bp'
41-
Name.Class: "#000000", # class: 'nc' - to be revised
42-
Name.Constant: "#000000", # class: 'no' - to be revised
43-
Name.Decorator: "#888", # class: 'nd' - to be revised
44-
Name.Entity: "#ce5c00", # class: 'ni'
45-
Name.Exception: "bold #cc0000", # class: 'ne'
46-
Name.Function: "#000000", # class: 'nf'
47-
Name.Property: "#000000", # class: 'py'
48-
Name.Label: "#f57900", # class: 'nl'
49-
Name.Namespace: "#000000", # class: 'nn' - to be revised
50-
Name.Other: "#000000", # class: 'nx'
51-
Name.Tag: "bold #004461", # class: 'nt' - like a keyword
52-
Name.Variable: "#000000", # class: 'nv' - to be revised
53-
Name.Variable.Class: "#000000", # class: 'vc' - to be revised
54-
Name.Variable.Global: "#000000", # class: 'vg' - to be revised
55-
Name.Variable.Instance: "#000000", # class: 'vi' - to be revised
56-
57-
Number: "#990000", # class: 'm'
58-
59-
Literal: "#000000", # class: 'l'
60-
Literal.Date: "#000000", # class: 'ld'
61-
62-
String: "#4e9a06", # class: 's'
63-
String.Backtick: "#4e9a06", # class: 'sb'
64-
String.Char: "#4e9a06", # class: 'sc'
65-
String.Doc: "italic #8f5902", # class: 'sd' - like a comment
66-
String.Double: "#4e9a06", # class: 's2'
67-
String.Escape: "#4e9a06", # class: 'se'
68-
String.Heredoc: "#4e9a06", # class: 'sh'
69-
String.Interpol: "#4e9a06", # class: 'si'
70-
String.Other: "#4e9a06", # class: 'sx'
71-
String.Regex: "#4e9a06", # class: 'sr'
72-
String.Single: "#4e9a06", # class: 's1'
73-
String.Symbol: "#4e9a06", # class: 'ss'
74-
75-
Generic: "#000000", # class: 'g'
76-
Generic.Deleted: "#a40000", # class: 'gd'
77-
Generic.Emph: "italic #000000", # class: 'ge'
78-
Generic.Error: "#ef2929", # class: 'gr'
79-
Generic.Heading: "bold #000080", # class: 'gh'
80-
Generic.Inserted: "#00A000", # class: 'gi'
81-
Generic.Output: "#888", # class: 'go'
82-
Generic.Prompt: "#745334", # class: 'gp'
83-
Generic.Strong: "bold #000000", # class: 'gs'
84-
Generic.Subheading: "bold #800080", # class: 'gu'
85-
Generic.Traceback: "bold #a40000", # class: 'gt'
44+
Name: "#000000", # class: 'n'
45+
Name.Attribute: "#c4a000", # class: 'na' - to be revised
46+
Name.Builtin: "#004461", # class: 'nb'
47+
Name.Builtin.Pseudo: "#3465a4", # class: 'bp'
48+
Name.Class: "#000000", # class: 'nc' - to be revised
49+
Name.Constant: "#000000", # class: 'no' - to be revised
50+
Name.Decorator: "#888", # class: 'nd' - to be revised
51+
Name.Entity: "#ce5c00", # class: 'ni'
52+
Name.Exception: "bold #cc0000", # class: 'ne'
53+
Name.Function: "#000000", # class: 'nf'
54+
Name.Property: "#000000", # class: 'py'
55+
Name.Label: "#f57900", # class: 'nl'
56+
Name.Namespace: "#000000", # class: 'nn' - to be revised
57+
Name.Other: "#000000", # class: 'nx'
58+
Name.Tag: "bold #004461", # class: 'nt' - like a keyword
59+
Name.Variable: "#000000", # class: 'nv' - to be revised
60+
Name.Variable.Class: "#000000", # class: 'vc' - to be revised
61+
Name.Variable.Global: "#000000", # class: 'vg' - to be revised
62+
Name.Variable.Instance: "#000000", # class: 'vi' - to be revised
63+
Number: "#990000", # class: 'm'
64+
Literal: "#000000", # class: 'l'
65+
Literal.Date: "#000000", # class: 'ld'
66+
String: "#4e9a06", # class: 's'
67+
String.Backtick: "#4e9a06", # class: 'sb'
68+
String.Char: "#4e9a06", # class: 'sc'
69+
String.Doc: "italic #8f5902", # class: 'sd' - like a comment
70+
String.Double: "#4e9a06", # class: 's2'
71+
String.Escape: "#4e9a06", # class: 'se'
72+
String.Heredoc: "#4e9a06", # class: 'sh'
73+
String.Interpol: "#4e9a06", # class: 'si'
74+
String.Other: "#4e9a06", # class: 'sx'
75+
String.Regex: "#4e9a06", # class: 'sr'
76+
String.Single: "#4e9a06", # class: 's1'
77+
String.Symbol: "#4e9a06", # class: 'ss'
78+
Generic: "#000000", # class: 'g'
79+
Generic.Deleted: "#a40000", # class: 'gd'
80+
Generic.Emph: "italic #000000", # class: 'ge'
81+
Generic.Error: "#ef2929", # class: 'gr'
82+
Generic.Heading: "bold #000080", # class: 'gh'
83+
Generic.Inserted: "#00A000", # class: 'gi'
84+
Generic.Output: "#888", # class: 'go'
85+
Generic.Prompt: "#745334", # class: 'gp'
86+
Generic.Strong: "bold #000000", # class: 'gs'
87+
Generic.Subheading: "bold #800080", # class: 'gu'
88+
Generic.Traceback: "bold #a40000", # class: 'gt'
8689
}

0 commit comments

Comments
 (0)