2018-08-21 21:52:28 +02:00
|
|
|
# Authentication in the development environment
|
|
|
|
|
|
|
|
This page documents special notes that are useful for configuring
|
2019-11-08 22:56:53 +01:00
|
|
|
Zulip's various [authentication
|
|
|
|
methods](../production/authentication-methods.md) for testing in a
|
|
|
|
development environment.
|
|
|
|
|
2021-04-06 19:13:58 +02:00
|
|
|
Many of these authentication methods involve a complex interaction
|
|
|
|
between Zulip, an external service, and the user's browser. Because
|
|
|
|
browsers can (rightly!) be picky about the identity of sites you
|
|
|
|
interact with, the preferred way to set up authentication methods in a
|
|
|
|
development environment is provide secret keys so that you can go
|
|
|
|
through the real flow.
|
2019-11-08 22:56:53 +01:00
|
|
|
|
|
|
|
The steps to do this are a variation of the steps discussed in the
|
2021-04-07 06:18:46 +02:00
|
|
|
production documentation, including the comments in
|
2021-08-20 21:53:28 +02:00
|
|
|
`zproject/prod_settings_template.py`. The differences here are driven
|
2021-04-07 06:18:46 +02:00
|
|
|
by the fact that `dev_settings.py` is in Git, so it is inconvenient
|
2021-08-20 21:53:28 +02:00
|
|
|
for local [settings configuration](../subsystems/settings.md). As a
|
2021-04-07 06:18:46 +02:00
|
|
|
result, in the development environment, we allow setting certain
|
|
|
|
settings in the untracked file `zproject/dev-secrets.conf` (which is
|
|
|
|
also serves as `/etc/zulip/zulip-secrets.conf`).
|
2019-06-07 13:26:04 +02:00
|
|
|
|
2019-11-08 22:56:53 +01:00
|
|
|
Below, we document the procedure for each of the major authentication
|
|
|
|
methods supported by Zulip.
|
|
|
|
|
2020-08-11 01:47:54 +02:00
|
|
|
### Email and password
|
2019-11-08 22:56:53 +01:00
|
|
|
|
|
|
|
Zulip's default EmailAuthBackend authenticates users by verifying
|
|
|
|
control over their email address, and then allowing them to set a
|
2021-08-20 21:53:28 +02:00
|
|
|
password for their account. There are two development environment
|
2019-11-08 22:56:53 +01:00
|
|
|
details worth understanding:
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- All of our authentication flows in the development environment have
|
2019-11-08 22:56:53 +01:00
|
|
|
special links to the `/emails` page (advertised in `/devtools`),
|
|
|
|
which shows all emails that the Zulip server has "sent" (emails are
|
|
|
|
not actually sent by the development environment), to make it
|
|
|
|
convenient to click through the UI of signup, password reset, etc.
|
2021-08-20 21:45:39 +02:00
|
|
|
- There's a management command,
|
2021-09-08 00:23:24 +02:00
|
|
|
`manage.py print_initial_password username@example.com`, that prints
|
|
|
|
out **default** passwords for the development environment users.
|
|
|
|
Note that if you change a user's password in the development
|
2021-08-20 21:53:28 +02:00
|
|
|
environment, those passwords will no longer work. It also prints
|
2021-09-08 00:23:24 +02:00
|
|
|
out the user's **current** API key.
|
2017-11-02 21:05:21 +01:00
|
|
|
|
|
|
|
### Google
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Visit [the Google developer
|
2021-04-06 19:13:58 +02:00
|
|
|
console](https://console.developers.google.com) and navigate to "APIs
|
|
|
|
& services" > "Credentials". Create a "Project", which will correspond
|
|
|
|
to your dev environment.
|
2017-11-02 21:05:21 +01:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Navigate to "APIs & services" > "Library", and find the "Identity
|
2021-08-20 21:53:28 +02:00
|
|
|
Toolkit API". Choose "Enable".
|
2017-11-02 21:05:21 +01:00
|
|
|
|
2021-08-20 21:53:28 +02:00
|
|
|
- Return to "Credentials", and select "Create credentials". Choose
|
2017-11-02 21:21:38 +01:00
|
|
|
"OAuth client ID", and follow prompts to create a consent screen, etc.
|
|
|
|
For "Authorized redirect URIs", fill in
|
2019-02-02 16:51:26 +01:00
|
|
|
`http://zulipdev.com:9991/complete/google/` .
|
2017-11-02 21:05:21 +01:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- You should get a client ID and a client secret. Copy them. In
|
2019-02-02 16:51:26 +01:00
|
|
|
`dev-secrets.conf`, set `social_auth_google_key` to the client ID
|
|
|
|
and `social_auth_google_secret` to the client secret.
|
2017-11-02 21:05:21 +01:00
|
|
|
|
|
|
|
### GitHub
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Register an OAuth2 application with GitHub at one of
|
2021-02-22 16:47:53 +01:00
|
|
|
<https://github.com/settings/developers> or
|
|
|
|
<https://github.com/organizations/ORGNAME/settings/developers>.
|
2017-11-02 21:21:38 +01:00
|
|
|
Specify `http://zulipdev.com:9991/complete/github/` as the callback URL.
|
2017-11-02 21:05:21 +01:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- You should get a page with settings for your new application,
|
2021-08-20 21:53:28 +02:00
|
|
|
showing a client ID and a client secret. In `dev-secrets.conf`, set
|
2019-06-07 13:26:04 +02:00
|
|
|
`social_auth_github_key` to the client ID and `social_auth_github_secret`
|
|
|
|
to the client secret.
|
2018-08-18 05:11:19 +02:00
|
|
|
|
2020-01-31 18:19:53 +01:00
|
|
|
### GitLab
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Register an OAuth application with GitLab at
|
2021-02-22 16:47:53 +01:00
|
|
|
<https://gitlab.com/oauth/applications>.
|
2020-01-31 18:19:53 +01:00
|
|
|
Specify `http://zulipdev.com:9991/complete/gitlab` as the callback URL.
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- You should get a page containing the Application ID and Secret for
|
2021-08-20 21:53:28 +02:00
|
|
|
your new application. In `dev-secrets.conf`, enter the Application
|
2020-01-31 18:19:53 +01:00
|
|
|
ID as `social_auth_gitlab_key` and the Secret as
|
|
|
|
`social_auth_gitlab_secret`.
|
|
|
|
|
2020-06-09 12:04:21 +02:00
|
|
|
### Apple
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Visit <https://developer.apple.com/account/resources/>,
|
2020-06-09 12:04:21 +02:00
|
|
|
Enable App ID and Create a Services ID with the instructions in
|
2021-02-22 16:47:53 +01:00
|
|
|
<https://help.apple.com/developer-account/?lang=en#/dev1c0e25352> .
|
2020-06-09 12:04:21 +02:00
|
|
|
When prompted for a "Return URL", enter
|
|
|
|
`http://zulipdev.com:9991/complete/apple/` .
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- [Create a Sign in with Apple private key](https://help.apple.com/developer-account/?lang=en#/dev77c875b7e)
|
2020-06-09 12:04:21 +02:00
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- In `dev-secrets.conf`, set
|
|
|
|
- `social_auth_apple_services_id` to your
|
2020-06-09 12:04:21 +02:00
|
|
|
"Services ID" (eg. com.application.your).
|
2021-08-20 21:45:39 +02:00
|
|
|
- `social_auth_apple_app_id` to "App ID" or "Bundle ID".
|
2020-06-26 12:22:48 +02:00
|
|
|
This is only required if you are testing Apple auth on iOS.
|
2021-08-20 21:45:39 +02:00
|
|
|
- `social_auth_apple_key` to your "Key ID".
|
|
|
|
- `social_auth_apple_team` to your "Team ID".
|
|
|
|
- Put the private key file you got from apple at the path
|
2020-06-09 12:04:21 +02:00
|
|
|
`zproject/dev_apple.key`.
|
|
|
|
|
2019-09-29 06:32:56 +02:00
|
|
|
### SAML
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Sign up for a [developer Okta account](https://developer.okta.com/).
|
|
|
|
- Set up SAML authentication by following
|
2019-10-31 05:07:11 +01:00
|
|
|
[Okta's documentation](https://developer.okta.com/docs/guides/saml-application-setup/overview/).
|
|
|
|
Specify:
|
2021-08-20 21:45:39 +02:00
|
|
|
- `http://localhost:9991/complete/saml/` for the "Single sign on URL"`.
|
|
|
|
- `http://localhost:9991` for the "Audience URI (SP Entity ID)".
|
|
|
|
- Skip "Default RelayState".
|
|
|
|
- Skip "Name ID format".
|
|
|
|
- Set 'Email` for "Application username format".
|
|
|
|
- Provide "Attribute statements" of `email` to `user.email`,
|
2019-09-29 06:32:56 +02:00
|
|
|
`first_name` to `user.firstName`, and `last_name` to `user.lastName`.
|
2021-08-20 21:45:39 +02:00
|
|
|
- Assign at least one account in the "Assignments" tab. You'll use it for
|
2019-10-31 05:07:11 +01:00
|
|
|
signing up / logging in to Zulip.
|
2021-08-20 21:45:39 +02:00
|
|
|
- Visit the big "Setup instructions" button on the "Sign on" tab.
|
|
|
|
- Edit `zproject/dev-secrets.conf` to add the two values provided:
|
|
|
|
- Set `saml_url = http...` from "Identity Provider Single Sign-On
|
2019-09-29 06:32:56 +02:00
|
|
|
URL".
|
2021-08-20 21:45:39 +02:00
|
|
|
- Set `saml_entity_id = http://...` from "Identity Provider Issuer".
|
|
|
|
- Download the certificate and put it at the path `zproject/dev_saml.cert`.
|
|
|
|
- Now you should have working SAML authentication!
|
|
|
|
- You can sign up to the target realm with the account that you've "assigned"
|
2019-10-31 05:07:11 +01:00
|
|
|
in the previous steps (if the account's email address is allowed in the realm,
|
|
|
|
so you may have to change the realm settings to allow the appropriate email domain)
|
|
|
|
and then you'll be able to log in freely. Alternatively, you can create an account
|
|
|
|
with the email in any other way, and then just use SAML to log in.
|
2019-09-29 06:32:56 +02:00
|
|
|
|
2018-11-27 16:08:43 +01:00
|
|
|
### When SSL is required
|
|
|
|
|
|
|
|
Some OAuth providers (such as Facebook) require HTTPS on the callback
|
|
|
|
URL they post back to, which isn't supported directly by the Zulip
|
2021-08-20 21:53:28 +02:00
|
|
|
development environment. If you run a
|
2019-09-30 19:37:56 +02:00
|
|
|
[remote Zulip development server](../development/remote.md), we have
|
2018-11-27 16:08:43 +01:00
|
|
|
instructions for
|
2019-04-06 02:58:44 +02:00
|
|
|
[an nginx reverse proxy with SSL](../development/remote.html#using-an-nginx-reverse-proxy)
|
2018-11-27 16:08:43 +01:00
|
|
|
that you can use for your development efforts.
|
|
|
|
|
2018-08-18 05:11:19 +02:00
|
|
|
## Testing LDAP in development
|
|
|
|
|
2019-05-28 22:53:36 +02:00
|
|
|
Before Zulip 2.0, one of the more common classes of bug reports with
|
|
|
|
Zulip's authentication was users having trouble getting [LDAP
|
|
|
|
authentication](../production/authentication-methods.html#ldap-including-active-directory)
|
2021-08-20 21:53:28 +02:00
|
|
|
working. The root cause was because setting up a local LDAP server
|
2019-05-28 22:53:36 +02:00
|
|
|
for development was difficult, which meant most developers were unable
|
|
|
|
to work on fixing even simple issues with it.
|
2018-08-18 05:11:19 +02:00
|
|
|
|
|
|
|
We solved this problem for our unit tests long ago by using the
|
2021-08-20 21:53:28 +02:00
|
|
|
popular [fakeldap](https://github.com/zulip/fakeldap) library. And in
|
2018-08-18 05:11:19 +02:00
|
|
|
2018, we added convenient support for using fakeldap in the Zulip
|
|
|
|
development environment as well, so that you can go through all the
|
|
|
|
actual flows for LDAP configuration.
|
|
|
|
|
|
|
|
- To enable fakeldap, set `FAKE_LDAP_MODE` in
|
2021-08-20 21:53:28 +02:00
|
|
|
`zproject/dev_settings.py` to one of the following options. For more
|
2018-09-27 22:30:29 +02:00
|
|
|
information on these modes, refer to
|
2019-04-06 02:58:44 +02:00
|
|
|
[our production docs](../production/authentication-methods.html#ldap-including-active-directory):
|
2018-08-18 05:11:19 +02:00
|
|
|
- `a`: If users' email addresses are in LDAP and used as username.
|
|
|
|
- `b`: If LDAP only has usernames but email addresses are of the form
|
|
|
|
username@example.com
|
|
|
|
- `c`: If LDAP usernames are completely unrelated to email addresses.
|
|
|
|
|
|
|
|
- To disable fakeldap, set `FAKE_LDAP_MODE` back to `None`.
|
|
|
|
|
|
|
|
- In all fakeldap configurations, users' fake LDAP passwords are equal
|
|
|
|
to their usernames (e.g. for `ldapuser1@zulip.com`, the password is
|
|
|
|
`ldapuser1`).
|
|
|
|
|
2018-08-18 02:35:19 +02:00
|
|
|
- `FAKE_LDAP_NUM_USERS` in `zproject/dev_settings.py` can be used to
|
|
|
|
specify the number of LDAP users to be added. The default value for
|
|
|
|
the number of LDAP users is 8.
|
2019-06-17 22:11:29 +02:00
|
|
|
|
|
|
|
### Testing avatar and custom profile field synchronization
|
|
|
|
|
|
|
|
The fakeldap LDAP directories we use in the development environment
|
|
|
|
are generated by the code in `zerver/lib/dev_ldap_directory.py`, and
|
|
|
|
contain data one might want to sync, including avatars and custom
|
|
|
|
profile fields.
|
|
|
|
|
|
|
|
We also have configured `AUTH_LDAP_USER_ATTR_MAP` in
|
2021-08-20 21:53:28 +02:00
|
|
|
`zproject/dev_settings.py` to sync several of those fields. For
|
2019-06-17 22:11:29 +02:00
|
|
|
example:
|
|
|
|
|
2021-08-20 21:45:39 +02:00
|
|
|
- Modes `a` and `b` will set the user's avatar on account creation and
|
2019-06-17 22:11:29 +02:00
|
|
|
update it when `manage.py sync_ldap_user_data` is run.
|
2021-08-20 21:45:39 +02:00
|
|
|
- Mode `b` is configured to automatically have the `birthday` and
|
2019-06-17 22:11:29 +02:00
|
|
|
`Phone number` custom profile fields populated/synced.
|
2021-08-20 21:45:39 +02:00
|
|
|
- Mode `a` is configured to deactivate/reactivate users whose accounts
|
2019-06-17 22:11:29 +02:00
|
|
|
are disabled in LDAP when `manage.py sync_ldap_user_data` is run.
|
|
|
|
(Note that you'll likely need to edit
|
|
|
|
`zerver/lib/dev_ldap_directory.py` to ensure there are some accounts
|
|
|
|
configured to be disabled).
|
|
|
|
|
|
|
|
### Automated testing
|
|
|
|
|
|
|
|
For our automated tests, we generally configure custom LDAP data for
|
|
|
|
each individual test, because that generally means one can understand
|
|
|
|
exactly what data is being used in the test without looking at other
|
2021-08-20 21:53:28 +02:00
|
|
|
resources. It also gives us more freedom to edit the development
|
2019-06-17 22:11:29 +02:00
|
|
|
environment directory without worrying about tests.
|
2019-10-07 21:10:18 +02:00
|
|
|
|
2020-08-11 01:47:54 +02:00
|
|
|
## Two factor authentication
|
2019-10-07 21:10:18 +02:00
|
|
|
|
|
|
|
Zulip uses [django-two-factor-auth][0] as a beta 2FA integration.
|
|
|
|
|
|
|
|
To enable 2FA, set `TWO_FACTOR_AUTHENTICATION_ENABLED` in settings to
|
docs: Add missing space to compound verbs “log in”, “set up”, etc.
Noun: backup, checkout, cleanup, login, logout, setup, shutdown, signup,
timeout.
Verb: back up, check out, clean up, log in, log out, set up, shut
down, sign up, time out.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-04-25 23:05:38 +02:00
|
|
|
`True`, then log in to Zulip and add an OTP device from the settings
|
2019-10-07 21:10:18 +02:00
|
|
|
page. Once the device is added, password based authentication will ask
|
2021-08-20 21:53:28 +02:00
|
|
|
for a one-time-password. In the development environment, this
|
2019-10-07 21:10:18 +02:00
|
|
|
one-time-password will be printed to the console when you try to
|
2021-08-20 21:53:28 +02:00
|
|
|
log in. Just copy-paste it into the form field to continue.
|
2019-10-07 21:10:18 +02:00
|
|
|
|
|
|
|
Direct development logins don't prompt for 2FA one-time-passwords, so
|
docs: Add missing space to compound verbs “log in”, “set up”, etc.
Noun: backup, checkout, cleanup, login, logout, setup, shutdown, signup,
timeout.
Verb: back up, check out, clean up, log in, log out, set up, shut
down, sign up, time out.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-04-25 23:05:38 +02:00
|
|
|
to test 2FA in development, make sure that you log in using a
|
2021-08-20 21:53:28 +02:00
|
|
|
password. You can get the passwords for the default test users using
|
2019-10-07 21:10:18 +02:00
|
|
|
`./manage.py print_initial_password`.
|
|
|
|
|
2021-04-05 09:42:29 +02:00
|
|
|
## Password form implementation
|
|
|
|
|
|
|
|
By default, Zulip uses `autocomplete=off` for password fields where we
|
|
|
|
enter the current password, and `autocomplete="new-password"` for
|
|
|
|
password fields where we create a new account or change the existing
|
2021-08-20 21:53:28 +02:00
|
|
|
password. This prevents the browser from auto-filling the existing
|
2021-04-05 09:42:29 +02:00
|
|
|
password.
|
|
|
|
|
|
|
|
Visit <https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete> for more details.
|
|
|
|
|
2019-10-07 21:10:18 +02:00
|
|
|
[0]: https://github.com/Bouke/django-two-factor-auth
|