Browse Source

Replace the Timestamp properties by new ConcurrencyToken properties to work around a MySQL limitation

pull/504/head
Kévin Chalet 8 years ago
parent
commit
37e24a5e76
  1. 36
      src/OpenIddict.EntityFramework/OpenIddictExtensions.cs
  2. 5
      src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs
  3. 9
      src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs
  4. 5
      src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs
  5. 5
      src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs
  6. 34
      src/OpenIddict.EntityFrameworkCore/OpenIddictExtensions.cs
  7. 5
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs
  8. 9
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
  9. 7
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs
  10. 5
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs
  11. 11
      src/OpenIddict.Models/OpenIddictApplication.cs
  12. 11
      src/OpenIddict.Models/OpenIddictAuthorization.cs
  13. 5
      src/OpenIddict.Models/OpenIddictScope.cs
  14. 11
      src/OpenIddict.Models/OpenIddictToken.cs

36
src/OpenIddict.EntityFramework/OpenIddictExtensions.cs

@ -193,10 +193,8 @@ namespace Microsoft.Extensions.DependencyInjection
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute()));
builder.Entity<TApplication>()
.Property(application => application.Timestamp)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed)
.IsConcurrencyToken()
.IsRowVersion();
.Property(application => application.ConcurrencyToken)
.IsConcurrencyToken();
builder.Entity<TApplication>()
.Property(application => application.Type)
@ -220,6 +218,10 @@ namespace Microsoft.Extensions.DependencyInjection
builder.Entity<TAuthorization>()
.HasKey(authorization => authorization.Id);
builder.Entity<TAuthorization>()
.Property(authorization => authorization.ConcurrencyToken)
.IsConcurrencyToken();
builder.Entity<TAuthorization>()
.Property(authorization => authorization.Status)
.IsRequired();
@ -228,12 +230,6 @@ namespace Microsoft.Extensions.DependencyInjection
.Property(authorization => authorization.Subject)
.IsRequired();
builder.Entity<TAuthorization>()
.Property(authorization => authorization.Timestamp)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed)
.IsConcurrencyToken()
.IsRowVersion();
builder.Entity<TAuthorization>()
.Property(authorization => authorization.Type)
.IsRequired();
@ -252,14 +248,12 @@ namespace Microsoft.Extensions.DependencyInjection
.HasKey(scope => scope.Id);
builder.Entity<TScope>()
.Property(scope => scope.Name)
.IsRequired();
.Property(scope => scope.ConcurrencyToken)
.IsConcurrencyToken();
builder.Entity<TScope>()
.Property(scope => scope.Timestamp)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed)
.IsConcurrencyToken()
.IsRowVersion();
.Property(scope => scope.Name)
.IsRequired();
builder.Entity<TScope>()
.ToTable("OpenIddictScopes");
@ -268,6 +262,10 @@ namespace Microsoft.Extensions.DependencyInjection
builder.Entity<TToken>()
.HasKey(token => token.Id);
builder.Entity<TToken>()
.Property(token => token.ConcurrencyToken)
.IsConcurrencyToken();
builder.Entity<TToken>()
.Property(token => token.Hash)
.HasMaxLength(450)
@ -277,12 +275,6 @@ namespace Microsoft.Extensions.DependencyInjection
.Property(token => token.Subject)
.IsRequired();
builder.Entity<TToken>()
.Property(token => token.Timestamp)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed)
.IsConcurrencyToken()
.IsRowVersion();
builder.Entity<TToken>()
.Property(token => token.Type)
.IsRequired();

5
src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs

@ -281,6 +281,11 @@ namespace OpenIddict.EntityFramework
}
Applications.Attach(application);
// Generate a new concurrency token and attach it
// to the application before persisting the changes.
application.ConcurrencyToken = Guid.NewGuid().ToString();
Context.Entry(application).State = EntityState.Modified;
return Context.SaveChangesAsync(cancellationToken);

9
src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs

@ -329,8 +329,17 @@ namespace OpenIddict.EntityFramework
/// </returns>
public override Task UpdateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
{
if (authorization == null)
{
throw new ArgumentNullException(nameof(authorization));
}
Authorizations.Attach(authorization);
// Generate a new concurrency token and attach it
// to the authorization before persisting the changes.
authorization.ConcurrencyToken = Guid.NewGuid().ToString();
Context.Entry(authorization).State = EntityState.Modified;
return Context.SaveChangesAsync(cancellationToken);

5
src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs

@ -206,6 +206,11 @@ namespace OpenIddict.EntityFramework
}
Scopes.Attach(scope);
// Generate a new concurrency token and attach it
// to the scope before persisting the changes.
scope.ConcurrencyToken = Guid.NewGuid().ToString();
Context.Entry(scope).State = EntityState.Modified;
return Context.SaveChangesAsync(cancellationToken);

5
src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs

@ -393,6 +393,11 @@ namespace OpenIddict.EntityFramework
}
Tokens.Attach(token);
// Generate a new concurrency token and attach it
// to the token before persisting the changes.
token.ConcurrencyToken = Guid.NewGuid().ToString();
Context.Entry(token).State = EntityState.Modified;
return Context.SaveChangesAsync(cancellationToken);

34
src/OpenIddict.EntityFrameworkCore/OpenIddictExtensions.cs

@ -223,15 +223,13 @@ namespace Microsoft.Extensions.DependencyInjection
entity.HasKey(application => application.Id);
entity.HasIndex(application => application.ClientId)
.IsUnique(unique: true);
.IsUnique();
entity.Property(application => application.ClientId)
.IsRequired(required: true);
.IsRequired();
entity.Property(application => application.Timestamp)
.ValueGeneratedOnAddOrUpdate()
.IsConcurrencyToken()
.IsRowVersion();
entity.Property(application => application.ConcurrencyToken)
.IsConcurrencyToken();
entity.Property(application => application.Type)
.IsRequired();
@ -255,17 +253,15 @@ namespace Microsoft.Extensions.DependencyInjection
{
entity.HasKey(authorization => authorization.Id);
entity.Property(authorization => authorization.ConcurrencyToken)
.IsConcurrencyToken();
entity.Property(authorization => authorization.Status)
.IsRequired();
entity.Property(authorization => authorization.Subject)
.IsRequired();
entity.Property(authorization => authorization.Timestamp)
.ValueGeneratedOnAddOrUpdate()
.IsConcurrencyToken()
.IsRowVersion();
entity.Property(authorization => authorization.Type)
.IsRequired();
@ -283,10 +279,8 @@ namespace Microsoft.Extensions.DependencyInjection
{
entity.HasKey(scope => scope.Id);
entity.Property(scope => scope.Timestamp)
.ValueGeneratedOnAddOrUpdate()
.IsConcurrencyToken()
.IsRowVersion();
entity.Property(scope => scope.ConcurrencyToken)
.IsConcurrencyToken();
entity.Property(scope => scope.Name)
.IsRequired();
@ -300,16 +294,14 @@ namespace Microsoft.Extensions.DependencyInjection
entity.HasKey(token => token.Id);
entity.HasIndex(token => token.Hash)
.IsUnique(unique: true);
.IsUnique();
entity.Property(token => token.ConcurrencyToken)
.IsConcurrencyToken();
entity.Property(token => token.Subject)
.IsRequired();
entity.Property(token => token.Timestamp)
.ValueGeneratedOnAddOrUpdate()
.IsConcurrencyToken()
.IsRowVersion();
entity.Property(token => token.Type)
.IsRequired();

5
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs

@ -281,6 +281,11 @@ namespace OpenIddict.EntityFrameworkCore
}
Context.Attach(application);
// Generate a new concurrency token and attach it
// to the application before persisting the changes.
application.ConcurrencyToken = Guid.NewGuid().ToString();
Context.Update(application);
return Context.SaveChangesAsync(cancellationToken);

9
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs

@ -371,8 +371,17 @@ namespace OpenIddict.EntityFrameworkCore
/// </returns>
public override Task UpdateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
{
if (authorization == null)
{
throw new ArgumentNullException(nameof(authorization));
}
Context.Attach(authorization);
// Generate a new concurrency token and attach it
// to the authorization before persisting the changes.
authorization.ConcurrencyToken = Guid.NewGuid().ToString();
Context.Update(authorization);
return Context.SaveChangesAsync(cancellationToken);

7
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs

@ -206,7 +206,12 @@ namespace OpenIddict.EntityFrameworkCore
}
Context.Attach(scope);
Context.Entry(scope).State = EntityState.Modified;
// Generate a new concurrency token and attach it
// to the scope before persisting the changes.
scope.ConcurrencyToken = Guid.NewGuid().ToString();
Context.Update(scope);
return Context.SaveChangesAsync(cancellationToken);
}

5
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs

@ -463,6 +463,11 @@ namespace OpenIddict.EntityFrameworkCore
}
Context.Attach(token);
// Generate a new concurrency token and attach it
// to the token before persisting the changes.
token.ConcurrencyToken = Guid.NewGuid().ToString();
Context.Update(token);
return Context.SaveChangesAsync(cancellationToken);

11
src/OpenIddict.Models/OpenIddictApplication.cs

@ -51,6 +51,11 @@ namespace OpenIddict.Models
/// </summary>
public virtual string ClientSecret { get; set; }
/// <summary>
/// Gets or sets the concurrency token.
/// </summary>
public virtual string ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
/// <summary>
/// Gets or sets the display name
/// associated with the current application.
@ -77,12 +82,6 @@ namespace OpenIddict.Models
/// </summary>
public virtual string RedirectUris { get; set; }
/// <summary>
/// Gets or sets the timestamp associated with the current
/// application, which is used as a concurrency token.
/// </summary>
public virtual byte[] Timestamp { get; set; }
/// <summary>
/// Gets the list of the tokens associated with this application.
/// </summary>

11
src/OpenIddict.Models/OpenIddictAuthorization.cs

@ -38,6 +38,11 @@ namespace OpenIddict.Models
/// </summary>
public virtual TApplication Application { get; set; }
/// <summary>
/// Gets or sets the concurrency token.
/// </summary>
public virtual string ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
/// <summary>
/// Gets or sets the unique identifier
/// associated with the current authorization.
@ -60,12 +65,6 @@ namespace OpenIddict.Models
/// </summary>
public virtual string Subject { get; set; }
/// <summary>
/// Gets or sets the timestamp associated with the current
/// authorization, which is used as a concurrency token.
/// </summary>
public virtual byte[] Timestamp { get; set; }
/// <summary>
/// Gets or sets the list of tokens
/// associated with the current authorization.

5
src/OpenIddict.Models/OpenIddictScope.cs

@ -26,10 +26,9 @@ namespace OpenIddict.Models
public class OpenIddictScope<TKey> where TKey : IEquatable<TKey>
{
/// <summary>
/// Gets or sets the timestamp associated with the
/// current scope, which is used as a concurrency token.
/// Gets or sets the concurrency token.
/// </summary>
public virtual byte[] Timestamp { get; set; }
public virtual string ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
/// <summary>
/// Gets or sets the public description

11
src/OpenIddict.Models/OpenIddictToken.cs

@ -50,6 +50,11 @@ namespace OpenIddict.Models
/// </summary>
public virtual string Ciphertext { get; set; }
/// <summary>
/// Gets or sets the concurrency token.
/// </summary>
public virtual string ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
/// <summary>
/// Gets or sets the date on which the token
/// will start to be considered valid.
@ -85,12 +90,6 @@ namespace OpenIddict.Models
/// </summary>
public virtual string Subject { get; set; }
/// <summary>
/// Gets or sets the timestamp associated with the
/// current token, which is used as a concurrency token.
/// </summary>
public virtual byte[] Timestamp { get; set; }
/// <summary>
/// Gets or sets the type of the current token.
/// </summary>

Loading…
Cancel
Save