public AuthenticationService(UriString host, IKeychain keychain,
                              IProcessManager processManager, ITaskManager taskManager,
                              IEnvironment environment
                              )
 {
     client = new ApiClient(keychain, processManager, taskManager, environment, host);
 }
Example #2
0
        public GitHubCredentialProvider(IKeychain keychain, [Import(AllowDefault = true)] JoinableTaskContext joinableTaskContext)
        {
            Guard.ArgumentNotNull(keychain, nameof(keychain));

            this.keychain       = keychain;
            JoinableTaskContext = joinableTaskContext ?? ThreadHelper.JoinableTaskContext;
        }
Example #3
0
        public OctorunTask(CancellationToken token, IKeychain keychain, IEnvironment environment,
                           string arguments,
                           IOutputProcessor <OctorunResult> processor = null)
            : base(token, processor ?? new OctorunResultOutputProcessor())
        {
            this.clientId        = ApplicationInfo.ClientId;
            this.clientSecret    = ApplicationInfo.ClientSecret;
            this.pathToNodeJs    = environment.NodeJsExecutablePath;
            this.pathToOctorunJs = environment.OctorunScriptPath;
            this.arguments       = $"\"{pathToOctorunJs}\" {arguments}";

            var cloneUrl = environment.Repository?.CloneUrl;
            var host     = String.IsNullOrEmpty(cloneUrl)
                ? UriString.ToUriString(HostAddress.GitHubDotComHostAddress.WebUri)
                : new UriString(cloneUrl.ToRepositoryUri()
                                .GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped));

            var adapter = keychain.Connect(host);

            if (adapter.Credential?.Token != null)
            {
                userToken = adapter.Credential.Token;
            }
            else
            {
                // use a cached adapter if there is one filled out
                adapter = keychain.LoadFromSystem(host);
                if (adapter != null)
                {
                    userToken = adapter.Credential.Token;
                }
            }
        }
Example #4
0
 public SessionFactory(AbstractLogger logger, ICoroutineManager coroutineManager, IStopwatch pollCountdownStopwatch, IEpochTime epochTime, DatabaseCorruptionHandler databaseCorruptionHandler, INotificationQueue notificationQueue, INotificationDispatcher notificationDispatcher, ISessionStatus sessionStatus, IMixWebCallFactoryFactory mixWebCallFactoryFactory, IWebCallEncryptorFactory webCallEncryptorFactory, IMixSessionStarter mixSessionStarter, IKeychain keychain, ISessionRefresherFactory sessionRefresherFactory, IGuestControllerClientFactory guestControllerClientFactory, IRandom random, IEncryptor encryptor, IFileSystem fileSystem, IWwwCallFactory wwwCallFactory, string localStorageDirPath, string clientVersion, IDatabaseDirectoryCreator databaseDirectoryCreator, IDocumentCollectionFactory documentCollectionFactory, IDatabase database)
 {
     this.logger                       = logger;
     this.coroutineManager             = coroutineManager;
     this.pollCountdownStopwatch       = pollCountdownStopwatch;
     this.epochTime                    = epochTime;
     this.databaseCorruptionHandler    = databaseCorruptionHandler;
     this.notificationQueue            = notificationQueue;
     this.notificationDispatcher       = notificationDispatcher;
     this.sessionStatus                = sessionStatus;
     this.mixWebCallFactoryFactory     = mixWebCallFactoryFactory;
     this.webCallEncryptorFactory      = webCallEncryptorFactory;
     this.mixSessionStarter            = mixSessionStarter;
     this.keychain                     = keychain;
     this.sessionRefresherFactory      = sessionRefresherFactory;
     this.guestControllerClientFactory = guestControllerClientFactory;
     this.random                       = random;
     this.encryptor                    = encryptor;
     this.fileSystem                   = fileSystem;
     this.wwwCallFactory               = wwwCallFactory;
     this.localStorageDirPath          = localStorageDirPath;
     this.clientVersion                = clientVersion;
     this.databaseDirectoryCreator     = databaseDirectoryCreator;
     this.documentCollectionFactory    = documentCollectionFactory;
     this.database                     = database;
 }
Example #5
0
 public Session(AbstractLogger logger, IInternalLocalUser localUser, string guestControllerAccessToken, bool pushNotificationsEnabled, INotificationPoller notificationPoller, ICoroutineManager coroutineManager, IDatabase database, IUserDatabase userDatabase, IGuestControllerClient guestControllerClient, IMixWebCallFactory mixWebCallFactory, IEpochTime epochTime, DatabaseCorruptionHandler databaseCorruptionHandler, ISessionStatus sessionStatus, IKeychain keychain, IGetStateResponseParser getStateResponseParser, string clientVersion, INotificationQueue notificationQueue)
 {
     this.logger                                     = logger;
     this.localUser                                  = localUser;
     this.notificationPoller                         = notificationPoller;
     this.coroutineManager                           = coroutineManager;
     this.database                                   = database;
     this.userDatabase                               = userDatabase;
     this.guestControllerClient                      = guestControllerClient;
     this.mixWebCallFactory                          = mixWebCallFactory;
     this.epochTime                                  = epochTime;
     this.databaseCorruptionHandler                  = databaseCorruptionHandler;
     this.sessionStatus                              = sessionStatus;
     this.keychain                                   = keychain;
     this.getStateResponseParser                     = getStateResponseParser;
     this.clientVersion                              = clientVersion;
     this.notificationQueue                          = notificationQueue;
     GuestControllerAccessToken                      = guestControllerAccessToken;
     guestControllerClient.OnAccessTokenChanged     += HandleGuestControllerAccessTokenChanged;
     guestControllerClient.OnAuthenticationLost     += HandleAuthenticationLost;
     mixWebCallFactory.OnAuthenticationLost         += HandleAuthenticationLost;
     localUser.OnPushNotificationsToggled           += HandlePushNotificationsToggled;
     localUser.OnPushNotificationReceived           += HandlePushNotificationReceived;
     localUser.OnDisplayNameUpdated                 += HandleDisplayNameUpdated;
     databaseCorruptionHandler.OnCorruptionDetected += HandleCorruptionDetected;
     updateEnumerator                                = Update();
     coroutineManager.Start(updateEnumerator);
     notificationPoller.OnNotificationsPolled += HandleNotificationsPolled;
     notificationPoller.UsePollIntervals       = !pushNotificationsEnabled;
     this.sessionStatus.IsPaused = true;
     notificationPoller.OnSynchronizationError += HandleNotificationPollerSynchronizationError;
 }
Example #6
0
 public static void StoreSecret(
     this IKeychain keychain,
     string serviceName,
     string accountName,
     string secret,
     bool updateExisting = true)
 => keychain.StoreSecret(
Example #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LoginManager"/> class.
        /// </summary>
        /// <param name="keychain">The keychain in which to store credentials.</param>
        /// <param name="twoFactorChallengeHandler">The handler for 2FA challenges.</param>
        /// <param name="oauthListener">The callback listener to signal successful login.</param>
        /// <param name="clientId">The application's client API ID.</param>
        /// <param name="clientSecret">The application's client API secret.</param>
        /// <param name="minimumScopes">The minimum acceptable scopes.</param>
        /// <param name="requestedScopes">The scopes to request when logging in.</param>
        /// <param name="authorizationNote">An note to store with the authorization.</param>
        /// <param name="fingerprint">The machine fingerprint.</param>
        public LoginManager(
            IKeychain keychain,
            Lazy <ITwoFactorChallengeHandler> twoFactorChallengeHandler,
            IOAuthCallbackListener oauthListener,
            string clientId,
            string clientSecret,
            IReadOnlyList <string> minimumScopes,
            IReadOnlyList <string> requestedScopes,
            string authorizationNote = null,
            string fingerprint       = null)
        {
            Guard.ArgumentNotNull(keychain, nameof(keychain));
            Guard.ArgumentNotNull(twoFactorChallengeHandler, nameof(twoFactorChallengeHandler));
            Guard.ArgumentNotEmptyString(clientId, nameof(clientId));
            Guard.ArgumentNotEmptyString(clientSecret, nameof(clientSecret));

            this.keychain = keychain;
            this.twoFactorChallengeHandler = twoFactorChallengeHandler;
            this.oauthListener             = oauthListener;
            this.clientId          = clientId;
            this.clientSecret      = clientSecret;
            this.minimumScopes     = minimumScopes;
            this.requestedScopes   = requestedScopes;
            this.authorizationNote = authorizationNote;
            this.fingerprint       = fingerprint;
        }
Example #8
0
        public static IApiClient Create(UriString repositoryUrl, IKeychain keychain)
        {
            var credentialStore = keychain.Connect(repositoryUrl);
            var hostAddress     = HostAddress.Create(repositoryUrl);

            return(new ApiClient(repositoryUrl, keychain,
                                 new GitHubClient(AppConfiguration.ProductHeader, credentialStore, hostAddress.ApiUri)));
        }
        public GraphQLKeychainCredentialStore(IKeychain keychain, HostAddress address)
        {
            Guard.ArgumentNotNull(keychain, nameof(keychain));
            Guard.ArgumentNotNull(address, nameof(keychain));

            this.keychain = keychain;
            this.address  = address;
        }
Example #10
0
        private void initCPKeyValueDatabase(IKeychain keychainData)
        {
            string localStorageDirPath = Path.Combine(Application.persistentDataPath, "KeyValueDatabase");

            byte[] localStorageKey = keychainData.LocalStorageKey;
            DocumentCollectionFactory documentCollectionFactory = new DocumentCollectionFactory();

            CPKeyValueDatabase = new CPKeyValueDatabase(localStorageKey, localStorageDirPath, documentCollectionFactory);
        }
Example #11
0
        public static IApiClient Create(UriString repositoryUrl, IKeychain keychain, IProcessManager processManager, ITaskManager taskManager, NPath nodeJsExecutablePath, NPath octorunScriptPath)
        {
            logger.Trace("Creating ApiClient: {0}", repositoryUrl);

            var credentialStore = keychain.Connect(repositoryUrl);
            var hostAddress     = HostAddress.Create(repositoryUrl);

            return(new ApiClient(repositoryUrl, keychain,
                                 processManager, taskManager, nodeJsExecutablePath, octorunScriptPath));
        }
Example #12
0
 public SimpleApiClientFactory(
     IProgram program,
     IKeychain keychain,
     Lazy <IEnterpriseProbe> enterpriseProbe,
     Lazy <IWikiProbe> wikiProbe)
 {
     this.keychain       = keychain;
     productHeader       = program.ProductHeader;
     lazyEnterpriseProbe = enterpriseProbe;
     lazyWikiProbe       = wikiProbe;
 }
Example #13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LoginManager"/> class.
        /// </summary>
        /// <param name="keychain"></param>
        /// <param name="processManager"></param>
        /// <param name="taskManager"></param>
        /// <param name="nodeJsExecutablePath"></param>
        /// <param name="octorunScript"></param>
        public LoginManager(
            IKeychain keychain, IProcessManager processManager, ITaskManager taskManager,
            IEnvironment environment)
        {
            Guard.ArgumentNotNull(keychain, nameof(keychain));

            this.keychain       = keychain;
            this.processManager = processManager;
            this.taskManager    = taskManager;
            this.environment    = environment;
        }
Example #14
0
        public GraphQLClientFactory(IKeychain keychain, IProgram program)
        {
            this.keychain = keychain;
            this.program  = program;

            var cachePath = Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                ApplicationInfo.ApplicationName,
                "GraphQLCache");

            cache = new FileCache(cachePath);
        }
		public MixSessionStarter(AbstractLogger logger, IRsaEncryptor rsaEncryptor, IDatabase database, IWebCallEncryptorFactory webCallEncryptorFactory, IWebCallEncryptor sessionStartEncryptor, IMixWebCallFactoryFactory mixWebCallFactoryFactory, IKeychain keychain, ICoroutineManager coroutineManager, ISessionRefresherFactory sessionRefresherFactory)
		{
			this.logger = logger;
			this.rsaEncryptor = rsaEncryptor;
			this.database = database;
			this.webCallEncryptorFactory = webCallEncryptorFactory;
			this.sessionStartEncryptor = sessionStartEncryptor;
			this.mixWebCallFactoryFactory = mixWebCallFactoryFactory;
			this.keychain = keychain;
			this.coroutineManager = coroutineManager;
			this.sessionRefresherFactory = sessionRefresherFactory;
		}
Example #16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LoginManager"/> class.
        /// </summary>
        /// <param name="keychain"></param>
        /// <param name="processManager"></param>
        /// <param name="taskManager"></param>
        /// <param name="nodeJsExecutablePath"></param>
        /// <param name="octorunScript"></param>
        public LoginManager(
            IKeychain keychain, IProcessManager processManager = null, ITaskManager taskManager = null,
            NPath?nodeJsExecutablePath = null, NPath?octorunScript = null)
        {
            Guard.ArgumentNotNull(keychain, nameof(keychain));

            this.keychain             = keychain;
            this.processManager       = processManager;
            this.taskManager          = taskManager;
            this.nodeJsExecutablePath = nodeJsExecutablePath;
            this.octorunScript        = octorunScript;
        }
Example #17
0
        public ApiClient(UriString hostUrl, IKeychain keychain, IGitHubClient githubClient)
        {
            Guard.ArgumentNotNull(hostUrl, nameof(hostUrl));
            Guard.ArgumentNotNull(keychain, nameof(keychain));
            Guard.ArgumentNotNull(githubClient, nameof(githubClient));

            HostAddress       = HostAddress.Create(hostUrl);
            OriginalUrl       = hostUrl;
            this.keychain     = keychain;
            this.githubClient = githubClient;
            loginManager      = new LoginManager(keychain, ApplicationInfo.ClientId, ApplicationInfo.ClientSecret);
        }
Example #18
0
        public ApiClient(UriString hostUrl, IKeychain keychain, IProcessManager processManager, ITaskManager taskManager, NPath nodeJsExecutablePath, NPath octorunScriptPath)
        {
            Guard.ArgumentNotNull(hostUrl, nameof(hostUrl));
            Guard.ArgumentNotNull(keychain, nameof(keychain));

            HostAddress               = HostAddress.Create(hostUrl);
            OriginalUrl               = hostUrl;
            this.keychain             = keychain;
            this.processManager       = processManager;
            this.taskManager          = taskManager;
            this.nodeJsExecutablePath = nodeJsExecutablePath;
            this.octorunScriptPath    = octorunScriptPath;
            loginManager              = new LoginManager(keychain, processManager, taskManager, nodeJsExecutablePath, octorunScriptPath);
        }
Example #19
0
		public MixLoginCreateService()
		{
			keychainData = Service.Get<IKeychain>();
			sessionStarter = new SessionStarter();
			coroutineManager = new MixCoroutineManager();
			logger = new MixLogger();
			localizer = Service.Get<Localizer>();
			Localizer obj = localizer;
			obj.TokensUpdated = (Localizer.TokensUpdatedDelegate)Delegate.Combine(obj.TokensUpdated, new Localizer.TokensUpdatedDelegate(onLanguageChanged));
			overrideCountryCode = new DevCacheableType<string>("mix.OverrideCountryCode", "");
			spoofedGeoIp = new DevCacheableType<string>("mix.SpoofedGeoIP", null);
			Service.Get<ICommonGameSettings>().RegisterSetting(overrideCountryCode, canBeReset: true);
			Service.Get<ICommonGameSettings>().RegisterSetting(spoofedGeoIp, canBeReset: true);
		}
Example #20
0
 public UsageTracker(ITaskManager taskManager, IGitClient gitClient, IProcessManager processManager,
                     ISettings userSettings,
                     IEnvironment environment,
                     IKeychain keychain,
                     string instanceId)
     : base(userSettings,
            new UsageLoader(environment.UserCachePath.Combine(Constants.UsageFile)),
            environment.UnityVersion, instanceId)
 {
     TaskManager    = taskManager;
     Environment    = environment;
     GitClient      = gitClient;
     ProcessManager = processManager;
     Keychain       = keychain;
 }
Example #21
0
        public static bool TryGetSecret(
            this IKeychain keychain,
            string serviceName,
            string accountName,
            out string secret)
        {
            if (keychain.TryGetSecret(((serviceName, accountName)), out var fullSecret))
            {
                secret = fullSecret.GetUtf8StringValue();
                return(true);
            }

            secret = null;
            return(false);
        }
Example #22
0
 public OSKeychain()
 {
     if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
     {
         keychain = new AppleKeychain();
     }
     else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
     {
         keychain = new DPAPIKeychain();
     }
     else
     {
         keychain = new ManagedProtectionKeychain();
     }
 }
Example #23
0
        public static bool TryGetSecretBytes(
            this IKeychain keychain,
            string serviceName,
            string accountName,
            out byte [] secret)
        {
            if (keychain.TryGetSecret(((serviceName, accountName)), out var fullSecret))
            {
                secret = (byte [])fullSecret.Value;
                return(true);
            }

            secret = null;
            return(false);
        }
        public NewAccountValidator(IKeychain keychain, AbstractLogger logger, string localStorageDirPath, string guestControllerHostUrl, string guestControllerSpoofedIpAddress, string oneIdClientId, ICoroutineManager coroutineManager)
        {
            this.logger = logger;
            SystemStopwatchFactory    stopwatchFactory          = new SystemStopwatchFactory();
            SystemWwwFactory          wwwFactory                = new SystemWwwFactory();
            WwwCallFactory            wwwCallFactory            = new WwwCallFactory(logger, coroutineManager, stopwatchFactory, wwwFactory);
            FileSystem                fileSystem                = new FileSystem();
            DatabaseDirectoryCreator  directoryCreator          = new DatabaseDirectoryCreator(fileSystem, localStorageDirPath);
            DocumentCollectionFactory documentCollectionFactory = new DocumentCollectionFactory();
            SystemRandom              random = new SystemRandom();
            DatabaseCorruptionHandler databaseCorruptionHandler = new DatabaseCorruptionHandler(logger, fileSystem, localStorageDirPath);
            SystemEpochTime           epochTime = new SystemEpochTime();
            Database database = new Database(keychain.LocalStorageKey, random, epochTime, directoryCreator, documentCollectionFactory, databaseCorruptionHandler);

            guestControllerClient = new GuestControllerClient(wwwCallFactory, guestControllerSpoofedIpAddress, database, string.Empty, guestControllerHostUrl, oneIdClientId, logger);
        }
    public NonRegisteredTransactorUpgradeSender(IKeychain keychain, AbstractLogger logger, string localStorageDirPath, string guestControllerHostUrl, string guestControllerSpoofedIpAddress, string oneIdClientId, ICoroutineManager coroutineManager)
    {
        SystemStopwatchFactory    stopwatchFactory          = new SystemStopwatchFactory();
        SystemWwwFactory          wwwFactory                = new SystemWwwFactory();
        WwwCallFactory            wwwCallFactory            = new WwwCallFactory(logger, coroutineManager, stopwatchFactory, wwwFactory);
        FileSystem                fileSystem                = new FileSystem();
        DatabaseDirectoryCreator  directoryCreator          = new DatabaseDirectoryCreator(fileSystem, localStorageDirPath);
        DocumentCollectionFactory documentCollectionFactory = new DocumentCollectionFactory();
        SystemRandom              random = new SystemRandom();
        DatabaseCorruptionHandler databaseCorruptionHandler = new DatabaseCorruptionHandler(logger, fileSystem, localStorageDirPath);
        SystemEpochTime           epochTime = new SystemEpochTime();
        Database database = new Database(keychain.LocalStorageKey, random, epochTime, directoryCreator, documentCollectionFactory, databaseCorruptionHandler);
        GuestControllerClient guestControllerClient = new GuestControllerClient(wwwCallFactory, guestControllerSpoofedIpAddress, database, "NoSWID", guestControllerHostUrl, oneIdClientId, logger);

        nrtUpgradeSender = new NrtUpgradeSender(logger, guestControllerClient);
    }
Example #26
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LoginManager"/> class.
        /// </summary>
        /// <param name="loginCache">The cache in which to store login details.</param>
        /// <param name="twoFactorChallengeHandler">The handler for 2FA challenges.</param>
        /// <param name="clientId">The application's client API ID.</param>
        /// <param name="clientSecret">The application's client API secret.</param>
        /// <param name="authorizationNote">An note to store with the authorization.</param>
        /// <param name="fingerprint">The machine fingerprint.</param>
        public LoginManager(
            IKeychain keychain,
            string clientId,
            string clientSecret,
            string authorizationNote = null,
            string fingerprint       = null)
        {
            Guard.ArgumentNotNull(keychain, nameof(keychain));
            Guard.ArgumentNotNullOrWhiteSpace(clientId, nameof(clientId));
            Guard.ArgumentNotNullOrWhiteSpace(clientSecret, nameof(clientSecret));

            this.keychain          = keychain;
            this.clientId          = clientId;
            this.clientSecret      = clientSecret;
            this.authorizationNote = authorizationNote;
            this.fingerprint       = fingerprint;
        }
Example #27
0
        public ApiClient(UriString hostUrl, IKeychain keychain, IProcessManager processManager, ITaskManager taskManager, IEnvironment environment)
        {
            Guard.ArgumentNotNull(keychain, nameof(keychain));

            var host = String.IsNullOrEmpty(hostUrl)
                ? UriString.ToUriString(HostAddress.GitHubDotComHostAddress.WebUri)
                : new UriString(hostUrl.ToRepositoryUri()
                                .GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped));

            HostAddress         = HostAddress.Create(host);
            OriginalUrl         = host;
            this.keychain       = keychain;
            this.processManager = processManager;
            this.taskManager    = taskManager;
            this.environment    = environment;
            loginManager        = new LoginManager(keychain, processManager, taskManager, environment);
        }
 public ConnectionManager(
     IProgram program,
     IConnectionCache cache,
     IKeychain keychain,
     ILoginManager loginManager,
     IUsageTracker usageTracker)
 {
     this.program      = program;
     this.cache        = cache;
     this.keychain     = keychain;
     this.loginManager = loginManager;
     this.usageTracker = usageTracker;
     loaded            = new TaskCompletionSource <object>();
     connections       = new Lazy <ObservableCollectionEx <IConnection> >(
         this.CreateConnections,
         LazyThreadSafetyMode.ExecutionAndPublication);
 }
Example #29
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LoginManager"/> class.
        /// </summary>
        /// <param name="keychain"></param>
        /// <param name="clientId">The application's client API ID.</param>
        /// <param name="clientSecret">The application's client API secret.</param>
        /// <param name="processManager"></param>
        /// <param name="taskManager"></param>
        /// <param name="nodeJsExecutablePath"></param>
        /// <param name="octorunScript"></param>
        public LoginManager(
            IKeychain keychain,
            string clientId,
            string clientSecret,
            IProcessManager processManager = null, ITaskManager taskManager = null, NPath?nodeJsExecutablePath = null, NPath?octorunScript = null)
        {
            Guard.ArgumentNotNull(keychain, nameof(keychain));
            Guard.ArgumentNotNullOrWhiteSpace(clientId, nameof(clientId));
            Guard.ArgumentNotNullOrWhiteSpace(clientSecret, nameof(clientSecret));

            this.keychain             = keychain;
            this.clientId             = clientId;
            this.clientSecret         = clientSecret;
            this.processManager       = processManager;
            this.taskManager          = taskManager;
            this.nodeJsExecutablePath = nodeJsExecutablePath;
            this.octorunScript        = octorunScript;
        }
Example #30
0
        /// <summary>
        /// Initializes a new instance of the <see cref="LoginManager"/> class.
        /// </summary>
        /// <param name="keychain">The keychain in which to store credentials.</param>
        /// <param name="twoFactorChallengeHandler">The handler for 2FA challenges.</param>
        /// <param name="clientId">The application's client API ID.</param>
        /// <param name="clientSecret">The application's client API secret.</param>
        /// <param name="authorizationNote">An note to store with the authorization.</param>
        /// <param name="fingerprint">The machine fingerprint.</param>
        public LoginManager(
            IKeychain keychain,
            Lazy <ITwoFactorChallengeHandler> twoFactorChallengeHandler,
            string clientId,
            string clientSecret,
            string authorizationNote = null,
            string fingerprint       = null)
        {
            Guard.ArgumentNotNull(keychain, nameof(keychain));
            Guard.ArgumentNotNull(twoFactorChallengeHandler, nameof(twoFactorChallengeHandler));
            Guard.ArgumentNotEmptyString(clientId, nameof(clientId));
            Guard.ArgumentNotEmptyString(clientSecret, nameof(clientSecret));

            this.keychain = keychain;
            this.twoFactorChallengeHandler = twoFactorChallengeHandler;
            this.clientId          = clientId;
            this.clientSecret      = clientSecret;
            this.authorizationNote = authorizationNote;
            this.fingerprint       = fingerprint;
        }