SMS gateway: cliConfigure() never writes sms_provider_name

Open Beginner friendly
#1,197 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
84/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
php

Research direction

Start in lib/Provider/Channel/SMS/Gateway.php by tracing cliConfigure() after the provider is selected, then compare it with setProvider() and getProvider(). Persist the selected provider's Settings::id and verify that sms_provider_name is written and the SMS send path no longer raises ConfigurationException.

Written by the indexing model from the issue text.

Description

bug
How to use GitHub
  • Please use the 👍 reaction to show that you are affected by the same issue.
  • Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
  • Subscribe to receive notifications on status change and new comments.

Disclaimer: This report was created with the help of AI, please dont kill me :-)

SMS gateway: cliConfigure() never writes sms_provider_name, so every send throws ConfigurationException: Invalid gateway/provider configuration set

Environment

  • twofactor_gateway: 4.0.0 (only release declaring nextcloud max-version="34"; all 3.x are 33-only)
  • Nextcloud: 34.0.4.1
  • PHP: 8.4
  • Database: MariaDB 10.6
  • Web server: Apache + PHP-FPM (Ubuntu)

Description

SMS\Gateway::getProvider() resolves the active SMS provider solely from the sms_provider_name app-config key and throws when it is empty:

lib/Provider/Channel/SMS/Gateway.php

public function getProvider(string $providerName = ''): IProvider {
    if ($providerName) {
        $this->setProvider($providerName);
    }
    $providerName = $this->appConfig->getValueString(Application::APP_ID, 'sms_provider_name');
    if ($providerName === '') {
        throw new ConfigurationException();   // "Invalid gateway/provider configuration set"
    }
    return $this->smsProviderFactory->get($providerName);
}

public function setProvider(string $provider): void {
    $this->appConfig->setValueString(Application::APP_ID, 'sms_provider_name', $provider);
}

cliConfigure() in the same file prompts for a provider and writes only that provider's fields (e.g. sms77io_api_key). It never calls setProvider(), so sms_provider_name is left blank:

final public function cliConfigure(InputInterface $input, OutputInterface $output): int {
    // ... build provider list, ask user to choose ...
    $provider = $providers[$selectedIndex];

    foreach ($provider->getSettings()->fields as $field) {
        // prompts and calls set<Field>() on the provider (writes e.g. sms77io_api_key)
    }
    return 0;   // <-- sms_provider_name is never written
}

Steps to reproduce

  1. occ twofactorauth:gateway:configure sms
  2. Choose a provider (e.g. seven (formerly sms77.io)), enter the API key.
  3. occ config:list twofactor_gateway → the credential key is present (sms77io_api_key), but there is no sms_provider_name key.
  4. Trigger any SMS second-factor challenge (or the admin test).

Expected

The selected provider is persisted; the gateway resolves it and sends.

Actual

getProvider() reads an empty sms_provider_name and throws:

OCA\TwoFactorGateway\Exception\ConfigurationException: Invalid gateway/provider configuration set
  at lib/Provider/Channel/SMS/Gateway.php (getProvider)

Scope

The same structure exists in 3.4.0 (getProvider() reads sms_provider_name; cliConfigure() has no setProvider() call), so this is long-standing rather than a 4.0.0-only regression — but it is only reachable now because 4.0.0 is the sole NC 34 build.

Suggested fix

Persist the chosen provider in cliConfigure() after selection:

$provider = $providers[$selectedIndex];
$this->setProvider($provider->getSettings()->id);   // e.g. 'sms77io', 'smsapi'

The admin configuration-save path should persist sms_provider_name on the same basis. (Note: that path is currently unreachable for SMS due to a separate defect — see the companion issue on AdminGatewayController::resolveGatewayForInstance() returning a provider driver where an IGateway is required.)

Workaround

occ config:app:set twofactor_gateway sms_provider_name --value=<settings-id> --type=string
# seven (formerly sms77.io) -> sms77io ; SMSAPI -> smsapi

The value must equal the provider's Settings::id (matched by SMS\Factory::get() against $fqcn or $settings->id) — not the display name or the driver class name. After setting it, the send path (SMS\Gateway::send()getProvider()->send()) works, reading sms_provider_name plus the provider field keys directly from app-config.

Dominant language
PHP
Stars
122
Forks
63
Avg merge
2d 23h
Merged PRs (30d)
22

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from nextcloud/twofactor_gateway

All issues in nextcloud/twofactor_gateway

Similar issues

More PHP issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.