98 lines
3.0 KiB
C#
98 lines
3.0 KiB
C#
using Socialize.Api.Modules.Identity.Contracts;
|
|
|
|
namespace Socialize.Api.Modules.Approvals.Services;
|
|
|
|
public static class ApprovalModes
|
|
{
|
|
public const string None = "None";
|
|
public const string Optional = "Optional";
|
|
public const string Required = "Required";
|
|
public const string MultiLevel = "Multi-level";
|
|
}
|
|
|
|
public static class ApprovalWorkflowRules
|
|
{
|
|
public static bool BlocksManualApprovedOrScheduledStatus(string approvalMode)
|
|
{
|
|
return approvalMode is ApprovalModes.Required or ApprovalModes.MultiLevel;
|
|
}
|
|
|
|
public static bool IsApprovalCompletionStatus(string status)
|
|
{
|
|
return status is "Approved" or "Scheduled";
|
|
}
|
|
|
|
public static string GetFinalApprovalStatus(bool schedulePostsAutomaticallyOnApproval, DateTimeOffset? plannedPublishDate)
|
|
{
|
|
return schedulePostsAutomaticallyOnApproval && plannedPublishDate.HasValue
|
|
? "Scheduled"
|
|
: "Approved";
|
|
}
|
|
|
|
public static bool HasRequiredStepApprovals(int approvedDecisionCount, int requiredApproverCount)
|
|
{
|
|
return approvedDecisionCount >= Math.Max(1, requiredApproverCount);
|
|
}
|
|
|
|
public static bool CanApproveWorkflowStep(
|
|
bool isAdministrator,
|
|
bool hasWorkspaceAccess,
|
|
IReadOnlyCollection<string> userRoles,
|
|
Guid userId,
|
|
string? targetType,
|
|
string? targetValue)
|
|
{
|
|
if (isAdministrator)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (!hasWorkspaceAccess ||
|
|
string.IsNullOrWhiteSpace(targetType) ||
|
|
string.IsNullOrWhiteSpace(targetValue))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return targetType switch
|
|
{
|
|
ApprovalStepTargetTypes.Role => userRoles.Contains(targetValue),
|
|
ApprovalStepTargetTypes.Membership => MatchesMembershipTarget(userRoles, targetValue),
|
|
ApprovalStepTargetTypes.Member => ParseMemberTargetIds(targetValue).Contains(userId),
|
|
_ => false,
|
|
};
|
|
}
|
|
|
|
public static IReadOnlyCollection<Guid> ParseMemberTargetIds(string? targetValue)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(targetValue))
|
|
{
|
|
return [];
|
|
}
|
|
|
|
return targetValue
|
|
.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
|
|
.Select(value => Guid.TryParse(value, out Guid memberUserId) ? memberUserId : Guid.Empty)
|
|
.Where(memberUserId => memberUserId != Guid.Empty)
|
|
.Distinct()
|
|
.ToArray();
|
|
}
|
|
|
|
public static string FormatMemberTargetValue(IEnumerable<Guid> memberUserIds)
|
|
{
|
|
return string.Join(",", memberUserIds.Distinct().OrderBy(memberUserId => memberUserId));
|
|
}
|
|
|
|
private static bool MatchesMembershipTarget(
|
|
IReadOnlyCollection<string> userRoles,
|
|
string targetValue)
|
|
{
|
|
return targetValue switch
|
|
{
|
|
ApprovalMembershipTargets.Client => userRoles.Contains(KnownRoles.Client),
|
|
ApprovalMembershipTargets.Team => !userRoles.Contains(KnownRoles.Client),
|
|
_ => false,
|
|
};
|
|
}
|
|
}
|