Skip to content

Repository files navigation

Musterroll

A lightweight LDAP and OAUTH server for user management

Why?

Musterroll wants to be a simple user management tool to make it easier to self-host services for individuals and small organizations.

As a simple LDAP server with an API

LDAP is a widely supported user directory format. However for most use cases the management of a full LDAP server is an overkill that is reflected in overcomplicated user interfaces.

Musterroll exposes the users in a virtual LDAP directory while providing an optional REST API and simple UI to manage them.

Musterroll will never support non user management related aspects of LDAP.

Compatible Applications

While Musterroll should work with any service that can authenticate against an LDAP directory, some expect non-standard behaviour that other LDAP servers provide. If you run into such a case, please open an issue and we will look into it.

However the following applications have been tested and run well with Musterroll as an LDAP server:

As a simple OAUTH server with an API

TBI

Example Usage

Typically Musterroll will be deployed as a Docker service.

An exemplary docker-compose file would look like this

---
version: '2'services:
musterroll:
hostname: musterrollimage: cloudfleet/musterrollrestart: alwaysvolumes:
- "./data:/home/node/app/data"environment:
USER_STORAGE_PATH: "./data/"DOMAIN: "example.com"LDAP_ENABLED: "true"AUTH_ENABLED: "true"API_ENABLED: "true"env_file:
- secrets.env # set SESSION_SECRET therelabels:
- "traefik.port=80"
- "traefik.enable=true"
- "traefik.frontend.rule=Host:example.com"traefik:
hostname: traefikimage: traefikrestart: alwayscommand:
- "--defaultentrypoints=http,https"
- "--entryPoints=Name:http Address::80 Redirect.EntryPoint:https"
- "--entryPoints=Name:https Address::443 TLS"
- "--docker.exposedByDefault=false"
- "--acme.email=security@example.com"
- "--acme.entryPoint=https"
- "--acme.storage=/acme/acme.json"
- "--acme.tlsChallenge=true"
- "--acme.onHostRule=true"ports:
- "80:80"
- "443:443"volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./acme:/acme

Configuration

VariableDefaultDescription
USER_STORAGE_PATH./data/
DOMAINuser.example.comThe root domain. Is used to create the Root DN for LDAP and to autogenerate email adresses if none are present
DEBUGfalseTBD
LDAP_ENABLEDIf the variable is present, LDAP server will be enabled
LDAP_PORT389The port the ldap server should listen on
AUTH_ENABLEDIf the variable is present, login by http is enabled. Prerequisite for API_ENABLED and OAUTH_ENABLED to take effect
API_ENABLEDIf the variable is present, the REST API for user management is enabled
OAUTH_ENABLEDIf the variable is present, the OAUTH server is enabled (not implemented yet)
API_PORT80The port the http server listens on
SESSION_SECRETA string randomly generated at server startSecret to encrypt cookie data. If not given every server restart invalidates all cookies and logins.

Data Model

User

A user in musterroll has the following properties:

PropertyTypeDescription
idstringThe unique username. Will be used to autopopulate the email field if no explicit email is given.
uuidstringAutogenerated, needed for Nextcloud LDAP plugin
firstnamestring
lastnamestring
aliaseslist of string
isAdminboolean
passwordHashstring
emailstring

Group

At this time there exists only one group, admins.

User Store

At this time only storing users as JSON file is implemented. As soon as there is a second implementation, the user store will be configurable.

LDAP Server

The LDAP server exposes the users in a virtual LDAP tree.

The root DN of this tree consists of the elements of the DOMAIN configuration setting as dc elements. Eg. the default users.example.com translates into dc=users, dc=example, dc=com.

The users are in a subtree under ou=users, [root DN], eg. ou=users, dc=users, dc=example, dc=com.

The user FQDNs are cn=[username], [users subtree DN], eg. cn=doublemalt, ou=users, dc=users, dc=example, dc=com

Every user is a inetOrgPerson with the following attributes:

LDAP Attribute NameMapping
cnid
uuiduuid
givenNamefirstname
snlastname
emailemail or [id]@[domain]
maillike email

OAuth Server

TBD

User Management API

The user management API provides the following endpoints:

GET /api/v1/currentUser

Returns the currently logged in user. If not logged in returns 401 Not authenticated.

Example Response:

{
}

GET /api/v1/users/from_alias/:alias

Returns the user that has the alias. If not logged in returns 401 Not authenticated. If no user uses the alias returns 404 Not found.

Example Response:

{
"id":"admin",
"uuid": "09d182d8-175e-11e9-afb9-47cedb30a11c",
"aliases":[],
"firstname":"John",
"lastname":"Doe",
"isAdmin":true,
"email":"admin@example.com"
}

GET /api/v1/users

Returns a list of all users. If not logged in returns 401 Not authenticated. If logged in but not admin returns 403 Unauthorized.

Example Response:

[
{
"id":"admin",
"uuid": "09d182d8-175e-11e9-afb9-47cedb30a11c",
"aliases":[],
"firstname":"John",
"lastname":"Doe",
"isAdmin":true,
"email":"admin@example.com"
}
]

GET /api/v1/users/:user_id

Returns the user identified by user_id. If not logged in returns 401 Not authenticated. If logged in but not admin or logged in as the user with user_id returns 403 Unauthorized.

Example Response:

{
"id":"admin",
"uuid": "09d182d8-175e-11e9-afb9-47cedb30a11c",
"aliases":[],
"firstname":"John",
"lastname":"Doe",
"isAdmin":true,
"email":"admin@example.com"
}

POST /api/v1/users

Creates a new user. If not logged in returns 401 Not authenticated. If logged in but not admin returns 403 Unauthorized.

Example Payload:

{
"id":"jack",
"firstname":"Jack",
"lastname":"Doe"
}

Example Response:

{
"id":"jack",
"uuid": "7144b534-175e-11e9-820c-c373deae43d3",
"aliases":[],
"firstname":"Jack",
"lastname":"Doe",
"isAdmin":false,
"email":"jack@example.com"
}

PUT /api/v1/users/:user_id

Updates a user. If not logged in returns 401 Not authenticated. If logged in but not admin or logged in as the user with user_id returns 403 Unauthorized.

Example Payload:

{
"email":"jack.doe@example.com",
}

Example Response:

{
"id":"jack",
"uuid": "7144b534-175e-11e9-820c-c373deae43d3",
"aliases":[],
"firstname":"Jack",
"lastname":"Doe",
"isAdmin":false,
"email":"jack.doe@example.com"
}

DELETE /api/v1/users/:user_id

Deletes a user. If not logged in returns 401 Not authenticated. If logged in but not admin returns 403 Unauthorized.

Example Response:

{
"id":"jack",
"uuid": "7144b534-175e-11e9-820c-c373deae43d3",
"aliases":[],
"firstname":"Jack",
"lastname":"Doe",
"isAdmin":false,
"email":"jack@example.com"
}

PUT /api/v1/users/:user_id/password

Sets password for a user. If not logged in returns 401 Not authenticated. If logged in but not admin or logged in as the user with user_id returns 403 Unauthorized.

Example Payload:

{
"password": "supersecurerandompassword"
}

Example Response:

{
"success": "true"
}

PUT /api/v1/users/:user_id/is_admin

Sets admin rights for a user. If not logged in returns 401 Not authenticated. If logged in but not admin returns 403 Unauthorized.

Example Payload:

{
"is_admin": "true"
}

Example Response:

{
"success": "true"
}

About

A user directory server with LDAP and OAUTH interface

Resources

Contributing

Stars

2 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages