feat: Implement API client and token models with hashing and JWT authentication
- Added ApiClientModel and ApiTokenModel for managing API clients and tokens. - Introduced ConfigurationDefinitionModel and ConfigurationValueModel for configuration management. - Created CredentialSecretModel for storing credential secrets. - Developed DeploymentArtifactModel and DeploymentBatchModel for deployment management. - Enhanced DeploymentTargetModel and DeploymentTemplateSelectionModel to support template revisions. - Added TemplateRevisionModel and TemplateVersionModel for versioning templates. - Implemented ApiClientSecretHasher for secure secret hashing. - Created ApiTokenService for generating and validating JWT tokens. - Updated QueueJobService to handle deployment requests with artifacts. - Configured authentication settings in appsettings.json for JWT and Negotiate authentication.
This commit is contained in:
28
Models/ApiClientModel.cs
Normal file
28
Models/ApiClientModel.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Models
|
||||
{
|
||||
public class ApiClientModel : BaseModel
|
||||
{
|
||||
[Column(Order = 1)]
|
||||
public string ClientId { get; set; } = string.Empty;
|
||||
|
||||
[Column(Order = 2)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[Column(Order = 3)]
|
||||
public string SecretHash { get; set; } = string.Empty;
|
||||
|
||||
[Column(Order = 4)]
|
||||
public string ScopesJson { get; set; } = "[]";
|
||||
|
||||
[Column(Order = 5)]
|
||||
public bool IsEnabled { get; set; } = true;
|
||||
|
||||
[Column(Order = 6)]
|
||||
public DateTime? ExpiresAt { get; set; }
|
||||
|
||||
[Column(Order = 7)]
|
||||
public DateTime? LastUsedAt { get; set; }
|
||||
}
|
||||
}
|
||||
42
Models/ApiTokenModel.cs
Normal file
42
Models/ApiTokenModel.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Models
|
||||
{
|
||||
public class ApiTokenModel : BaseModel
|
||||
{
|
||||
[Column(Order = 1)]
|
||||
public string Jti { get; set; } = string.Empty;
|
||||
|
||||
[Column(Order = 2)]
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
|
||||
[Column(Order = 3)]
|
||||
public string SubjectType { get; set; } = "User";
|
||||
|
||||
[Column(Order = 4)]
|
||||
public Guid? ApiClientId { get; set; }
|
||||
|
||||
[Column(Order = 5)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[Column(Order = 6)]
|
||||
public string ScopesJson { get; set; } = "[]";
|
||||
|
||||
[Column(Order = 7)]
|
||||
public DateTime IssuedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Column(Order = 8)]
|
||||
public DateTime ExpiresAt { get; set; }
|
||||
|
||||
[Column(Order = 9)]
|
||||
public DateTime? RevokedAt { get; set; }
|
||||
|
||||
[Column(Order = 10)]
|
||||
public string? RevokedBy { get; set; }
|
||||
|
||||
[Column(Order = 11)]
|
||||
public DateTime? LastUsedAt { get; set; }
|
||||
|
||||
public ApiClientModel? ApiClient { get; set; }
|
||||
}
|
||||
}
|
||||
31
Models/ConfigurationDefinitionModel.cs
Normal file
31
Models/ConfigurationDefinitionModel.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Models
|
||||
{
|
||||
public static class ConfigurationDefinitionKinds
|
||||
{
|
||||
public const string Parameter = "Parameter";
|
||||
public const string Variable = "Variable";
|
||||
}
|
||||
|
||||
public class ConfigurationDefinitionModel : BaseModel
|
||||
{
|
||||
[Column(Order = 1)]
|
||||
public Guid? TemplateRevisionId { get; set; }
|
||||
|
||||
[Column(Order = 2)]
|
||||
public string Kind { get; set; } = ConfigurationDefinitionKinds.Parameter;
|
||||
|
||||
[Column(Order = 3)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[Column(Order = 4)]
|
||||
public string PropertiesJson { get; set; } = "{}";
|
||||
|
||||
[Column(Order = 5)]
|
||||
public string DefinitionHash { get; set; } = string.Empty;
|
||||
|
||||
public TemplateRevisionModel? TemplateRevision { get; set; }
|
||||
public ICollection<ConfigurationValueModel> Values { get; set; } = new List<ConfigurationValueModel>();
|
||||
}
|
||||
}
|
||||
52
Models/ConfigurationValueModel.cs
Normal file
52
Models/ConfigurationValueModel.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Models
|
||||
{
|
||||
public static class ConfigurationValueSourceTypes
|
||||
{
|
||||
public const string Static = "Static";
|
||||
public const string ScopeProperty = "ScopeProperty";
|
||||
public const string Expression = "Expression";
|
||||
public const string SecretReference = "SecretReference";
|
||||
}
|
||||
|
||||
public static class ConfigurationValueScopeTypes
|
||||
{
|
||||
public const string TemplateRevision = "TemplateRevision";
|
||||
public const string Environment = "Environment";
|
||||
public const string Domain = "Domain";
|
||||
public const string Target = "Target";
|
||||
public const string DeploymentGroup = "DeploymentGroup";
|
||||
public const string Deployment = "Deployment";
|
||||
public const string TemplateSelection = "TemplateSelection";
|
||||
}
|
||||
|
||||
public class ConfigurationValueModel : BaseModel
|
||||
{
|
||||
[Column(Order = 1)]
|
||||
public Guid ConfigurationDefinitionId { get; set; }
|
||||
|
||||
[Column(Order = 2)]
|
||||
public string ScopeType { get; set; } = ConfigurationValueScopeTypes.TemplateRevision;
|
||||
|
||||
[Column(Order = 3)]
|
||||
public Guid ScopeId { get; set; }
|
||||
|
||||
[Column(Order = 4)]
|
||||
public string ValueSourceType { get; set; } = ConfigurationValueSourceTypes.Static;
|
||||
|
||||
[Column(Order = 5)]
|
||||
public string? SourcePath { get; set; }
|
||||
|
||||
[Column(Order = 6)]
|
||||
public string? ValueJson { get; set; }
|
||||
|
||||
[Column(Order = 7)]
|
||||
public string ValueHash { get; set; } = string.Empty;
|
||||
|
||||
[Column(Order = 8)]
|
||||
public int SortOrder { get; set; }
|
||||
|
||||
public ConfigurationDefinitionModel ConfigurationDefinition { get; set; } = null!;
|
||||
}
|
||||
}
|
||||
25
Models/CredentialSecretModel.cs
Normal file
25
Models/CredentialSecretModel.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Models
|
||||
{
|
||||
public class CredentialSecretModel : BaseModel
|
||||
{
|
||||
[Column(Order = 1)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[Column(Order = 2)]
|
||||
public string? UserName { get; set; }
|
||||
|
||||
[Column(Order = 3)]
|
||||
public string SecretValue { get; set; } = string.Empty;
|
||||
|
||||
[Column(Order = 4)]
|
||||
public string SecretType { get; set; } = "Credential";
|
||||
|
||||
[Column(Order = 5)]
|
||||
public string? MetadataJson { get; set; }
|
||||
|
||||
[Column(Order = 6)]
|
||||
public bool IsEnabled { get; set; } = true;
|
||||
}
|
||||
}
|
||||
58
Models/DeploymentArtifactModel.cs
Normal file
58
Models/DeploymentArtifactModel.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Models
|
||||
{
|
||||
public static class DeploymentArtifactTypes
|
||||
{
|
||||
public const string Preview = "Preview";
|
||||
public const string ResolvedConfigurationData = "ResolvedConfigurationData";
|
||||
public const string Mof = "Mof";
|
||||
public const string PullServerPackage = "PullServerPackage";
|
||||
}
|
||||
|
||||
public class DeploymentArtifactModel : BaseModel
|
||||
{
|
||||
[Column(Order = 1)]
|
||||
public Guid DeploymentGroupId { get; set; }
|
||||
|
||||
[Column(Order = 2)]
|
||||
public Guid? DeploymentTargetId { get; set; }
|
||||
|
||||
[Column(Order = 3)]
|
||||
public Guid? TargetId { get; set; }
|
||||
|
||||
[Column(Order = 4)]
|
||||
public string ArtifactType { get; set; } = DeploymentArtifactTypes.ResolvedConfigurationData;
|
||||
|
||||
[Column(Order = 5)]
|
||||
public string Status { get; set; } = QueueJobStatus.Pending;
|
||||
|
||||
[Column(Order = 6)]
|
||||
public string DeploymentJson { get; set; } = "{}";
|
||||
|
||||
[Column(Order = 7)]
|
||||
public string? SourceJson { get; set; }
|
||||
|
||||
[Column(Order = 8)]
|
||||
public string? ResolvedJson { get; set; }
|
||||
|
||||
[Column(Order = 9)]
|
||||
public string? SourceSnapshotJson { get; set; }
|
||||
|
||||
[Column(Order = 10)]
|
||||
public string InputHash { get; set; } = string.Empty;
|
||||
|
||||
[Column(Order = 11)]
|
||||
public string OutputHash { get; set; } = string.Empty;
|
||||
|
||||
[Column(Order = 12)]
|
||||
public bool IsStale { get; set; }
|
||||
|
||||
[Column(Order = 13)]
|
||||
public string? StaleReasonJson { get; set; }
|
||||
|
||||
public DeploymentGroupModel DeploymentGroup { get; set; } = null!;
|
||||
public DeploymentModel? Deployment { get; set; }
|
||||
public TargetModel? Target { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ namespace Microsoft.SelfService.Portal.Core.API.Models
|
||||
public ICollection<DeploymentTemplateSelectionModel> TemplateSelections { get; set; } = new List<DeploymentTemplateSelectionModel>();
|
||||
public ICollection<DeploymentParameterValueModel> ParameterValues { get; set; } = new List<DeploymentParameterValueModel>();
|
||||
public ICollection<DeploymentTargetAssignmentModel> TargetAssignments { get; set; } = new List<DeploymentTargetAssignmentModel>();
|
||||
public ICollection<DeploymentArtifactModel> Artifacts { get; set; } = new List<DeploymentArtifactModel>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,23 @@ namespace Microsoft.SelfService.Portal.Core.API.Models
|
||||
[Column(Order = 3)]
|
||||
public Guid TargetId { get; set; }
|
||||
[Column(Order = 4)]
|
||||
public string Status { get; set; }
|
||||
public Guid? TemplateRevisionId { get; set; }
|
||||
[Column(Order = 5)]
|
||||
public Guid? CurrentArtifactId { get; set; }
|
||||
[Column(Order = 6)]
|
||||
public string Status { get; set; }
|
||||
[Column(Order = 7)]
|
||||
public string JSONData { get; set; }
|
||||
[Column(Order = 8)]
|
||||
public string? OverridesJson { get; set; }
|
||||
[Column(Order = 9)]
|
||||
public string? SourceJson { get; set; }
|
||||
|
||||
public DeploymentGroupModel DeploymentGroup { get; set; }
|
||||
public TargetModel Target { get; set; }
|
||||
public TemplateRevisionModel? TemplateRevision { get; set; }
|
||||
public DeploymentArtifactModel? CurrentArtifact { get; set; }
|
||||
public ICollection<DeploymentArtifactModel> Artifacts { get; set; } = new List<DeploymentArtifactModel>();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,16 +11,20 @@ namespace Microsoft.SelfService.Portal.Core.API.Models
|
||||
public Guid TemplateVersionId { get; set; }
|
||||
|
||||
[Column(Order = 3)]
|
||||
public string TemplateRole { get; set; } = "Service";
|
||||
public Guid? TemplateRevisionId { get; set; }
|
||||
|
||||
[Column(Order = 4)]
|
||||
public int SortOrder { get; set; }
|
||||
public string TemplateRole { get; set; } = "Service";
|
||||
|
||||
[Column(Order = 5)]
|
||||
public int SortOrder { get; set; }
|
||||
|
||||
[Column(Order = 6)]
|
||||
public string? Alias { get; set; }
|
||||
|
||||
public DeploymentGroupModel DeploymentGroup { get; set; } = null!;
|
||||
public TemplateVersionModel TemplateVersion { get; set; } = null!;
|
||||
public TemplateRevisionModel? TemplateRevision { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
45
Models/TemplateRevisionModel.cs
Normal file
45
Models/TemplateRevisionModel.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Microsoft.SelfService.Portal.Core.API.Models
|
||||
{
|
||||
public class TemplateRevisionModel : BaseModel
|
||||
{
|
||||
[Column(Order = 1)]
|
||||
public Guid TemplateVersionId { get; set; }
|
||||
|
||||
[Column(Order = 2)]
|
||||
public int RevisionNumber { get; set; }
|
||||
|
||||
[Column(Order = 3)]
|
||||
public string JsonData { get; set; } = "{}";
|
||||
|
||||
[Column(Order = 4)]
|
||||
public string JsonHash { get; set; } = string.Empty;
|
||||
|
||||
[Column(Order = 5)]
|
||||
public string SchemaVersion { get; set; } = "1.0";
|
||||
|
||||
[Column(Order = 6)]
|
||||
public bool IsCurrent { get; set; }
|
||||
|
||||
[Column(Order = 7)]
|
||||
public bool IsPublished { get; set; }
|
||||
|
||||
[Column(Order = 8)]
|
||||
public DateTime? PublishedAt { get; set; }
|
||||
|
||||
[Column(Order = 9)]
|
||||
public string? PublishedBy { get; set; }
|
||||
|
||||
public TemplateVersionModel TemplateVersion { get; set; } = null!;
|
||||
public ICollection<ConfigurationDefinitionModel> ConfigurationDefinitions { get; set; } = new List<ConfigurationDefinitionModel>();
|
||||
public ICollection<DeploymentTemplateSelectionModel> DeploymentTemplateSelections { get; set; } = new List<DeploymentTemplateSelectionModel>();
|
||||
public ICollection<DeploymentModel> Deployments { get; set; } = new List<DeploymentModel>();
|
||||
|
||||
public void SetJsonData(string jsonData)
|
||||
{
|
||||
JsonData = string.IsNullOrWhiteSpace(jsonData) ? "{}" : jsonData;
|
||||
JsonHash = TemplateVersionModel.ComputeSha256(JsonData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ namespace Microsoft.SelfService.Portal.Core.API.Models
|
||||
public string? PublishedBy { get; set; }
|
||||
|
||||
public TemplateModel Template { get; set; } = null!;
|
||||
public ICollection<TemplateRevisionModel> TemplateRevisions { get; set; } = new List<TemplateRevisionModel>();
|
||||
|
||||
public void SetJsonData(string jsonData)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user