Glauth management ui created with python/flask

Related tags

Flask glauth-ui
Overview

glauth-ui

Glauth-UI is a small flask web app i created to manage the minimal glauth ldap server. I created this as i wanted to use glauth for authentication in several service at home and at work, but since it is readonly there is no way for users to configure their own password for example.

Since i knew a bit of python and wanted to learn flask i thought i create a small webapp that acts as a management ui for glauth.

This should be considered as a prove of concept and some glauth features arent implemented yet as i have no use for them (yet). There are probably a lot of bugs in this and if you are using it you should limit the usage to the local network only.

Current features:

  • Stores Data (Glauth Settings, Users, Groups) in a SQL DB (Sqlite, MySQL, PostgreSQL are supported)
  • Generates a glauth compatible config.cfg file on every change to the db
  • Small UI for Endusers to change their password, name and email or reset their password (if forgotten).
  • Admin UI for managing settings and creating users and groups
  • eMail support for forgotten passwords and new user creation

Missing features:

  • Not all glauth settings and user options can be configured, following featurs and Options are missing:
    • API
    • Backend: nameformat, groupformat, sshkeyattr
    • User: loginShell, homeDir, sshkeys, passappsha256, otpsecret, yubikey

Installation:

The best installation method atm is to build the docker image with the included Dockerfile.

  1. Clone Repository
git clone https://github.com/sonicnkt/glauth-ui.git glauth-ui
  1. Run docker build
cd glauth-ui
docker build -t glauthui:latest . 

  1. Create container

docker-compose.yaml

version: '3.8'
services:
  glauthui:
    image: glauthui:latest
    container_name: glauthui
    restart: unless-stopped
    ports:
      - 80:5000
    volumes:
      # Mount Folder that contains DB and config file outside the container
      - './docker-data:/home/ldap/db'
    environment:
      - SECRET_KEY=mysuperlongsecretkeythatnobodywillguess
      # MAIL CONFIG
      - MAIL_SERVER=mail.example.com
      - MAIL_PORT=587
      - MAIL_USE_TLS=1
      - MAIL_USERNAME=username
      - MAIL_PASSWORD=password
      - [email protected]

docker-compose up #-d

On first startup (or if DB is empty) a sample database will be created with 2 users and 4 groups. Use the username "j_doe" and password "dogood" to login and have access to the administration interface.

This should be run behind a reverse proxy like nginx that handles https!

  1. Point glauth to the config.cfg created by glauth-ui

Environment Variables:

These can be set using environment variables using docker.

SECRET_KEY=

Should be a long random string to protect against CSRF attacks and should definatly be set in a production environment.

APPNAME=

Short name that will be displayed in the webapp and emails. Default = Glauth UI

ORGANISATION=

Longer organisations name that will show up in emails. Default = LDAP Management Team

ADMIN_GROUP=glauth_admin

Name of the glauth/ldap group which members have admin access to the ui (This can't be an included/nested group atm and must be assigned directly to the user)

FLASK_DEBUG=

Enable Debugging mode in Flask, never enable this for production environment! Default = False

MAIL_SERVER=mail.example.com
MAIL_PORT=587
MAIL_USE_TLS=1
MAIL_USERNAME=username
MAIL_PASSWORD=password
[email protected]

Configure your email provider, MAIL_ADMIN will show up as sender. Default = [email protected]

DATABASE_URL=

Sets the Databsae URI, Default is a sqlite app.db in the apps db/ subdirectory. For MySQL/Maria DB use mysql+pymysql://<user>:<password>@<server>:<port>/<db>. See also (https://flask-sqlalchemy.palletsprojects.com/en/2.x/config/#connection-uri-format) for more Options.

GLAUTH_CFG_PATH=

Sets the Glauth config.cfg path, Default is config.cfg in the apps db/ subdirectory.


Usage:

Login View: Login

After you spun up the container you can login with the sample user j_doe and the password dogood.

Main View: Login

In the main view normal user can change their names and email adress or change their password. Administrators also have access to a email test function and the admin interface.

Main Admin View: Login

In the Admin Interface you can configure your glauth settings, users and groups.

Admin User View: Login

Creating new users: Login

When you create a new user you have the option to send an invite link per mail, the account is disabled until they created their password.

If the password field is left blank when creating new users it will be autogenerated and displayed to the admin but only if the Invite Option is not enabled. Otherwise a random password and a token is generated for users to set their own.

Users without an email adress are not allowed to log into the ui (service accounts).

Admin Group View: Login

Creating new groups: Login

When you create a new group you can select if it is a primary group.

Editing secondary groups: Login

When you edit a non primary group you can assign users and set to include this group in other groups or configure the included groups.

Editing primary groups: Login

When you edit a primary group you can assign users and set which secondary groups it includes. Primary groups can't be included in other primary groups or secondary groups.

Editing glauth settings: Login

You can also change several glauth settings from the ui. These are also stored in the db and are used when generating a new config file so make sure these are correct. Changing those settings require you to restart glauth.

The glauth watchconfig option is missing here, it is automatically added as it is a dependancy for this to work correctly.


This would generate the following config.cfg:

## GLAUTH config backend configuration file

# General configuration
watchconfig = true
debug = true

[ldap]
  enabled = true
  listen = "0.0.0.0:389"

[ldaps]
  enabled = false

# Backend configuration
[backend]
  datastore = "config"
  baseDN = "dc=glauth-example,dc=com"


## LDAP Users configuration
[[users]]
  name = "j_doe"
  givenname = "Jane"
  sn = "Doe"
  mail = "[email protected]"
  unixid = 5001
  primarygroup = 5501
  passsha256 = "6478579e37aff45f013e14eeb30b3cc56c72ccdc310123bcdf53e0333e3f416a"
  otherGroups = [ 5551,5552,5553 ]

[[users]]
  name = "search"
  unixid = 5002
  primarygroup = 5502
  passsha256 = "125844054e30fabcd4182ae69c9d7b38b58d63c067be10ab5ab883d658383316"

[[users]]
  name = "jo_doe"
  givenname = "John"
  sn = "Doe"
  mail = "[email protected]"
  unixid = 5004
  primarygroup = 5501
  passsha256 = "3c8580d143af4b0585a84e7497978aafe550f8687ea52ceb180e8f884fd3319d"
  otherGroups = [ 5551,5552 ]
  disabled = True

## LDAP Groups configuration
[[groups]]
  name = "people"
  unixid = 5501
  # primary user group

[[groups]]
  name = "svcaccts"
  unixid = 5502
  # service accounts

[[groups]]
  name = "glauth_admin"
  unixid = 5551

[[groups]]
  name = "vpn"
  unixid = 5552
  includegroups = [ 5501 ]

[[groups]]
  name = "xmpp"
  unixid = 5553
  includegroups = [ 5501 ]
  # Prosody XMPP Users
Comments
  • Use existing glauth environment?

    Use existing glauth environment?

    I have an existing glauth environment that I would like to manage with glauth-ui. It's using just the config file. I don't quite understand from the README but it seems that when you set this up, you create a blank glauth environment then this exports a .cfg which can be used. Is it possible to import from an existing glauth environment?

    opened by surfrock66 4
  • No license

    No license

    Hi sonicnkt :) I am really happy with using glauth-ui for a project or two, but I noticed that it currently is not under a specific license. Are you planning on changing that?

    opened by glubii 2
  • Improvements to auto-generated glauth config

    Improvements to auto-generated glauth config

    The original version generated config files that would not return valid results for ldapsearch or Authelia. The reasons were the use of the deprecated "unixid" field as well as the missing behavior attribute. This change sets up default behavior to allow all users to search. Ideally the UI would be updated with a checkbox or something like that per user which would then add a [behaviour] section for each user

    opened by sharatbala 2
  • Missing options in glauth settings tab

    Missing options in glauth settings tab

    The Glauth settings tab is missing two values (nameformat and groupformat) under the "backend" section:

    [backend] datastore = "config" baseDN = "dc=glauth,dc=com" nameformat = "uid" groupformat = "cn"

    Please add those two options to the Glauth settings page.

    Thanks!

    opened by dl1ch 2
  • Error -

    Error - "unable to open database file" when using bind mount

    Hello,

    When I use a bind mount for the /home/ldap/db directory, I get an error that the database cannot be opened, before the initial database is even created. I've tried a populated folder (with config.cfg), and an empty one. This does not happen when I use a volume mount. My docker-compose.yml is as follows:

    version: '3'
    services:
      glauth:
        image: glauth/glauth
        container_name: glauth
        restart: unless-stopped
        ports:
          - 389:389
          - 636:636
        volumes:
          - $DOCKERDIR/swag/config/keys:/app/config/certs
          - $DOCKERDIR/glauth/config.cfg:/app/config/config.cfg
    
      glauthui:
        image: glauthui:latest
        container_name: glauth-ui
        restart: unless-stopped
        ports:
          - 9045:5000
        volumes:
          - $DOCKERDIR/glauth:/home/ldap/db
          - $SECRETSDIR/glauth:/secrets
        environment:
          - SECRET_KEY=<redacted>
          - MAIL_SERVER=smtp.gmail.com
          - MAIL_PORT=587
          - MAIL_USE_TLS=1
          - MAIL_USERNAME=
          - MAIL_PASSWORD=
          - MAIL_ADMIN=
    

    Works if:

        volumes:
          - dockervolume:/home/ldap/db
    

    Error:

    [2021-04-20 20:56:31,397] INFO in __init__: Glauth UI
    sqlite3.OperationalError: unable to open database file
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "/home/ldap/venv/bin/flask", line 8, in <module>
        sys.exit(main())
      File "/home/ldap/venv/lib/python3.8/site-packages/flask/cli.py", line 967, in main
        cli.main(args=sys.argv[1:], prog_name="python -m flask" if as_module else None)
      File "/home/ldap/venv/lib/python3.8/site-packages/flask/cli.py", line 586, in main
        return super(FlaskGroup, self).main(*args, **kwargs)
      File "/home/ldap/venv/lib/python3.8/site-packages/click/core.py", line 782, in main
        rv = self.invoke(ctx)
      File "/home/ldap/venv/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "/home/ldap/venv/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "/home/ldap/venv/lib/python3.8/site-packages/click/core.py", line 610, in invoke
        return callback(*args, **kwargs)
      File "/home/ldap/venv/lib/python3.8/site-packages/click/decorators.py", line 21, in new_func
        return f(get_current_context(), *args, **kwargs)
      File "/home/ldap/venv/lib/python3.8/site-packages/flask/cli.py", line 426, in decorator
        return __ctx.invoke(f, *args, **kwargs)
      File "/home/ldap/venv/lib/python3.8/site-packages/click/core.py", line 610, in invoke
        return callback(*args, **kwargs)
      File "/home/ldap/app/__init__.py", line 74, in createdbdata
        if models.User.query.count() == 0:
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/orm/query.py", line 3803, in count
        return self.from_self(col).scalar()
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/orm/query.py", line 3523, in scalar
        ret = self.one()
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/orm/query.py", line 3490, in one
        ret = self.one_or_none()
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/orm/query.py", line 3459, in one_or_none
        ret = list(self)
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/orm/query.py", line 3535, in __iter__
        return self._execute_and_instances(context)
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/orm/query.py", line 3556, in _execute_and_instances
        conn = self._get_bind_args(
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/orm/query.py", line 3571, in _get_bind_args
        return fn(
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/orm/query.py", line 3550, in _connection_from_session
        conn = self.session.connection(**kw)
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 1142, in connection
        return self._connection_for_bind(
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 1150, in _connection_for_bind
        return self.transaction._connection_for_bind(
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 433, in _connection_for_bind
        conn = bind._contextual_connect()
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2302, in _contextual_connect
        self._wrap_pool_connect(self.pool.connect, None),
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2339, in _wrap_pool_connect
        Connection._handle_dbapi_exception_noconnection(
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1583, in _handle_dbapi_exception_noconnection
        util.raise_(
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 182, in raise_
        raise exception
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2336, in _wrap_pool_connect
        return fn()
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 364, in connect
        return _ConnectionFairy._checkout(self)
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 778, in _checkout
        fairy = _ConnectionRecord.checkout(pool)
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 495, in checkout
        rec = pool._do_get()
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/pool/impl.py", line 241, in _do_get
        return self._create_connection()
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 309, in _create_connection
        return _ConnectionRecord(self)
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 440, in __init__
        self.__connect(first_connect_check=True)
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 661, in __connect
        pool.logger.debug("Error on connect(): %s", e)
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py", line 68, in __exit__
        compat.raise_(
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 182, in raise_
        raise exception
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/pool/base.py", line 656, in __connect
        connection = pool._invoke_creator(self)
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/engine/strategies.py", line 114, in connect
        return dialect.connect(*cargs, **cparams)
      File "/home/ldap/venv/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 508, in connect
        return self.dbapi.connect(*cargs, **cparams)
    sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file
    (Background on this error at: http://sqlalche.me/e/13/e3q8)
    

    Am I dense and am missing something, or doing something wrong?

    Thanks in advance!

    opened by tmeuze 2
  • A bit of cleanup

    A bit of cleanup

    Hi Nils.

    It's great work you've done, creating a web UI for GLAuth.

    I took the liberty of doing a bit of cleanup. Nothing extraordinary, since your code is already fully functional :)

    opened by Fusion 1
  • Provide a sample docker-compose file that includes launching a glauth server?

    Provide a sample docker-compose file that includes launching a glauth server?

    This is the one I came up with

    version: '3.7'
    services:
      ui:
        image: glauthui:latest
        container_name: glauthui
        restart: unless-stopped
        ports:
          - 801:5000
        volumes:
          # Mount Folder that contains DB and config file outside the container
          - 'glauth:/home/ldap/db'
        environment:
          - SECRET_KEY=mysuperlongsecretkeythatnobodywillguess
          # MAIL CONFIG
          #- MAIL_SERVER=mail.example.com
          #- MAIL_PORT=587
          #- MAIL_USE_TLS=1
          #- MAIL_USERNAME=username
          #- MAIL_PASSWORD=password
          #- [email protected]
      glauth:
        image: glauth/glauth
        command: glauth -c /config/
    
    volumes:
      glauth:
    

    Should make it easier for people to get set up. I'm not sure I have it set up properly though.

    opened by traverseda 1
  • Encrypt passwords using bcrypt, keep sha256 for backwards compatibility

    Encrypt passwords using bcrypt, keep sha256 for backwards compatibility

    The number of rounds can be specified by BCRYPT_ROUNDS environment variable. The default value is 14, as it takes 600 ms on my machine. As we currently only support bcrypt and plain sha256 hashes, we can distinguish them by the leading '$' of bcrypt hashes. Upgrading hashes on login is not yet implemented.

    opened by Jonny007-MKD 0
  • Organize config, update dependencies

    Organize config, update dependencies

    • Update Flask to 2.1, together with related dependencies
    • Replace deprecated flask-mail (did hit a bug) with maintained flask-mailman
    • Add BEHAVIORS_IGNORE_CAPABILITIES for future use
    • Glauth-UI configuration is now separate from Flask appconfig to reduce risk of undocumenet behavior
      • Several of the flask- packages have a lot of config under the same namespace, some of it undocumented
    opened by threadnought 0
  • Optimize docker image

    Optimize docker image

    • Add PUID build arg to set user id in resulting image
    • Add postgres dependencies
    • Only give write access to db and logs folders
    • Optimize build for image size (reduced from ~700MB to 140MB)
    opened by threadnought 0
  • Replaced unixid with uid-/gidnumber (glauth v2.0)

    Replaced unixid with uid-/gidnumber (glauth v2.0)

    Hey Nils,

    since glauth v2.0.0 complains about unixid being deprecated I replaced it with uidnumber and gidnumber accordingly.

    To be consistent, I also changed the db column names in the group and user table. So if you have an existing setup, you need to rename the sqlite columns using dbeaver for example.

    opened by zeo101 2
Owner
Nils Thiele
Nils Thiele
flask-apispec MIT flask-apispec (🥉24 · ⭐ 520) - Build and document REST APIs with Flask and apispec. MIT

flask-apispec flask-apispec is a lightweight tool for building REST APIs in Flask. flask-apispec uses webargs for request parsing, marshmallow for res

Joshua Carp 617 Dec 30, 2022
Library books management program, built with Flask, Python

Library books management program, With many features and good User Interface. built with Flask, Python. (Include Screenshots) and documentation on how to run it! Thank you :)

Thierry Mugisha 1 May 3, 2022
Search users in Github. Created with Flask, PipEnv, Heroku and free time.

Search in Github Here search for users in Github and other stuff! This app is working with, Data Github API BackEnd Flask Language Python Package mana

AmirHossein Mohammadi 12 Jan 16, 2022
flask-reactize is a boostrap to serve any React JS application via a Python back-end, using Flask as web framework.

flask-reactize Purpose Developing a ReactJS application requires to use nodejs as back end server. What if you want to consume external APIs: how are

Julien Chomarat 4 Jan 11, 2022
Flask Sitemapper is a small Python 3 package that generates XML sitemaps for Flask applications.

Flask Sitemapper Flask Sitemapper is a small Python 3 package that generates XML sitemaps for Flask applications. This allows you to create a nice and

null 6 Jan 6, 2023
Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application.

Flask-Bcrypt Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application. Due to the recent increased prevelance of

Max Countryman 310 Dec 14, 2022
Flask-Rebar combines flask, marshmallow, and swagger for robust REST services.

Flask-Rebar Flask-Rebar combines flask, marshmallow, and swagger for robust REST services. Features Request and Response Validation - Flask-Rebar reli

PlanGrid 223 Dec 19, 2022
Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application.

Flask-Bcrypt Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application. Due to the recent increased prevelance of

Max Countryman 282 Feb 11, 2021
Flask-Starter is a boilerplate starter template designed to help you quickstart your Flask web application development.

Flask-Starter Flask-Starter is a boilerplate starter template designed to help you quickstart your Flask web application development. It has all the r

Kundan Singh 259 Dec 26, 2022
Brandnew-flask is a CLI tool used to generate a powerful and mordern flask-app that supports the production environment.

Brandnew-flask is still in the initial stage and needs to be updated and improved continuously. Everyone is welcome to maintain and improve this CLI.

brandonye 4 Jul 17, 2022
Flask Project Template A full feature Flask project template.

Flask Project Template A full feature Flask project template. See also Python-Project-Template for a lean, low dependency Python app. HOW TO USE THIS

Bruno Rocha 96 Dec 23, 2022
A Fast API style support for Flask. Gives you MyPy types with the flexibility of flask

Flask-Fastx Flask-Fastx is a Fast API style support for Flask. It Gives you MyPy types with the flexibility of flask. Compatibility Flask-Fastx requir

Tactful.ai 18 Nov 26, 2022
Flask-app scaffold, generate flask restful backend

Flask-app scaffold, generate flask restful backend

jacksmile 1 Nov 24, 2021
Flask pre-setup architecture. This can be used in any flask project for a faster and better project code structure.

Flask pre-setup architecture. This can be used in any flask project for a faster and better project code structure. All the required libraries are already installed easily to use in any big project.

Ajay kumar sharma 5 Jun 14, 2022
Pf-flask-rest-com - Flask REST API Common Implementation by Problem Fighter Library

In the name of God, the Most Gracious, the Most Merciful. PF-Flask-Rest-Com Docu

Problem Fighter 3 Jan 15, 2022
Open-source Flask Sample built on top of flask-dance library

Open-source Flask Sample built on top of flask-dance library. The project implements the social login for Github and Twitter - Originally coded by TestDriven.IO.

App Generator 4 Jul 26, 2022
Flask-redmail - Email sending for Flask

Flask Red Mail: Email Sending for Flask Flask extension for Red Mail What is it?

Mikael Koli 11 Sep 23, 2022
Flask-template - A simple template for make an flask api

flask-template By GaGoU :3 a simple template for make an flask api notes: you ca

GaGoU 2 Feb 17, 2022