Beispiel #1
0
    public void PrepareRegistrationChallenge(Guid correlationId, string emailOrPhone, ContactChallengePurpose purpose) {
      if (ContactChallenges.ContainsKey(correlationId))
        throw new CommandRejectedException(nameof(correlationId), correlationId, CommandRejectionReason.AlreadyApplied,
          $"Contact challenge for correlationId '{correlationId}' has already been prepared.");

      string stamp = Guid.NewGuid().ToString();
      string code = ContactChallengers.TotpCodeProvider.Generate(Id, emailOrPhone, purpose, stamp);
      string token = ContactChallengers.DataProtectionTokenProvider.Generate(Id, purpose, stamp);
      var assembly = Assembly.GetExecutingAssembly();
      string message = assembly.GetManifestResourceText(assembly.GetManifestResourceName($"{purpose}.Message.txt")).Replace("{Code}", code);
      ContactChallengePrepared eventToRaise;
      switch (purpose) {

        case ContactChallengePurpose.CreateUserFromEmail:
          string subject = assembly.GetManifestResourceText(assembly.GetManifestResourceName($"{purpose}.Subject.txt"));
          eventToRaise = new ContactEmailChallengePrepared(Id, DateTime.UtcNow, correlationId,
            emailOrPhone, purpose, stamp, token, subject, message);
          break;

        case ContactChallengePurpose.CreateUserFromPhone:
          var phoneNumber = ContactIdParser.AsPhoneNumber(emailOrPhone);
          eventToRaise = new ContactSmsChallengePrepared(Id, DateTime.UtcNow, correlationId,
            phoneNumber.NationalNumber, ContactIdParser.DefaultRegionCode, emailOrPhone, purpose, stamp, token, message);
          break;

        default:
          throw new CommandRejectedException(nameof(emailOrPhone), emailOrPhone, CommandRejectionReason.Unknown);
      }

      RaiseEvent(eventToRaise);
    }
 public static string Generate(Guid userId, string contactValue, ContactChallengePurpose purpose, string stamp) {
   byte[] stampBytes = Encoding.Unicode.GetBytes(stamp);
   string modifier = $"Totp:{purpose}:{contactValue}:{userId}";
   int code = Rfc6238AuthenticationService.GenerateCode(stampBytes, modifier);
   string totpCode = code.ToString("D6", CultureInfo.InvariantCulture);
   return totpCode;
 }
    private bool ValidateCore(string token, Guid userId, ContactChallengePurpose purpose, string stamp) {
      try {
        byte[] unprotectedData = Protector.Unprotect(Convert.FromBase64String(token));
        var ms = new MemoryStream(unprotectedData);
        using (var reader = new BinaryReader(ms, DefaultEncoding, true)) {
          DateTimeOffset creationTime = new DateTimeOffset(reader.ReadInt64(), TimeSpan.Zero);
          DateTimeOffset expirationTime = creationTime + TokenLifespan;
          if (expirationTime < DateTimeOffset.UtcNow) {
            return false;
          }

          string tokenUserId = reader.ReadString();
          if (!string.Equals(tokenUserId, userId.ToString(), StringComparison.OrdinalIgnoreCase)) {
            return false;
          }

          var tokenPurpose = reader.ReadString();
          if (!string.Equals(tokenPurpose, purpose.ToString())) {
            return false;
          }

          var tokenStamp = reader.ReadString();
          if (reader.PeekChar() != -1) {
            return false;
          }

          bool isTokenValid = tokenStamp == stamp;
          return isTokenValid;
        }
      } catch {
        // do not leak exception
        return false;
      }
    }
    public ContactEmailChallengePrepared(Guid aggregateId, DateTime happenedOn,
      Guid correlationId, string emailAddress, ContactChallengePurpose purpose,
      string stamp, string token, string messageSubject, string messageBody)
      : base(aggregateId, happenedOn, correlationId, purpose, stamp, token) {

      EmailAddress = emailAddress;
      MessageSubject = messageSubject;
      MessageBody = messageBody;
    }
    protected ContactChallengePrepared(Guid aggregateId, DateTime happenedOn,
      Guid correlationId, ContactChallengePurpose purpose, string stamp, string token)
      : base(aggregateId, happenedOn) {

      CorrelationId = correlationId;
      Purpose = purpose;
      Stamp = stamp;
      Token = token;
    }
 public static bool Validate(string totpCode, Guid userId, string contactValue, ContactChallengePurpose purpose, string stamp) {
   byte[] stampBytes = Encoding.Unicode.GetBytes(stamp);
   int code;
   if (!int.TryParse(totpCode, out code))
     return false;
   string modifier = $"Totp:{purpose}:{contactValue}:{userId}";
   bool isValid = Rfc6238AuthenticationService.ValidateCode(stampBytes, code, modifier);
   return isValid;
 }
    public ContactSmsChallengePrepared(Guid aggregateId, DateTime happenedOn,
      Guid correlationId, ulong phoneNumber, string regionCode, string unformattedPhone,
      ContactChallengePurpose purpose, string stamp, string token, string message)
      : base(aggregateId, happenedOn, correlationId, purpose, stamp, token) {

      PhoneNumber = phoneNumber;
      RegionCode = regionCode;
      UnformattedPhone = unformattedPhone;
      Message = message;
    }
    private string GenerateCore(Guid userId, ContactChallengePurpose purpose, string stamp) {
      MemoryStream memoryStream = new MemoryStream();
      using (var writer = new BinaryWriter(memoryStream, DefaultEncoding, true)) {
        writer.Write(DateTimeOffset.UtcNow.Ticks);
        writer.Write(userId.ToString());
        writer.Write(purpose.ToString());
        writer.Write(stamp);
      }

      byte[] protectedBytes = Protector.Protect(memoryStream.ToArray());
      string token = Convert.ToBase64String(protectedBytes);
      return token;
    }
 internal static bool Validate(string token, Guid userId, ContactChallengePurpose purpose, string stamp) {
   return new DataProtectionTokenProvider().ValidateCore(token, userId, purpose, stamp);
 }
 internal static string Generate(Guid userId, ContactChallengePurpose purpose, string stamp) {
   return new DataProtectionTokenProvider().GenerateCore(userId, purpose, stamp);
 }