Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: v0.4.3: "Downloads" inaccessible when using LDAP authentication #591

Open
2 tasks done
Salvoxia opened this issue Nov 11, 2023 · 5 comments
Open
2 tasks done
Labels
help wanted Extra attention is needed question Further information is requested

Comments

@Salvoxia
Copy link

I've read the documentation

Operating System

Docker

Your Bug Report

Describe the bug

I'm running tubearchivist in Docker and use LDAP for authentication.
After upgrading to v0.4.3 I noticed the "Downloads" menu item in TA was missing.
When manually navigating to https://tubearchivist.mydomain.com/downloads I was redirected to the login page with the URL https://tubearchivist.mydomain.com/login/?next=/downloads/. After logging in again I ended up in a login loop with the same URL.
After disabling LDAP authentication, logging out and back in with the django credentials the "Downloads" menu item re-appeared and worked as expected.

Steps To Reproduce

  • Set up Tubearchivist v0.4.3 to use LDAP authentication
  • Log in
  • See "Donloads" item missing from the top navigation bar
  • Manually browse to https://tubearchivist.mydomain.com/login/?next=/downloads/
  • Stuck in login loop

Expected behavior

"Downloads" is displayed and functioning also when using LDAP authentication

The Docker logfiles did not change from the point the container finished starting up until after reproducing the bug with DJANGO_DEBUG=True.

Best Regards,
Salvoxia

Relevant log output

Operations to perform:
  Apply all migrations: admin, auth, authtoken, contenttypes, home, sessions
Running migrations:
  No migrations to apply.
                         ....  .....
                  ...'',;:cc,. .;::;;,'...
               ..,;:cccllclc,  .:ccllllcc;,..
            ..,:cllcc:;,'.',.  ....'',;ccllc:,..
          ..;cllc:,'..                ...,:cccc:'.
         .;cccc;..                        ..,:ccc:'.
       .ckkkOkxollllllllllllc.      .,:::;.  .,cclc;
      .:0MMMMMMMMMMMMMMMMMMMX:     .cNMMMWx.   .;clc:
     .;lOXK0000KNMMMMX00000KO;     ;KMMMMMNl.   .;ccl:,.
     .;:c:'.....kMMMNo........    'OMMMWMMMK:    '::;;'.
   .......     .xMMMNl           .dWMMXdOMMMO'   ........
   .:cc:;.     .xMMMNc          .lNMMNo.:XMMWx.    .:cl:.
   .:llc,.     .:xxxd,          ;KMMMk. .oWMMNl.   .:llc'
   .cll:.     .;:;;:::,.       'OMMMK:';''kWMMK:   .;llc,
   .cll:.     .,;;;;;;,.     .,xWMMNl.:l:.;KMMMO'  .;llc'
   .:llc.      .cOOOk;      .lKNMMWx..:l:..lNMMWx. .:llc'
   .;lcc,.     .xMMMNc      :KMMMM0, .:lc. .xWMMNl.'ccl:.
    .cllc.     .xMMMNc     'OMMMMXc...:lc...,0MMMKl:lcc,.
    .,ccl:.    .xMMMNc    .xWMMMWo.,;;:lc;;;.cXMMMXdcc;.
     .,clc:.   .xMMMNc   .lNMMMWk. .':clc:,. .dWMMW0o;.
      .,clcc,. .ckkkx;   .okkkOx,    .';,.    'kKKK0l.
       .':lcc:'.....      .  ..            ..,;cllc,.
         .,cclc,....                     ....;clc;..
          ..,:,..,c:'..              ...';:,..,:,.
            ....:lcccc:;,'''.....'',;;:clllc,....
               .'',;:cllllllccccclllllcc:,'..
                   ...'',,;;;;;;;;;,''...
                            .....
#######################
#  Environment Setup  #
#######################
[1] checking expected env vars
    ✓ all expected env vars are set
[2] check ES user overwrite
    ✓ ES user is set to elastic
[3] check TA_PORT overwrite
    TA_PORT is not set
[4] check TA_UWSGI_PORT overwrite
    TA_UWSGI_PORT is not set
[5] check ENABLE_CAST overwrite
    ENABLE_CAST is not set
[6] create superuser
    superuser already created
#######################
#  Connection check   #
#######################
[1] connect to Redis
    ✓ Redis connection verified
[2] set Redis config
    ✓ Redis config set
[3] connect to Elastic Search
    ... waiting for ES [0/24]
    ✓ ES connection established
[4] Elastic Search version check
    ✓ ES version check passed
[5] check ES path.repo env var
    ✓ path.repo env var is set
#######################
#  Application Start  #
#######################
[1] set new config.json values
    no new config values
[2] create expected cache folders
    ✓ expected folders created
[3] clear leftover locks in redis
    no locks found
[4] clear task leftovers
[5] clear leftover files from dl cache
clear download cache
    no files found
[6] check for first run after update
    no new update found
[MIGRATION] validate index mappings
ta_config index is created and up to date...
ta_channel index is created and up to date...
ta_video index is created and up to date...
ta_download index is created and up to date...
ta_playlist index is created and up to date...
ta_subtitle index is created and up to date...
ta_comment index is created and up to date...
[MIGRATION] setup snapshots
snapshot: run setup
snapshot: repo ta_snapshot already created
snapshot: policy is set.
snapshot: last snapshot is up-to-date
[MIGRATION] move user configuration to ES
    ✓ Settings for user '2' migrated to ES
    ✓ Settings for all users migrated to ES
########################
# Filesystem Migration #
########################
    no channel migration needed
[uWSGI] getting INI configuration from uwsgi.ini
*** Starting uWSGI 2.0.23 (64bit) on [Sat Nov 11 22:12:09 2023] ***
compiled with version: 10.2.1 20210110 on 09 November 2023 02:44:40
os: Linux-5.15.107+truenas #1 SMP Mon Jun 19 11:49:06 UTC 2023
nodename: 76b700360d39
machine: x86_64
clock source: unix
detected number of CPU cores: 20
current working directory: /app
writing pidfile to /tmp/project-master.pid
detected binary path: /root/.local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
your memory page size is 4096 bytes
detected max file descriptor number: 1048576
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to TCP address :8080 fd 3
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
Python version: 3.11.3 (main, May 23 2023, 13:34:03) [GCC 10.2.1 20210110]
*** Python threads support is disabled. You can enable it with --enable-threads ***
Python main interpreter initialized at 0x7f95371a7558
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 154032 bytes (150 KB) for 1 cores
*** Operational MODE: single process ***
celery beat v5.3.4 (emerald-rush) is starting.
WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0x7f95371a7558 pid: 25 (default app)
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** 
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 25)
spawned uWSGI worker 1 (pid: 53, cores: 1)
/root/.local/lib/python3.11/site-packages/celery/platforms.py:829: SecurityWarning: You're running the worker with superuser privileges: this is
absolutely not recommended!
Please specify a different user using the --uid option.
User information: uid=0 euid=0 gid=0 egid=0
  warnings.warn(SecurityWarning(ROOT_DISCOURAGED.format(
__    -    ... __   -        _
LocalTime -> 2023-11-11 22:12:10
Configuration ->
    . broker -> redis://archivist-redis:6379//
    . loader -> celery.loaders.app.AppLoader
    . scheduler -> celery.beat.PersistentScheduler
    . db -> /celerybeat-schedule
    . logfile -> [stderr]@%INFO
    . maxinterval -> 5.00 minutes (300s)
[2023-11-11 22:12:10,580: INFO/MainProcess] beat: Starting...
 
 -------------- celery@76b700360d39 v5.3.4 (emerald-rush)
--- ***** ----- 
-- ******* ---- Linux-5.15.107+truenas-x86_64-with-glibc2.31 2023-11-11 22:12:10
- *** --- * --- 
- ** ---------- [config]
- ** ---------- .> app:         tasks:0x7fd12596d090
- ** ---------- .> transport:   redis://archivist-redis:6379//
- ** ---------- .> results:     redis://archivist-redis:6379/
- *** --- * --- .> concurrency: 20 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** ----- 
 -------------- [queues]
                .> celery           exchange=celery(direct) key=celery
                
[tasks]
  . check_reindex
  . download_pending
  . extract_download
  . index_playlists
  . manual_import
  . rescan_filesystem
  . restore_backup
  . resync_thumbs
  . run_backup
  . subscribe_to
  . thumbnail_check
  . update_subscribed
  . version_check
[2023-11-11 22:12:11,265: WARNING/MainProcess] /root/.local/lib/python3.11/site-packages/celery/worker/consumer/consumer.py:507: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine
whether broker connection retries are made during startup in Celery 6.0 and above.
If you wish to retain the existing behavior for retrying connections on startup,
you should set broker_connection_retry_on_startup to True.
  warnings.warn(
[2023-11-11 22:12:11,269: INFO/MainProcess] Connected to redis://archivist-redis:6379//
[2023-11-11 22:12:11,269: WARNING/MainProcess] /root/.local/lib/python3.11/site-packages/celery/worker/consumer/consumer.py:507: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine
whether broker connection retries are made during startup in Celery 6.0 and above.
If you wish to retain the existing behavior for retrying connections on startup,
you should set broker_connection_retry_on_startup to True.
  warnings.warn(
[2023-11-11 22:12:11,270: INFO/MainProcess] mingle: searching for neighbors
[2023-11-11 22:12:12,277: INFO/MainProcess] mingle: all alone
[2023-11-11 22:12:12,299: INFO/MainProcess] celery@76b700360d39 ready.
expire session in 172800 secs

Anything else?

No response

@bbilly1
Copy link
Member

bbilly1 commented Nov 12, 2023

This would suggest that you have become an view only user, see latest release notes for that. Validation expects your user to be in the admin group, to allow you to access all resources.

@DanielBatteryStapler can you look into this? Do we need to update the docs?

@bbilly1 bbilly1 added help wanted Extra attention is needed question Further information is requested labels Nov 12, 2023
@Salvoxia
Copy link
Author

Salvoxia commented Nov 12, 2023

I suspected something along that lines, without realizing the full implications of what "read only user" actually meant.
I did check the LDAP Authentication Docs before posting to see if there were any new variables, but nothing new is listed there.

At the moment it seems the only way to get Superuser status with LDAP is to disable it, log in with a djago super user, edit the LDAP user to set Superuser status, and enable LDAP again. This is a bit cumbersome, but a workaround.

So I guess this evolves more into a feature request to add additional LDAP filters to determine superuser/staff status and LDAP group <> TA group mapping. That would be awesome. :)

@DanielBatteryStapler
Copy link
Contributor

DanielBatteryStapler commented Nov 15, 2023

Sorry for the delay, but I'm also not much help here. I've worked on adding LDAP support to other Django projects and I've always had some issues with trying to get user permissions to work properly. Sometimes(and I really do mean sometimes, I can't figure out why for some projects it refuses to work) it works okay based on LDAP groups, but there always seems to be something weird going on. Specifically, I have been unable to figure out how to give superuser status to LDAP users by default, or really any other specific user permission level. I've tried editing Django's User prototype but nothing I seem to do works. I agree it would be great to have more controls over how LDAP interacts with Django's permissions system to iron this all out, but believe me when I say I've tried everything I could think of and I couldn't get it to work -- though I will admit I not an expect in Python or Django so I'm sure for somebody else it's possible.

@Salvoxia Your cumbersome work around is exactly what I have to do with on another project I helped add LDAP support to ArchiveBox/ArchiveBox#1214 . If anybody finds a fix for the LDAP-Django permissions on this project I'll port them over to ArchiveBox as well. I've just accepted having to do a whole rigmarole when setting up new users as the price I have to pay for LDAP accounts to work on Django, it's still worth it to me.

@bbilly1
Copy link
Member

bbilly1 commented Nov 15, 2023

The docs here gives example for AUTH_LDAP_USER_FLAGS_BY_GROUP to map to django's is_superuser, this also suggests that you still need the ModelBackend too?

https://github.com/django-auth-ldap/django-auth-ldap#example-configuration

@jmerdich
Copy link

jmerdich commented Feb 5, 2024

Adding temporary instructions until there is some way to make LDAP users that are not read-only users.

  1. In a shell, run python manage.py shell
  2. Run the following commands for your own account (or some admin):
from django.contrib.auth import get_user_model
User = get_user_model()
user = User.objects.get(name="myname")
user.is_staff = True
user.is_admin = True
user.is_superuser = True
user.save()
  1. This account can now both add videos and other users via http://yoururl/admin under 'Accounts' by adding them as staff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants