Skip to content

one-time passwords (e.g. for public file shares)#61722

Open
theCalcaholic wants to merge 8 commits into
nextcloud:masterfrom
theCalcaholic:feature/nextcloud-share-otp
Open

one-time passwords (e.g. for public file shares)#61722
theCalcaholic wants to merge 8 commits into
nextcloud:masterfrom
theCalcaholic:feature/nextcloud-share-otp

Conversation

@theCalcaholic

@theCalcaholic theCalcaholic commented Jul 2, 2026

Copy link
Copy Markdown

Summary

This PR adds one-time password management to Nextcloud server and integrates them with the files_sharing app.

image

(the actual form in the screenshot is part of #61733)

Notes

  • This PR only changes <60 files. The huge amount of changes comes from rebuilding the frontend (make build-js-production).
  • There is a second otp provider available as a Nextcloud app over at otp_provider_debug, which basically just logs OTPs to the Nextcloud logs. This could be helpful for testing/debugging and I would suggest moving it to the nextcloud namespace once this is merged (unless you don't consider it necessary). The main advantage is that you can test OTPs without setting up SMTP. However, I will not keep maintaining it, because that would require tracking changes to the OTP API and testing every new Nextcloud version.
  • This PR should be merged after the refactoring of IShare->isPasswordProtected() (Refactor: Centralize logic for checking if a share is password protected #61946)

TODO

  • (core) Implement OTP core functionality
  • (core) Implement OTP integration into shares
  • (files_sharing) Implement creation of OTP protected shares via OCS
  • (files_sharing) Implement retrieval of public OTP protected shares via OCS
  • Harden bruteforce settings for endpoints
  • Tests
  • Linting
  • Regenerate openapi definitions for files_sharing
  • Contribute documentation for the feature

Architecture and Rationale

General concepts

OTPs (one-time password) are short-lived, single use credentials sent to users via an (according to a given threat model) trusted channel (e.g. a specific email address).

OTP Providers define a method of sending OTPs to users.

OTP Recipients are valid address definitions within the scope of an OTP provider that can be sent OTPs.

Core/Server Changes

Generic

One-time passwords are implemented with generic interfaces so that they can be used by other parts of Nextcloud than sharing.

The core functionality for one-time passwords is implemented within the \OCP and \OC namespaces. OTPs are stored within a new database table one_time_password and have a providerID, a recipient string, an expiration date and a password. The idea here is, that the OTP configuration (i.e. provider+recipient) can be long lived, while the credentials (password+expiration date) are (re-)generated per use.
Management of OTPs is implemented in \OC\OneTimePassword\Manager (implementing the injectable interface at \OCP\OneTimePassword\IManager).

\OCP\Security\PasswordContext has been extended by an OTP case to allow the creation of password policies specifically for OTPs.

Events are used to allow apps to register OTP providers. They need to hook into the GetOneTimePasswordProviders and the SendOneTimePassword events to provider their functionality. Providers also need to implement the interface \OCP\OneTimePassword\IOneTimePasswordProvider, which defines methods that allow the Manager to select providers and provide information about them.

Sharing specific

Shares (see \OCP\Share\IShare) have been extended with an one_time_password field.

The \OC\Share20\Manager has been adjusted to prioritize OTPs when checking the authentication for a share.

The template publicshareauth.php has been adjusted to receive and display OTP related information (used in #61733 to show the OTP specific password form).

files_sharing Changes

The ShareAPIController has been extended to allow creating and updating OTP protected shares and returning the otp configuration when fetching shares. OTPs and passwords are mutually exclusive and an error will be returned when attempting to create a share with both.

The ShareController has been extended to supply template responses for public shares with otp related information.

A new ShareOTPController has been implemented that allows users to request OTPs for a share.

OTP Providers

An OTP provider, which allows sending OTPs via email has been implemented as (core) app: otp_provider_email. It can be disabled or restricted by administrators to disallow this functionality.

UI changes

The authentication page for public shares has been updated to accommodate OTPs (see screenshot).
When an OTP is required for a share, the authentication form will change to present a button for requesting an OTP in addition to the normal password field. It will also display a different title above the password field.

Password authentication page for OTP protected shares image

The email template for sending OTPs to users is located in apps/otp_provider_email/lib/listener/SendOneTimePasswordEventListener.php and uses Nextclouds usual Mailer interface for templating emails.

Example OTP email sent to users image

The logo is not displayed, because I'm testing with a local Nextcloud instance at a non-public URL.

The custom permissions in the sidebar sharing tab (files->sidebar->sharing->custom permissions) has been adjusted to allow choosing between no password protection, setting a normal password and configuring an OTP. The descriptions of the OTP are defined and localized by the OTP provider.

New UI for selecting an authentication method during share creation image image image
Previous UI for selecting an auth method for comparison image

Checklist

AI (if applicable)

  • The content of this PR was partly or fully generated using AI

@theCalcaholic theCalcaholic requested review from a team and provokateurin as code owners July 2, 2026 11:40
@theCalcaholic theCalcaholic requested review from Altahrim, ArtificialOwl, leftybournes, nfebe, sorbaugh and susnux and removed request for a team July 2, 2026 11:40
@theCalcaholic theCalcaholic force-pushed the feature/nextcloud-share-otp branch 2 times, most recently from adbd854 to ae1bd6a Compare July 2, 2026 12:14
@provokateurin provokateurin marked this pull request as draft July 2, 2026 13:35
@theCalcaholic theCalcaholic force-pushed the feature/nextcloud-share-otp branch from ae1bd6a to 5035daf Compare July 2, 2026 13:56
@susnux susnux added enhancement 2. developing Work in progress labels Jul 2, 2026
@theCalcaholic theCalcaholic force-pushed the feature/nextcloud-share-otp branch from 5035daf to 99f7621 Compare July 2, 2026 15:36
@theCalcaholic theCalcaholic changed the title [WIP] Support one-time passwords (e.g. for public file shares) [backend] Support one-time passwords (e.g. for public file shares) Jul 2, 2026
@theCalcaholic theCalcaholic force-pushed the feature/nextcloud-share-otp branch 3 times, most recently from edb4db5 to 27730a7 Compare July 2, 2026 23:28
@susnux susnux added the community pull requests from community label Jul 3, 2026
@theCalcaholic theCalcaholic force-pushed the feature/nextcloud-share-otp branch from bc04d3a to 9a9f4d3 Compare July 3, 2026 13:26
@theCalcaholic theCalcaholic marked this pull request as ready for review July 3, 2026 14:00
@theCalcaholic

theCalcaholic commented Jul 3, 2026

Copy link
Copy Markdown
Author

From my side, this PR is ready for review. :)

The only thing missing, is documentation, but I would want to wait for feedback before working on that.

Let me know if there is anything you require from me.

Here are curl commands to create an OTP protected share on a Nextcloud instance running at http://nextcloud.local with user=admin and password=admin (requires the otp_provider_debug and otp_provider_email apps to be enabled):

For email:

curl http://nextcloud.local/ocs/v2.php/apps/files_sharing/api/v1/shares -u 'admin:admin' -H 'Content-Type: application/json' -H "Accept: application/json" -H "OCS-APIRequest: true" --data '{"path": "/Nextcloud_Server_Administration_Manual.pdf", "attributes": "[]", "shareType": 3, "otpProvider": "email", "otpRecipient": "your@email.address"}'

For debug (OTPs will be written to Nextcloud logs, requires https://github.com/theCalcaholic/otp_provider_debug):

curl http://nextcloud.local/ocs/v2.php/apps/files_sharing/api/v1/shares -u 'admin:admin' -H 'Content-Type: application/json' -H "Accept: application/json" -H "OCS-APIRequest: true" --data '{"path": "/Nextcloud_Server_Administration_Manual.pdf", "attributes": "[]", "shareType": 3, "otpProvider": "debug", "otpRecipient": "foobar"}'

If the file /Nextcloud_Server_Administration_Manual.pdf doesn't exist for your user, you will need to use a different path.

@theCalcaholic theCalcaholic force-pushed the feature/nextcloud-share-otp branch from f79b8ba to 702cee9 Compare July 3, 2026 17:36
@theCalcaholic

Copy link
Copy Markdown
Author

@susnux I hope it's ok to tag you (I wasn't sure if the update messages above would reach you otherwise).

@susnux susnux removed the 2. developing Work in progress label Jul 6, 2026
@susnux susnux added the 3. to review Waiting for reviews label Jul 6, 2026
Comment thread apps/otp_provider_email/lib/Listener/SendOneTimePasswordEventListener.php Outdated
Comment thread apps/otp_provider_debug/appinfo/info.xml Outdated
Comment thread apps/otp_provider_debug/appinfo/info.xml Outdated
Comment thread apps/otp_provider_email/appinfo/info.xml Outdated
Comment thread lib/composer/composer/InstalledVersions.php
@theCalcaholic theCalcaholic force-pushed the feature/nextcloud-share-otp branch 4 times, most recently from d1d74e7 to 5783ad1 Compare July 9, 2026 14:50
@theCalcaholic theCalcaholic changed the title [backend] Support one-time passwords (e.g. for public file shares) Support one-time passwords (e.g. for public file shares) Jul 9, 2026
@theCalcaholic theCalcaholic force-pushed the feature/nextcloud-share-otp branch from d1d74e7 to f1e9faa Compare July 9, 2026 15:16
@theCalcaholic theCalcaholic changed the title Support one-time passwords (e.g. for public file shares) one-time passwords (e.g. for public file shares) Jul 9, 2026
@theCalcaholic theCalcaholic force-pushed the feature/nextcloud-share-otp branch from f1e9faa to bfaac2e Compare July 9, 2026 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews community pull requests from community enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants