public void FromOtpAuthMigrationAuthenticatorTest(OtpAuthMigration.Authenticator migration, Authenticator b)
        {
            var a = Authenticator.FromOtpAuthMigrationAuthenticator(migration, _iconResolver);

            Assert.Equal(a.Type, b.Type);
            Assert.Equal(a.Algorithm, b.Algorithm);
            Assert.Equal(a.Counter, b.Counter);
            Assert.Equal(a.Digits, b.Digits);
            Assert.Equal(a.Period, b.Period);
            Assert.Equal(a.Issuer, b.Issuer);
            Assert.Equal(a.Username, b.Username);
            Assert.True(Base32.Rfc4648.Decode(a.Secret).SequenceEqual(Base32.Rfc4648.Decode(b.Secret)));
        }
        public void FromOtpAuthMigrationAuthenticatorTest(OtpAuthMigration.Authenticator migration, Authenticator b)
        {
            var a = Authenticator.FromOtpAuthMigrationAuthenticator(migration, _iconResolver);

            Assert.Equal(a.Type, b.Type);
            Assert.Equal(a.Algorithm, b.Algorithm);
            Assert.Equal(a.Counter, b.Counter);
            Assert.Equal(a.Digits, b.Digits);
            Assert.Equal(a.Period, b.Period);
            Assert.Equal(a.Issuer, b.Issuer);
            Assert.Equal(a.Username, b.Username);
            Assert.Equal(Base32Encoding.ToBytes(a.Secret), Base32Encoding.ToBytes(b.Secret));
        }
        public void FromOtpAuthMigrationAuthenticatorTest(OtpAuthMigration.Authenticator migration, Authenticator b)
        {
            var a = Authenticator.FromOtpAuthMigrationAuthenticator(migration);

            Assert.That(a.Type == b.Type);
            Assert.That(a.Algorithm == b.Algorithm);
            Assert.That(a.Counter == b.Counter);
            Assert.That(a.Digits == b.Digits);
            Assert.That(a.Period == b.Period);
            Assert.That(a.Issuer == b.Issuer);
            Assert.That(a.Username == b.Username);
            Assert.That(Base32Encoding.ToBytes(a.Secret).SequenceEqual(Base32Encoding.ToBytes(b.Secret)));
        }
        public static Authenticator FromOtpAuthMigrationAuthenticator(OtpAuthMigration.Authenticator input,
                                                                      IIconResolver iconResolver)
        {
            string issuer;
            string username;

            // Google Auth may not have an issuer, just use the username instead
            if (String.IsNullOrEmpty(input.Issuer))
            {
                issuer   = input.Username.Trim().Truncate(IssuerMaxLength);
                username = null;
            }
            else
            {
                issuer = input.Issuer.Trim().Truncate(IssuerMaxLength);
                // For some odd reason the username field always follows a '[issuer]: [username]' format
                username = input.Username.Replace($"{input.Issuer}: ", "").Trim().Truncate(UsernameMaxLength);
            }

            var type = input.Type switch
            {
                OtpAuthMigration.Type.Totp => AuthenticatorType.Totp,
                OtpAuthMigration.Type.Hotp => AuthenticatorType.Hotp,
                _ => throw new ArgumentOutOfRangeException(nameof(input.Type), "Unknown type")
            };

            var algorithm = input.Algorithm switch
            {
                OtpAuthMigration.Algorithm.Sha1 => HashAlgorithm.Sha1,
                _ => throw new ArgumentOutOfRangeException(nameof(input.Algorithm), "Unknown algorithm")
            };

            string secret;

            try
            {
                secret = Base32.Rfc4648.Encode(input.Secret);
                secret = CleanSecret(secret, type);
            }
            catch (Exception e)
            {
                throw new ArgumentException("Failed to parse secret", e);
            }

            var auth = new Authenticator
            {
                Issuer    = issuer,
                Username  = username,
                Algorithm = algorithm,
                Type      = type,
                Secret    = secret,
                Counter   = input.Counter,
                Digits    = type.GetDefaultDigits(),
                Period    = type.GetDefaultPeriod(),
                Icon      = iconResolver.FindServiceKeyByName(issuer)
            };

            if (!auth.IsValid())
            {
                throw new ArgumentException("Authenticator is invalid");
            }

            return(auth);
        }