ldap-ui 0.9.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ldap_ui/__init__.py +14 -0
- ldap_ui/__main__.py +4 -0
- ldap_ui/app.py +196 -0
- ldap_ui/ldap_api.py +416 -0
- ldap_ui/ldap_helpers.py +112 -0
- ldap_ui/schema.py +130 -0
- ldap_ui/settings.py +85 -0
- ldap_ui/statics/assets/fontawesome-webfont-B-jkhYfk.woff2 +0 -0
- ldap_ui/statics/assets/fontawesome-webfont-CDK5bt4p.woff +0 -0
- ldap_ui/statics/assets/fontawesome-webfont-CQDK8MU3.ttf +0 -0
- ldap_ui/statics/assets/fontawesome-webfont-D13rzr4g.svg +2671 -0
- ldap_ui/statics/assets/fontawesome-webfont-G5YE5S7X.eot +0 -0
- ldap_ui/statics/assets/index-CA45Sb-q.js +18 -0
- ldap_ui/statics/assets/index-CA45Sb-q.js.gz +0 -0
- ldap_ui/statics/assets/index-DlTKbnmq.css +4 -0
- ldap_ui/statics/assets/index-DlTKbnmq.css.gz +0 -0
- ldap_ui/statics/favicon.ico +0 -0
- ldap_ui/statics/index.html +24 -0
- ldap_ui-0.9.0.dist-info/LICENSE.txt +7 -0
- ldap_ui-0.9.0.dist-info/METADATA +142 -0
- ldap_ui-0.9.0.dist-info/RECORD +24 -0
- ldap_ui-0.9.0.dist-info/WHEEL +5 -0
- ldap_ui-0.9.0.dist-info/entry_points.txt +2 -0
- ldap_ui-0.9.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: ldap-ui
|
|
3
|
+
Version: 0.9.0
|
|
4
|
+
Summary: A fast and versatile LDAP editor
|
|
5
|
+
Author: dnknth
|
|
6
|
+
License: MIT License
|
|
7
|
+
Project-URL: Repository, https://github.com/dnknth/ldap-ui
|
|
8
|
+
Keywords: ldap,web-ui,python3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE.txt
|
|
18
|
+
Requires-Dist: python-ldap
|
|
19
|
+
Requires-Dist: python-multipart
|
|
20
|
+
Requires-Dist: starlette
|
|
21
|
+
Requires-Dist: uvicorn
|
|
22
|
+
|
|
23
|
+
# Fast and versatile LDAP editor
|
|
24
|
+
|
|
25
|
+
This is a *minimal* web interface for LDAP directories. Docker images for `linux/amd64` and `linux/arm64/v8` are [available](https://hub.docker.com/r/dnknth/ldap-ui).
|
|
26
|
+
|
|
27
|
+

|
|
28
|
+
|
|
29
|
+
Features:
|
|
30
|
+
|
|
31
|
+
* Directory tree view
|
|
32
|
+
* Entry creation / modification / deletion
|
|
33
|
+
* LDIF import / export
|
|
34
|
+
* Image support for the `jpegPhoto` and `thumbnailPhoto` attributes
|
|
35
|
+
* Schema aware
|
|
36
|
+
* Simple search (configurable)
|
|
37
|
+
* Asynchronous LDAP backend with decent scalability
|
|
38
|
+
* Available as [Docker image](https://hub.docker.com/r/dnknth/ldap-ui/)
|
|
39
|
+
|
|
40
|
+
The app always requires authentication, even if the directory permits anonymous access. User credentials are validated through a simple `bind` on the directory (SASL is not supported). What a particular user can see (and edit) is governed entirely by directory access rules. The app shows the directory contents, nothing less and nothing more.
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
### Environment variables
|
|
45
|
+
|
|
46
|
+
LDAP access is controlled by these environment variables, possibly from a `.env` file:
|
|
47
|
+
|
|
48
|
+
* `LDAP_URL` (optional): Connection URL, defaults to `ldap:///`.
|
|
49
|
+
* `BASE_DN` (required): Search base, e.g. `dc=example,dc=org`.
|
|
50
|
+
* `LOGIN_ATTR` (optional): User name attribute, defaults to `uid`.
|
|
51
|
+
|
|
52
|
+
* `USE_TLS` (optional): Enable TLS, defaults to true for `ldaps` connections. Set it to a non-empty string to force `STARTTLS` on `ldap` connections.
|
|
53
|
+
* `INSECURE_TLS` (optional): Do not require a valid server TLS certificate, defaults to false, implies `USE_TLS`.
|
|
54
|
+
|
|
55
|
+
For finer-grained control, see [settings.py](settings.py).
|
|
56
|
+
|
|
57
|
+
### Docker
|
|
58
|
+
|
|
59
|
+
For the impatient: Run it with
|
|
60
|
+
|
|
61
|
+
```shell
|
|
62
|
+
docker run -p 127.0.0.1:5000:5000 \
|
|
63
|
+
-e LDAP_URL=ldap://your.ldap.server/ \
|
|
64
|
+
-e BASE_DN=dc=example,dc=org dnknth/ldap-ui
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
For the even more impatient: Start a demo with
|
|
68
|
+
|
|
69
|
+
```shell
|
|
70
|
+
docker compose up -d
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
and go to <http://localhost:5000/>. You are automatically logged in as `Fred Flintstone`.
|
|
74
|
+
|
|
75
|
+
### Pip
|
|
76
|
+
|
|
77
|
+
Install the `python-ldap` dependency with your system's package manager.
|
|
78
|
+
Otherwise, Pip will try to compile it from source and this will likely fail because it lacks a development environment.
|
|
79
|
+
|
|
80
|
+
Then install `ldap-ui` in a virtual environment:
|
|
81
|
+
|
|
82
|
+
```shell
|
|
83
|
+
python3 -m venv --system-site-packages venv
|
|
84
|
+
. venv/bin/activate
|
|
85
|
+
pip3 install -U ldap-ui
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Possibly after a shell `rehash`, it is available as `ldap-ui`.
|
|
89
|
+
|
|
90
|
+
## Development
|
|
91
|
+
|
|
92
|
+
Prerequisites:
|
|
93
|
+
|
|
94
|
+
* [GNU make](https://www.gnu.org/software/make/)
|
|
95
|
+
* [node.js](https://nodejs.dev) LTS version with NPM
|
|
96
|
+
* [Python3](https://www.python.org) ≥ 3.7
|
|
97
|
+
* [pip3](https://packaging.python.org/tutorials/installing-packages/)
|
|
98
|
+
* [python-ldap](https://pypi.org/project/python-ldap/); To compile the Python module:
|
|
99
|
+
* Debian / Ubuntu: `apt-get install libsasl2-dev python-dev libldap2-dev libssl-dev`
|
|
100
|
+
* RedHat / CentOS: `yum install python-devel openldap-devel`
|
|
101
|
+
|
|
102
|
+
`ldap-ui` consists of a Vue frontend and a Python backend that roughly translates a subset of the LDAP protocol to a stateless ReST API.
|
|
103
|
+
|
|
104
|
+
For the frontend, `npm run build` assembles everything in `backend/ldap_ui/statics`.
|
|
105
|
+
|
|
106
|
+
Review the configuration in [settings.py](settings.py). It is short and mostly self-explaining.
|
|
107
|
+
Most settings can (and should) be overridden by environment variables or settings in a `.env` file; see [env.demo](env.demo) or [env.example](env.example).
|
|
108
|
+
|
|
109
|
+
The backend can be run locally with `make`, which will also install dependencies and build the frontend if needed.
|
|
110
|
+
|
|
111
|
+
## Notes
|
|
112
|
+
|
|
113
|
+
### Authentication methods
|
|
114
|
+
|
|
115
|
+
The UI always uses a simple `bind` operation to authenticate with the LDAP directory. How the `bind` DN is obtained from a given user name depends on a combination of OS environment variables, possibly from a `.env` file:
|
|
116
|
+
|
|
117
|
+
1. Search by some attribute. By default, this is the `uid`, which can be overridden by the environment variable `LOGIN_ATTR`, e.g. `LOGIN_ATTR=cn`.
|
|
118
|
+
2. If the environment variable `BIND_PATTERN` is set, then no search is performed. Login with a full DN can be configured with `BIND_PATTERN=%s`, which for example allows to login as user `cn=admin,dc=example,dc=org`. If a partial DN like `BIND_PATTERN=%s,dc=example,dc=org` is configured, the corresponding login would be `cn=admin`. If a specific pattern like `BIND_PATTERN=cn=%s,dc=example,dc=org` is configured, the login name is just `admin`.
|
|
119
|
+
3. If security is no concern, then a fixed `BIND_DN` and `BIND_PASSWORD` can be set in the environment. This is for demo purposes only, and probably a very bad idea if access to the UI is not restricted by any other means.
|
|
120
|
+
|
|
121
|
+
### Searching
|
|
122
|
+
|
|
123
|
+
Search uses a (configurable) set of criteria (`cn`, `gn`, `sn`, and `uid`) if the query does not contain `=`.
|
|
124
|
+
Wildcards are supported, e.g. `f*` will match all `cn`, `gn`, `sn`, and `uid` starting with `f`.
|
|
125
|
+
Additionally, arbitrary attributes can be searched with an LDAP filter specification, for example `sn=F*`.
|
|
126
|
+
|
|
127
|
+
### Caveats
|
|
128
|
+
|
|
129
|
+
* The software works with [OpenLdap](http://www.openldap.org) using simple bind. Other directories have not been tested, and SASL authentication schemes are presently not supported.
|
|
130
|
+
* Passwords are transmitted as plain text. The LDAP server is expected to hash them (OpenLdap 2.4 does). I strongly recommend to expose the app through a TLS-enabled web server.
|
|
131
|
+
* HTTP *Basic Authentication* is triggered unless the `AUTHORIZATION` request variable is already set by some upstream HTTP server.
|
|
132
|
+
|
|
133
|
+
## Q&A
|
|
134
|
+
|
|
135
|
+
* Q: Why are some fields not editable?
|
|
136
|
+
* A: The RDN of an entry is read-only. To change it, rename the entry with a different RDN, then change the old RDN and rename back. To change passwords, click on the question mark icon on the right side. Binary fields (as per schema) are read-only. You do not want to modify them accidentally.
|
|
137
|
+
* Q: Why did you write this?
|
|
138
|
+
* A: [PHPLdapAdmin](http://phpldapadmin.sf.net/) has not seen updates for ages. I needed a replacement, and wanted to try Vue.
|
|
139
|
+
|
|
140
|
+
## Acknowledgements
|
|
141
|
+
|
|
142
|
+
The Python backend uses [Starlette](https://starlette.io). The UI is built with [Vue.js](https://vuejs.org) and [Tailwind CSS](https://tailwindcss.com/). Kudos to the authors of these elegant frameworks!
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
ldap_ui/__init__.py,sha256=w8u2chV-MGP-XyBrr5D0d0xVZLicqa6xsTI-X7THvqE,224
|
|
2
|
+
ldap_ui/__main__.py,sha256=J0Hc3IiwRAjNKeov7tCLgpZJwT2iUHcmXb4UmazRqU4,62
|
|
3
|
+
ldap_ui/app.py,sha256=68__BoGHFJU8HePoTKyYTM8B305s_dYnlKb8e9yWm8I,6312
|
|
4
|
+
ldap_ui/ldap_api.py,sha256=ecK8K-7-tkoA2df2dbQT8y61I70r7NukE3BQFNN1BsE,12776
|
|
5
|
+
ldap_ui/ldap_helpers.py,sha256=DRpKtqEX_OvYJBuvzTNi0CcZAu446wwUiOezlkBAxrQ,3045
|
|
6
|
+
ldap_ui/schema.py,sha256=apbdLK_WpED0IzmrdktWTu4ESz8GfdOoJuRicFC84YY,3327
|
|
7
|
+
ldap_ui/settings.py,sha256=qEN2fechOCZ935VAa47cPimQruEq7h-iq9d7ascDtZc,2265
|
|
8
|
+
ldap_ui/statics/favicon.ico,sha256=_PMMM_C1ER5cpJTXZcRgISR4igj44kA4u8Trl-Ko3L0,4286
|
|
9
|
+
ldap_ui/statics/index.html,sha256=twUC90MNTfNFpQLiLIwUuU3H6RRDiPY92BnMRgIGRWU,827
|
|
10
|
+
ldap_ui/statics/assets/fontawesome-webfont-B-jkhYfk.woff2,sha256=Kt78vAQefRj88tQXh53FoJmXqmTWdbejxLbOM9oT8_4,77160
|
|
11
|
+
ldap_ui/statics/assets/fontawesome-webfont-CDK5bt4p.woff,sha256=ugxZ3rVFD1y0Gz-TYJ7i0NmVQVh33foiPoqKdTNHTwc,98024
|
|
12
|
+
ldap_ui/statics/assets/fontawesome-webfont-CQDK8MU3.ttf,sha256=qljzPyOaD7AvXHpsRcBD16msmgkzNYBmlOzW1O3A1qg,165548
|
|
13
|
+
ldap_ui/statics/assets/fontawesome-webfont-D13rzr4g.svg,sha256=rWFXkmwWIrpOHQPUePFUE2hSS_xG9R5C_g2UX37zI-Q,444379
|
|
14
|
+
ldap_ui/statics/assets/fontawesome-webfont-G5YE5S7X.eot,sha256=e_yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk,165742
|
|
15
|
+
ldap_ui/statics/assets/index-CA45Sb-q.js,sha256=qejoldzV9wbUVar1ljURYwyTb2DYn3HQPsdfIA2OwpI,122096
|
|
16
|
+
ldap_ui/statics/assets/index-CA45Sb-q.js.gz,sha256=1yJTHdcLZLU2d6DkPKbmNEFiOlPo7vIWXYyg_fidSdE,43710
|
|
17
|
+
ldap_ui/statics/assets/index-DlTKbnmq.css,sha256=Rpthz_HvUybqmodfPCnOXFsSwGd7v8hhh-p-duAzf1E,48119
|
|
18
|
+
ldap_ui/statics/assets/index-DlTKbnmq.css.gz,sha256=Ctq3hMh_BBVt9zsh9CYlHpVtDDHanicyGPAdcGXIFXw,11532
|
|
19
|
+
ldap_ui-0.9.0.dist-info/LICENSE.txt,sha256=UpJ0sDIqHxbOtzy1EG4bCHs9R_99ODxxPDK4NZ0g3I0,1042
|
|
20
|
+
ldap_ui-0.9.0.dist-info/METADATA,sha256=GV-khRNipkOv70wqkY11tULHZt8jXJYTVeDOcW3YORA,6783
|
|
21
|
+
ldap_ui-0.9.0.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
|
22
|
+
ldap_ui-0.9.0.dist-info/entry_points.txt,sha256=rJuKzXUTziBohZ3-tt4-WbD2DOO1LHfzwnDm2HdCg84,40
|
|
23
|
+
ldap_ui-0.9.0.dist-info/top_level.txt,sha256=t9Agyig1nDdJuQvx_UVuk1n28pgswc1BIYw8E6pWado,8
|
|
24
|
+
ldap_ui-0.9.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ldap_ui
|