registerStrategy(pluginName, strategyName, strategy) {
    // prior to Kaaf, plugin names can contains upper case
    const plugin = this._plugins.get(pluginName.toLowerCase());

    // only add the strategy to the strategies object if the init method
    // has not been called
    if (!plugin.initCalled) {
      plugin.instance.strategies = plugin.instance.strategies || {};
      plugin.instance.strategies[strategyName] = strategy;

      return;
    }

    this.validateStrategy(plugin.name, strategyName, strategy);

    if (has(this.strategies, strategyName)) {
      this.unregisterStrategy(plugin.name, strategyName);
    }

    const methods = {};

    // wrap plugin methods to force their context and to
    // convert uncaught exception into PluginImplementationError
    // promise rejections
    for (const methodName of Object.keys(strategy.methods).filter(
      (name) => name !== "verify",
    )) {
      methods[methodName] = async (...args) => {
        try {
          const boundFunction = plugin.instance[
            strategy.methods[methodName]
          ].bind(plugin.instance);

          return await boundFunction(...args);
        } catch (error) {
          if (error instanceof KuzzleError) {
            throw error;
          }

          throw runtimeError.getFrom(error, "unexpected_error", error.message);
        }
      };
    }

    const opts = {
      ...strategy.config.strategyOptions,
      passReqToCallback: true,
    };

    const verifyAdapter = this.wrapStrategyVerify(
      plugin.logPrefix,
      strategyName,
      plugin.instance[strategy.methods.verify].bind(plugin.instance),
    );

    try {
      const Ctor =
          this.authenticators[plugin.name][strategy.config.authenticator],
        instance = new Ctor(opts, verifyAdapter);

      this.strategies[strategyName] = { methods, owner: plugin.name, strategy };
      global.kuzzle.passport.use(
        strategyName,
        instance,
        strategy.config.authenticateOptions,
      );

      if (methods.afterRegister) {
        methods.afterRegister(instance);
      }
    } catch (e) {
      throw strategyError.getFrom(
        e,
        "failed_registration",
        strategyName,
        e.message,
      );
    }
  }
Registers an authentication strategy.
If the plugin init method has not been called yet, add the strategy to
the plugin.instance.strategies object.

@param {string} pluginName - plugin name
@param {string} strategyName - strategy name
@param {object} strategy - strategy properties
@throws {PluginImplementationError} If the strategy is invalid or if
                                    registration fails