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

[5.x] Add entry password protection #10800

Merged
merged 15 commits into from
Sep 17, 2024
Merged

Conversation

aerni
Copy link
Contributor

@aerni aerni commented Sep 13, 2024

This PR extends the existing password protection scheme with the concept of local passwords. This allows users to protect individual entries based on a password field.

To use a local entry password, you start by defining the field containing the password. In this example, we'll call the field password:

'password' => [
    'driver' => 'password',
    'allowed' => ['master-password'],
    'field' => 'password',
],

Next, you'll need to apply the protection scheme on the entry, along with the password.

id: 277de5b5-d28a-4af9-a57b-a929e39d59c9
title: 'Protected Page'
protect: password
password: local-password

Now, users can access the protected page using local-password.

If the protection scheme has both allowed and field configured, the passwords in allowed will act as master passwords. In our example, you'll be able to access the protected entry either with master-password or local-password.

If you use the local-password, the session will be scoped to the entry's ID. This ensures that you can only access the entry you entered the password for. This also ensures that multiple entries can share the same local password but still control access individually.

If you use the master-password, the session will be scoped to the protection scheme and immediately grant access to all other entries as well.

And if, for whatever reason, an entry uses a local password that is the same as a master password, access will be scoped to the entry as well. This ensures that global access won't be granted accidentally.

A little hack you can use to enable password protection only if an entry's password field is filled:

Collection::computed('pages', 'protect', function ($entry, $value) {
    if ($value) {
        return $value;
    }

    $field = config('statamic.protect.schemes.password.field');

    return $entry->$field ? 'password' : null;
});

references because there's potential for overlapping ids across types - entries, terms, etc.

prefix the session key to keep references and schemes separate
- hasEnteredValidPassword avoids checking both session keys if it doesnt need to
- get rid of the guard class. it doesnt really do much.
- move the guards into the protector class
@jasonvarga jasonvarga merged commit 9722f73 into statamic:5.x Sep 17, 2024
16 checks passed
duncanmcclean added a commit to statamic/statamic that referenced this pull request Oct 7, 2024
duncanmcclean added a commit to statamic/statamic that referenced this pull request Oct 7, 2024
* Nocache database driver

Related: statamic/cms#10671

* Prevent query parameters bloating the static cache

Related: statamic/cms#10701

* Add entry password protection

Related: statamic/cms#10800

* Fix small typo

Related: statamic/cms#10824

* Move nocache js back to end of body but make configurable

Related: statamic/cms#10898
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants