wallabag icon indicating copy to clipboard operation
wallabag copied to clipboard

Wallabag 2.6.10 no longer works correctly with LDAP configured

Open orhtej2 opened this issue 1 year ago • 8 comments

Environment

  • Version: 2.6.10
  • Installation: via attempted upgrade in YunoHost (see https://github.com/YunoHost-Apps/wallabag2_ynh/pull/225)
  • PHP version: 8.2.27
  • OS: Debian Bookworm
  • Database: PostgreSQL
  • Parameters: Not sure?
My app/config/parameters.yml are unmodified since 2.5.4 (working in that version, LMK if you need the full lot).

app/config/services.yml:

# snip, added at the bottom:
  Symfony\Component\Ldap\Ldap:
      arguments: ['@Symfony\Component\Ldap\Adapter\ExtLdap\Adapter']
      tags: [ldap]

  Symfony\Component\Ldap\Adapter\ExtLdap\Adapter:
      arguments:
          - host: localhost

  yunohost.logout_success_handler:
      class: Wallabag\YunoHostBundle\Security\LogoutSuccessHandler

app/config/security.yml:

security:
# snip
  providers:
  # snip, added last
      yunohost_users:
          ldap:
              service: Symfony\Component\Ldap\Ldap
              base_dn: ou=users,dc=yunohost,dc=org
              search_dn:
              search_password:
              filter: (&(uid={username})(objectClass=posixAccount))
              default_roles: ROLE_USER
              uid_key: uid

# snip
  firewalls:
  # snip
  
  secured_area:
  # snip
        http_basic_ldap:
              provider: yunohost_users
              service: Symfony\Component\Ldap\Ldap
              dn_string: "uid={username},ou=users,dc=yunohost,dc=org"        

What steps will reproduce the bug?

Issue is when you log in with Authorization header bearing your username and password you're greeted with HTTP/500 saying:

500: Internal Server Error

Attempted to call an undefined method named "getId" of class "Symfony\Component\Ldap\Security\LdapUser".

Symfony's debugger points to src/Wallabag/CoreBundle/Controller/EntryController.php, line 298 that indeed reads $this->getUser()->getId().

Glad to provide additional details if needed.

orhtej2 avatar Jan 18 '25 22:01 orhtej2

What version did it work on before?

j0k3r avatar Jan 20 '25 08:01 j0k3r

Hi, as mentioned in the description, 2.5.4, which I believe came before Symfony 3->4 upgrade.

orhtej2 avatar Jan 20 '25 09:01 orhtej2

LDAP is not officially supported on wallabag ...

nicosomb avatar Jan 20 '25 13:01 nicosomb

What YunoHost does it it clones LDAP users as normal Wallabag users and uses LDAP only for checking the credentials. This used to work before, but I see there was a major refactor under the hood so evidently LDAP user entity is now slipping through and making its way to the controllers.

Perhaps there's an easy remedy you can recommend here, even if we have to patch it in on YunoHost side?

orhtej2 avatar Jan 23 '25 21:01 orhtej2

@orhtej2 Please, share your experience – how did you manage to log in via LDAP and create new users in Wallabag? I would be very grateful for your response.

Thank you for your answer.

arbdevml avatar Mar 24 '25 01:03 arbdevml

I am trying to achieve Wallabag login via LDAP provider - https://github.com/lldap/lldap

Here are my files:

docker-compose.yml

wallabag:
    build:
        context: /home/docker/wallabag/
        dockerfile: Dockerfile
    image: wallabag
#    image: wallabag/wallabag:2.5.4
    container_name: wallabag
    environment:
        - SYMFONY__ENV__DOMAIN_NAME=https://wallabag.inner.loc
        - SYMFONY__ENV__BASE_PATH=https://wallabag.inner.loc/
        - SYMFONY__ENV__FOSUSER_REGISTRATION=true
    volumes:
        - /home/docker/wallabag/app/config/security.yml:/var/www/wallabag/app/config/security.yml:ro
        - /home/docker/wallabag/app/config/services.yml:/var/www/wallabag/app/config/services.yml:ro
    ports:
        - 80:80
    restart: "no"

Dockerfile

FROM wallabag/wallabag:2.5.4
RUN apk add --no-cache openldap-dev php81-ldap openldap-clients
ENV PATH="${PATH}:/var/www/wallabag/bin"
WORKDIR /var/www/wallabag
RUN composer require symfony/ldap:^3.4 --no-update
RUN chown -R nobody:nobody /var/www/wallabag
ENV SYMFONY_ENV=prod
ENV COMPOSER_NO_DEV=1
EXPOSE 80
ENTRYPOINT ["/entrypoint.sh"]
CMD ["wallabag"]

services.yml

parameters:
    lexik_form_filter.get_filter.doctrine_orm.class: Wallabag\CoreBundle\Event\Subscriber\CustomDoctrineORMSubscriber

services:
    Symfony\Component\Ldap\Ldap:
        arguments: ['@Symfony\Component\Ldap\Adapter\ExtLdap\Adapter']
        tags: [ldap]

    Symfony\Component\Ldap\Adapter\ExtLdap\Adapter:
        arguments:
            - host: lldap
              port: 3890
              encryption: none
              options:
                 protocol_version: 3
                 referrals: false

    twig.extension.text:
        class: Twig_Extensions_Extension_Text
        tags:
            - { name: twig.extension }

    wallabag.twig_extension:
        class: Wallabag\CoreBundle\Twig\WallabagExtension
        public: false
        arguments:
            - "@wallabag_core.entry_repository"
            - "@wallabag_core.tag_repository"
            - "@security.token_storage"
            - "%wallabag_core.cache_lifetime%"
            - "@translator"
            - "%kernel.root_dir%"
        tags:
            - { name: twig.extension }

    wallabag.twig_matomo_extension:
        class: MatomoTwigExtension\MatomoTwigExtension
        public: false
        tags:
            - { name: twig.extension }

    wallabag.locale_listener:
        class: Wallabag\CoreBundle\Event\Listener\LocaleListener
        arguments: ["%kernel.default_locale%"]
        tags:
            - { name: kernel.event_subscriber }

    wallabag.user_locale_listener:
        class: Wallabag\CoreBundle\Event\Listener\UserLocaleListener
        arguments: ["@session"]
        tags:
            - { name: kernel.event_listener, event: security.interactive_login, method: onInteractiveLogin }

    craue_config_cache_provider:
        class: Symfony\Component\Cache\Adapter\FilesystemAdapter
        public: false
        arguments:
            - 'craue_config'
            - 0
            - '%kernel.cache_dir%'

security.yml

security:
    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

    role_hierarchy:
        ROLE_ADMIN: ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    providers:
        wallabag_users:
            id: fos_user.user_provider.username_email
        ldap_users:
            ldap:
                service: Symfony\Component\Ldap\Ldap
                base_dn: ou=people,dc=inner,dc=loc
                search_dn: uid=wallabagldap,ou=people,dc=inner,dc=loc
                search_password: wallabagpass
                filter: "(&(uid={username})(memberOf=cn=wallabag-users,ou=groups,dc=inner,dc=loc))"
                default_roles: ROLE_USER
                uid_key: uid

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

        oauth_token:
            pattern: ^/oauth/v2/token
            security: false

        api:
            pattern: ^/api/.*
            fos_oauth: true
            stateless: true
            anonymous: true
            provider: ldap_users

        login_firewall:
            logout_on_user_change: true
            pattern: ^/login$
            anonymous: true

        secured_area:
            logout_on_user_change: true
            pattern: ^/
            form_login:
                provider: wallabag_users
                csrf_token_generator: security.csrf.token_manager

#            form_login_ldap:
#                provider: ldap_users
#                service: Symfony\Component\Ldap\Ldap
#                dn_string: "uid={username},ou=people,dc=inner,dc=loc"

            http_basic_ldap:
                provider: ldap_users
                service: Symfony\Component\Ldap\Ldap
                dn_string: "uid={username},ou=people,dc=inner,dc=loc"

            anonymous: true
            remember_me:
                secret: "%secret%"
                lifetime: 31536000
                path: /
                domain: ~

            logout:
                path: /logout
                target: /

            two_factor:
                provider: ldap_users
                auth_form_path: 2fa_login
                check_path: 2fa_login_check

    access_control:
        - { path: ^/api/(doc|version|info|user), roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/logout, roles: [IS_AUTHENTICATED_ANONYMOUSLY, IS_AUTHENTICATED_2FA_IN_PROGRESS] }
        - { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: /(unread|starred|archive|annotated|all).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/locale, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: /tags/(.*).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/feed, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: /(unread|starred|archive|annotated).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/share, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/settings, roles: ROLE_SUPER_ADMIN }
        - { path: ^/annotations, roles: ROLE_USER }
        - { path: ^/2fa, roles: IS_AUTHENTICATED_2FA_IN_PROGRESS }
        - { path: ^/users, roles: ROLE_SUPER_ADMIN }
        - { path: ^/ignore-origin-instance-rules, roles: ROLE_SUPER_ADMIN }
        - { path: ^/, roles: ROLE_USER }

I am able to log in using the default "wallabag" user, and users from the local database are working fine. However, when I try to log in with an LDAP user, I receive the following error:

Oops! An Error Occurred The server returned a "500 Internal Server Error". Something is broken. Please let us know what you were doing when this error occurred. We will fix it as soon as possible. Sorry for any inconvenience caused.

In the logs:

[2025-03-23 10:27:59] request.INFO: Matched route "fos_user_security_check". {"route":"fos_user_security_check","route_parameters":{"_controller":"FOS\\UserBundle\\Controller\\SecurityController::checkAction","_route":"fos_user_security_check"},"request_uri":"https://wallabag/login_check","method":"POST"} []
[2025-03-23 10:28:00] security.INFO: User has been authenticated successfully. {"username":"wbag"} []
[2025-03-23 10:28:00] request.CRITICAL: Uncaught PHP Exception Symfony\Component\Debug\Exception\UndefinedMethodException: "Attempted to call an undefined method named "getConfig" of class "Symfony\Component\Security\Core\User\User"." at /var/www/wallabag/src/Wallabag/CoreBundle/Event/Listener/UserLocaleListener.php line 32 {"exception":"[object] (Symfony\\Component\\Debug\\Exception\UndefinedMethodException(code: 0): Attempted to call an undefined method named \"getConfig\" of class \"Symfony\\Component\\Security\\Core\\User\\User\". at /var/www/wallabag/src/Wallabag/CoreBundle/Event/Listener\UserLocaleListener.php:32)"} []
[2025-03-23 10:28:00] security.DEBUG: Stored the security token in the session. {"key":"_security_secured_area"} []

@orhtej2, how did you enable wallabag 2.5.4 LDAP login successfully, please, share your experience?

arbdevml avatar Mar 24 '25 01:03 arbdevml

The method was pretty similar to yours, but you have to create a dummy Wallabag user that mirrors the user coming from LDAP (with whatever password, it's unused). Still, with 2.6 I'm getting the same error as you do.

orhtej2 avatar Mar 24 '25 10:03 orhtej2

I'm trying a little 🆙 in case someone has some clue about how to find a workaround on that topic 🙏

lapineige avatar Jun 23 '25 17:06 lapineige