Skip to content

Commit a8789a9

Browse files
authored
[OIDC] DB migration for federated credentials, associate policy with API key (#10285)
1 parent 4ca9831 commit a8789a9

7 files changed

Lines changed: 283 additions & 3 deletions

File tree

src/NuGet.Services.Entities/Credential.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
@@ -86,10 +86,14 @@ public Credential(string type, string value, TimeSpan? expiration)
8686

8787
public bool? WasCreatedSecurely { get; set; }
8888

89+
public int? FederatedCredentialPolicyKey { get; set; }
90+
8991
public virtual User User { get; set; }
9092

9193
public virtual ICollection<Scope> Scopes { get; set; }
9294

95+
public virtual FederatedCredentialPolicy FederatedCredentialPolicy { get; set; }
96+
9397
[NotMapped]
9498
public bool HasExpired
9599
{

src/NuGetGallery.Core/Entities/EntitiesContext.cs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
@@ -84,6 +84,8 @@ public IDisposable WithQueryHint(string queryHint)
8484
public DbSet<PackageVulnerability> Vulnerabilities { get; set; }
8585
public DbSet<VulnerablePackageVersionRange> VulnerableRanges { get; set; }
8686
public DbSet<PackageRename> PackageRenames { get; set; }
87+
public DbSet<FederatedCredentialPolicy> FederatedCredentialPolicies { get; set; }
88+
public DbSet<FederatedCredential> FederatedCredentials { get; set; }
8789

8890
/// <summary>
8991
/// User or organization accounts.
@@ -558,6 +560,54 @@ protected override void OnModelCreating(DbModelBuilder modelBuilder)
558560
.WithMany()
559561
.HasForeignKey(r => r.ToPackageRegistrationKey)
560562
.WillCascadeOnDelete(false);
563+
564+
modelBuilder.Entity<FederatedCredentialPolicy>()
565+
.HasKey(x => x.Key);
566+
567+
modelBuilder.Entity<FederatedCredentialPolicy>()
568+
.Property(x => x.Created)
569+
.HasColumnType("datetime2");
570+
571+
modelBuilder.Entity<FederatedCredentialPolicy>()
572+
.Property(x => x.LastMatched)
573+
.IsOptional()
574+
.HasColumnType("datetime2");
575+
576+
modelBuilder.Entity<FederatedCredentialPolicy>()
577+
.HasRequired(x => x.CreatedBy)
578+
.WithMany()
579+
.HasForeignKey(x => x.CreatedByUserKey)
580+
.WillCascadeOnDelete(false); // users are only soft deleted today
581+
582+
modelBuilder.Entity<FederatedCredentialPolicy>()
583+
.HasRequired(x => x.PackageOwner)
584+
.WithMany()
585+
.HasForeignKey(x => x.PackageOwnerUserKey)
586+
.WillCascadeOnDelete(false); // users are only soft deleted today
587+
588+
modelBuilder.Entity<FederatedCredentialPolicy>()
589+
.HasMany(x => x.Credentials)
590+
.WithOptional(c => c.FederatedCredentialPolicy)
591+
.WillCascadeOnDelete(false); // deletion must be done explicitly to improve per-credential auditing
592+
593+
modelBuilder.Entity<FederatedCredential>()
594+
.HasKey(x => x.Key);
595+
596+
modelBuilder.Entity<FederatedCredential>()
597+
.Property(x => x.Created)
598+
.HasColumnType("datetime2");
599+
600+
modelBuilder.Entity<FederatedCredential>()
601+
.Property(x => x.Expires)
602+
.IsOptional()
603+
.HasColumnType("datetime2");
604+
605+
modelBuilder.Entity<FederatedCredential>()
606+
.HasIndex(x => x.Identity)
607+
.IsUnique();
608+
609+
modelBuilder.Entity<FederatedCredential>()
610+
.HasIndex(x => x.FederatedCredentialPolicyKey);
561611
}
562612

563613
#pragma warning restore 618
@@ -578,4 +628,4 @@ public void Dispose()
578628
}
579629
}
580630
}
581-
}
631+
}

src/NuGetGallery.Services/Authentication/CredentialBuilder.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public Credential CreateShortLivedApiKey(TimeSpan expiration, FederatedCredentia
4545
// Tracking: https://github.com/NuGet/NuGetGallery/issues/10212
4646
var credential = CreateApiKey(expiration, out plaintextApiKey);
4747

48+
credential.FederatedCredentialPolicy = policy;
4849
credential.Description = "Short-lived API key generated via a federated credential";
4950
credential.Scopes = [new Scope(policy.PackageOwner, NuGetPackagePattern.AllInclusivePattern, NuGetScopes.All)];
5051

src/NuGetGallery/Migrations/202410302050035_AddFederatedCredentials.Designer.cs

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
namespace NuGetGallery.Migrations
2+
{
3+
using System;
4+
using System.Data.Entity.Migrations;
5+
6+
public partial class AddFederatedCredentials : DbMigration
7+
{
8+
public override void Up()
9+
{
10+
CreateTable(
11+
"dbo.FederatedCredentialPolicies",
12+
c => new
13+
{
14+
Key = c.Int(nullable: false, identity: true),
15+
Created = c.DateTime(nullable: false, precision: 7, storeType: "datetime2"),
16+
LastMatched = c.DateTime(precision: 7, storeType: "datetime2"),
17+
TypeKey = c.Int(nullable: false),
18+
Criteria = c.String(nullable: false),
19+
CreatedByUserKey = c.Int(nullable: false),
20+
PackageOwnerUserKey = c.Int(nullable: false),
21+
})
22+
.PrimaryKey(t => t.Key)
23+
.ForeignKey("dbo.Users", t => t.CreatedByUserKey)
24+
.ForeignKey("dbo.Users", t => t.PackageOwnerUserKey)
25+
.Index(t => t.CreatedByUserKey)
26+
.Index(t => t.PackageOwnerUserKey);
27+
28+
CreateTable(
29+
"dbo.FederatedCredentials",
30+
c => new
31+
{
32+
Key = c.Int(nullable: false, identity: true),
33+
TypeKey = c.Int(nullable: false),
34+
FederatedCredentialPolicyKey = c.Int(nullable: false),
35+
Identity = c.String(maxLength: 64),
36+
Created = c.DateTime(nullable: false, precision: 7, storeType: "datetime2"),
37+
Expires = c.DateTime(precision: 7, storeType: "datetime2"),
38+
})
39+
.PrimaryKey(t => t.Key)
40+
.Index(t => t.FederatedCredentialPolicyKey)
41+
.Index(t => t.Identity, unique: true);
42+
43+
AddColumn("dbo.Credentials", "FederatedCredentialPolicyKey", c => c.Int());
44+
CreateIndex("dbo.Credentials", "FederatedCredentialPolicyKey");
45+
AddForeignKey("dbo.Credentials", "FederatedCredentialPolicyKey", "dbo.FederatedCredentialPolicies", "Key");
46+
}
47+
48+
public override void Down()
49+
{
50+
DropForeignKey("dbo.FederatedCredentialPolicies", "PackageOwnerUserKey", "dbo.Users");
51+
DropForeignKey("dbo.Credentials", "FederatedCredentialPolicyKey", "dbo.FederatedCredentialPolicies");
52+
DropForeignKey("dbo.FederatedCredentialPolicies", "CreatedByUserKey", "dbo.Users");
53+
DropIndex("dbo.FederatedCredentials", new[] { "Identity" });
54+
DropIndex("dbo.FederatedCredentials", new[] { "FederatedCredentialPolicyKey" });
55+
DropIndex("dbo.FederatedCredentialPolicies", new[] { "PackageOwnerUserKey" });
56+
DropIndex("dbo.FederatedCredentialPolicies", new[] { "CreatedByUserKey" });
57+
DropIndex("dbo.Credentials", new[] { "FederatedCredentialPolicyKey" });
58+
DropColumn("dbo.Credentials", "FederatedCredentialPolicyKey");
59+
DropTable("dbo.FederatedCredentials");
60+
DropTable("dbo.FederatedCredentialPolicies");
61+
}
62+
}
63+
}

src/NuGetGallery/Migrations/202410302050035_AddFederatedCredentials.resx

Lines changed: 126 additions & 0 deletions
Large diffs are not rendered by default.

src/NuGetGallery/NuGetGallery.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,10 @@
347347
<Compile Include="Migrations\202205300006043_Int64PackageDownloadCount.designer.cs">
348348
<DependentUpon>202205300006043_Int64PackageDownloadCount.cs</DependentUpon>
349349
</Compile>
350+
<Compile Include="Migrations\202410302050035_AddFederatedCredentials.cs" />
351+
<Compile Include="Migrations\202410302050035_AddFederatedCredentials.Designer.cs">
352+
<DependentUpon>202410302050035_AddFederatedCredentials.cs</DependentUpon>
353+
</Compile>
350354
<Compile Include="Modules\CookieComplianceHttpModule.cs" />
351355
<Compile Include="RequestModels\DeletePackagesApiRequest.cs" />
352356
<Compile Include="RequestModels\UpdateListedRequest.cs" />
@@ -1707,6 +1711,9 @@
17071711
<EmbeddedResource Include="Migrations\202205300006043_Int64PackageDownloadCount.resx">
17081712
<DependentUpon>202205300006043_Int64PackageDownloadCount.cs</DependentUpon>
17091713
</EmbeddedResource>
1714+
<EmbeddedResource Include="Migrations\202410302050035_AddFederatedCredentials.resx">
1715+
<DependentUpon>202410302050035_AddFederatedCredentials.cs</DependentUpon>
1716+
</EmbeddedResource>
17101717
<EmbeddedResource Include="OData\QueryAllowed\Data\apiv1packages.json" />
17111718
<EmbeddedResource Include="OData\QueryAllowed\Data\apiv1search.json" />
17121719
<EmbeddedResource Include="OData\QueryAllowed\Data\apiv2getupdates.json" />

0 commit comments

Comments
 (0)