Enforcing SSO and subscription options

Contrary to the messages I found in the archive, rather trying to delete or remove the social login portion of the sign in page, I'm looking to see if there's any way to isolate the third-party login section and prevent local account sign in and sign up. This way, we can ensure that the people within our organization are using a stronger auth method that prioritizes MFA, rather than just username/password.
To do this, our plan is to block signups using "ACCOUNT_ADAPTER = 'django_mailman3.views.user_adapter.DisableSignupAdapter'" and to remove the portions of the login template such that the username/password/forgot password fields are removed, leaving just the button to our SSO instance. I'm anticipating that this should be sufficient to block username/password sign ins, and is resistant to page manipulation due to CSRF tokens, but I wanted to ask to see if there was a better way, like an official configuration (which I have not found yet). I did see that there is the SOCALACCOUNT_ONLY option, as provided by allauth (https://docs.allauth.org/en/latest/socialaccount/configuration.html), but that broke any attempt to display the sign in page, and I'm assuming is not supported with the current version of MM3. Is my plan to modify the templates viable?
Additionally, because external users would not have access to their own dashboards within the web UI, and since we are planning on disabling anonymous subscriptions with "SHOW_ANONYMOUS_SUBSCRIBE_FORM=False", the only two viable ways to subscribe to a list for them would be:
- Send a request directly to the list owner or a superadmin to subscribe/unsubscribe the address
- Allow email commands to subcribe/unsubscribe users (i.e. $LISTNAME-join@$DOMAIN)
Given the discussions on disabling the anonymous subscription form, are the email commands a less spam-susceptible solution or are they just as vulnerable as the form?
Thanks

dlb-ml--- via Mailman-users writes:
I'm looking to see if there's any way to isolate the third-party login section and prevent local account sign in and sign up. This way, we can ensure that the people within our organization are using a stronger auth method that prioritizes MFA, rather than just username/password.
This is really a Django/allauth question. I strongly recommend you ask there. Maybe Mark knows more, but my own experience with it is limited, and the client specified the setup, I just implemented it.
I did see that there is the SOCALACCOUNT_ONLY option, as provided by allauth (https://docs.allauth.org/en/latest/socialaccount/configuration.html), but that broke any attempt to display the sign in page,
My experience was using Shibboleth to authenticate to Apache, require authenticated user for all Mailman and Django locations, and Apache would communicate the authenticated user ID directly to Postorius. You could visit the page, but because you were already authenticated, you had to log out to log in. But -- Catch-22 -- that access would go through Apache and log you in.
assuming [SOCIALACCOUNT_ONLY] is not supported with the current version of MM3.
AFAIK, there's no code in Postorius that's specific to processing authentication -- that's all done by Django or Django plugins, and controlled by the standard Django and allauth parameters. So it's not something Mailman is related to supporting. This is a question of what allauth, and possibly Django core, supports. It's possible that Mailman defaults to a configuration that messes up Django's support, but if so I would bet that somebody with deep knowledge of how allauth works could tell you how to get the effect you want.
Is my plan to modify the templates viable?
It's not clear what your goal is. If it's just to keep typical users on the straight and narrow, yes, that should work. But as far as I know, a competent user who is mischievous or malicious can probably craft requests to successfully access any locations that are not disabled in code or protected by the frontend webserver. Disabling the signup adapter will definitely make mischief much harder, but I can't promise it's impossible.
But if you have a SSO system with an organization-specific IDP or a database of 3rd-party accounts with Google or whatever, I would think you'd want to use that as the source of ground truth directly, as I described my experience above, rather than creating a separate credientials database in Django.
Given the discussions on disabling the anonymous subscription form, are the email commands a less spam-susceptible solution or are they just as vulnerable as the form?
The whole point of email commands was to allow anonymous signups (more precisely, pseudonymous signups tied to a mailbox). If you don't want "anonymous" signups, you don't want to enable the email commands.

Thank you for the reply. Ultimately, I ended up digging deeper into the allauth docs, per your suggestion, and I went a little bit further with the "SOCIALACCOUNT_ONLY" option. It turns out that the errors I were seeing were related to the sign up button referencing a view that didn't exist. I solved this in an admittedly ugly way, by removing the sign up button from the postorius and hyperkitty templates. This will make upgrades a pain, as I'll have to account for this in the future, but it appears to be exactly what I was looking for.
Thank you for your insight!
The whole point of email commands was to allow anonymous signups (more precisely, pseudonymous signups tied to a mailbox). If you don't want "anonymous" signups, you don't want to enable the email commands.
Also, thank you for this. I figured this was the case, but I wanted to make sure.

via Mailman-users writes:
Thank you for the reply. Ultimately, I ended up digging deeper into the allauth docs, per your suggestion, and I went a little bit further with the "SOCIALACCOUNT_ONLY" option. It turns out that the errors I were seeing were related to the sign up button referencing a view that didn't exist.
You have to do this, I suspect (I am unsure that removing the reference from urls.py would protect you from A Sufficiently Smart Miscreant, and if it did you'd still get the error, so why not remmove the code and remove all doubt!)
I solved this in an admittedly ugly way, by removing the sign up button from the postorius and hyperkitty templates.
You do not have to do it this way. There is a search path for templates, and you can remove those buttons from copies stored in a directory earlier in the path. I use /etc/mailman3/templates/..., but they can go anywhere convenient that won't be overwritten by an upgrade. The worst that could happen is the copies get removed, and then you get the error, which you fix.

Hello,
did you manage to disable the local registration (with django accounts)? I am trying to get rid of these locally registered accounts as well. Background: I only want authorized accounts (provided by our SSO) to be owners or moderators with the ability to manage lists... So, if I block all other (local django accounts) a list-owner might be able to enter an account with an external e-mail address as another owner, but the external account will not able to sign in via web ui...and to manage the list! (A list member can be any (external) user...I only care about moderators/admins and moderators) Questions: Is this a viable approach, or do I make a conceptual mistake here? Is there another way to prevent non (sso-)authorized from becoming an owner? Remark: I followed your way in this thread and made copies of various template files in a seperate location. (I run a venv installation on Ubuntu) My central configuration files are under /etc/mailman3 (mailman.cfg, mailman-hyperkitty.cfg, settings.py and uwsgi.ini) I set the following options in settings.py: TEMPLATES[0]['DIRS'].append('/etc/mailman3/templates') SOCIALACCOUNT_ONLY = True ACCOUNT_EMAIL_VERIFICATION = EmailVerificationMethod.NONE ACCOUNT_ADAPTER = 'django_mailman3.views.user_adapter.DisableSignupAdapter' This got me over the following error: django.urls.exceptions.NoReverseMatch: Reverse for 'account_signup' not found. 'account_signup' is not a valid view function or pattern name But a new error occured: django.urls.exceptions.NoReverseMatch: Reverse for 'account_reset_password' not found. 'account_reset_password' is not a valid view function or pattern name. When I scan the installation directory for this ("account_reset_password") I find it in several places, mostly non template files... So there seems no way to get rid of this error without modifying code... This is nothing one should do - it makes the whole software and its updates unmanageable... So it seems to be a kind of a dead end...
Is there any way to get approach (only sso-authorized owners/admins/moderators) working?
Kind regards
Christian
P.S. Sorry for hijacking this thread, but it seems the right place for my questions... :-)

Christian Schneider writes:
did you manage to disable the local registration (with django accounts)? I am trying to get rid of these locally registered accounts as well.
The easist way to do this is to require SSO authentication to access webapps (this can be done in the front-end webserver), then use the identity provider to pass the authenticated user to Django. This can be done with a small custom extension to Django, and no modifications to code provided by Mailman or Django. Just registering the extension in the usual way.
(A list member can be any (external) user...I only care about moderators/admins and moderators)
This is very hard. Django authenticates *users*, users possess *roles*, and roles are authorized to access *resources*. However, owners can add roles to other users to make them moderators or even owners -- but this cannot trigger a change in the users' authentication process. So if owner A decides to make external user B a moderator, B will still authenticate however they did previously.
Of course you can decide you trust all your owners and superusers not to do that. I'm just saying if they decide to do such a thing nothing in Mailman suite will stop them.
SOCIALACCOUNT_ONLY = True ACCOUNT_EMAIL_VERIFICATION = EmailVerificationMethod.NONE ACCOUNT_ADAPTER = 'django_mailman3.views.user_adapter.DisableSignupAdapter'
I don't think these settings do what you want (but I'm not a Django expert). In particular, you must disable all "unofficial" socialauth providers, which is unlikely to make your users happy.
Also, I think this disables web signups and account management for everyone who isn't in your official identity provider. Finally, I think EMAIL_VERIFICATION refers to the normal process of sending a one-time key to the address, to confirm that the anonymous person who is trying to sign up the email can read that mailbox, not to login authentication. If so, that would be bad, as anyone could claim any email address. (Could be wrong, though.)
Is there any way to get approach (only sso-authorized owners/admins/moderators) working?
If you're going to allow "external" users, the approaches that pretty clearly will work require substantial and tricky code changes. It might be possible to mask the "administrative" links in the front-end webserver and require SSO authentication to "see" them, but that's never a very robust solution. If you're willing to manage identities of all users, it's straightforward.
-- GNU Mailman consultant (installation, migration, customization) Sirius Open Source https://www.siriusopensource.com/ Software systems consulting in Europe, North America, and Japan

Dear Stephen,
thank you very much for this detailed and elaborated answer. I am very happy to have this well-founded evaluation of my approach!
Your rating will give me a good stand in discussion with my team leader ;-) to drop the constraint of only having SSO authorized moderators and admins...
Fullfilling this constraint would involve a big hassle in implementation and even more in maintenance considering future updates...so in my opinion this is not viable!
Thank you!
Kind regards
Christian

Christian Schneider writes:
thank you very much for this detailed and elaborated answer.
You're welcome. I'm sorry I couldn't be more optimistic about implementing the approach in Mailman.
At some point we in the Mailman project should probably consider changing the authorization model. The idea would be basically what you asked for: allow more powerful levels of authorization to require more secure forms of authentication. But that's a very big project because of the pervasive presence of authorization code throughout the administrative application, and I guess it would require changes to Django itself to be robust.
-- GNU Mailman consultant (installation, migration, customization) Sirius Open Source https://www.siriusopensource.com/ Software systems consulting in Europe, North America, and Japan
Teilnehmer (4)
-
Christian Schneider
-
dlb-ml@anl.gov
-
Stephen J. Turnbull
-
Stephen J. Turnbull