Skip to content

Commit 11c5de0

Browse files
committed
Secret Manager: device/client management
1 parent 35fccb9 commit 11c5de0

11 files changed

+1825
-184
lines changed

Commander/ConnectedCommands.cs

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,10 +1769,23 @@ private void DumpSecretManagerApplicationInfo(VaultData vault, SecretsManagerApp
17691769
DumpRowNo = true
17701770
};
17711771

1772-
clientTab.AddHeader("Name", "Created", "Last Accessed", "Expires");
1773-
foreach (var client in application.Devices)
1772+
var nameLength = 6;
1773+
var s = new HashSet<string>();
1774+
while (true)
17741775
{
1775-
clientTab.AddRow(client.Name, client.CreatedOn, client.LastAccess, client.AccessExpireOn);
1776+
s.Clear();
1777+
s.UnionWith(application.Devices.Select(x => x.DeviceId.Substring(0, nameLength)));
1778+
if (s.Count == application.Devices.Length)
1779+
{
1780+
break;
1781+
}
1782+
nameLength++;
1783+
}
1784+
1785+
clientTab.AddHeader("Name", "Device ID", "Created", "Last Accessed", "Expires");
1786+
foreach (var client in application.Devices)
1787+
{
1788+
clientTab.AddRow(client.Name, client.DeviceId.Substring(0, nameLength), client.CreatedOn, client.LastAccess, client.AccessExpireOn);
17761789
}
17771790

17781791
Console.WriteLine("{0, 20}: {1}", "Application UID", application.Uid);
@@ -1927,19 +1940,59 @@ record = folder.Records.Select(x => _vault.GetRecord(x)).FirstOrDefault(x =>
19271940
}
19281941
}
19291942

1930-
if (string.IsNullOrEmpty(uid)) {
1943+
if (string.IsNullOrEmpty(uid))
1944+
{
19311945
uid = arguments.Secret;
19321946
}
19331947
var app = await _vault.GetSecretManagerApplication(application.Uid);
19341948
var share = app.Shares.FirstOrDefault(x => x.SecretUid == uid);
1935-
1949+
19361950
if (share == null)
19371951
{
19381952
Console.Write($"\"{arguments.Secret}\" is not shared to application {application.Title}");
19391953
}
19401954
app = await _vault.UnshareFromSecretManagerApplication(application.Uid, uid);
19411955
DumpSecretManagerApplicationInfo(_vault, app);
19421956
}
1957+
else if (action == "add-client")
1958+
{
1959+
var unlockIp = arguments.UnlockIP;
1960+
int? firstAccess = arguments.CreateExpire > 0 ? arguments.CreateExpire : (int?) null;
1961+
int? accessExpire = arguments.AccessExpire > 0 ? arguments.AccessExpire : (int?) null;
1962+
var t = await _vault.AddSecretManagerClient(application.Uid, unlockIp: unlockIp,
1963+
firstAccessExpireInMinutes: firstAccess, accessExpiresInMinutes: accessExpire,
1964+
name: arguments.ClientName);
1965+
1966+
var device = t.Item1;
1967+
var clientKey = t.Item2;
1968+
1969+
Console.WriteLine("Successfully generated Client Device\n");
1970+
Console.WriteLine($"One-Time Access Token: { clientKey}");
1971+
var ipLock = device.LockIp ? "Enabled" : "Disabled";
1972+
Console.WriteLine($"IP Lock: {ipLock}");
1973+
var firstAccessOn = device.FirstAccessExpireOn.HasValue ? device.FirstAccessExpireOn.Value.ToString("G") : "Taken";
1974+
Console.WriteLine($"Token Expires On: {device.FirstAccessExpireOn.Value}");
1975+
var accessExpireOn = device.AccessExpireOn.HasValue ? device.AccessExpireOn.Value.ToString("G") : "Never";
1976+
Console.WriteLine($"App Access Expires On: {accessExpireOn}");
1977+
}
1978+
else if (action == "delete-client")
1979+
{
1980+
if (string.IsNullOrEmpty(arguments.ClientName))
1981+
{
1982+
Console.Write("\"client-name\" parameter is required");
1983+
return;
1984+
}
1985+
1986+
var app = await _vault.GetSecretManagerApplication(application.Uid);
1987+
var device = app.Devices.FirstOrDefault(x => x.Name == arguments.ClientName || x.DeviceId.StartsWith(arguments.ClientName));
1988+
if (device == null)
1989+
{
1990+
Console.Write($"Device \"{arguments.ClientName}\" is not found in application {application.Title}");
1991+
return;
1992+
}
1993+
await _vault.DeleteSecretManagerClient(application.Uid, device.DeviceId);
1994+
Console.Write($"Client \"{device.Name}\" has been deleted from application {application.Title}");
1995+
}
19431996
else
19441997
{
19451998
Console.Write($"Unsupported KSM command {arguments.Command}");
@@ -2879,13 +2932,22 @@ class MakeFolderOptions : FolderOptions
28792932

28802933
class SecretManagerOptions
28812934
{
2882-
[Option("folder", Required = false, HelpText = "Shared Folder UID or name")]
2935+
[Option("folder", Required = false, HelpText = "Shared Folder UID or name. \"share\", \"unshare\" only")]
28832936
public string Secret { get; set; }
2884-
[Option('e', "can-edit", Required = false, HelpText = "Can secret be edited")]
2937+
[Option('e', "can-edit", Required = false, HelpText = "Can secret be edited? \"share\", \"unshare\" only")]
28852938
public bool CanEdit { get; set; }
28862939

2940+
[Option("client-name", Required = false, HelpText = "Client name. \"add-client\", \"remove-client\" only")]
2941+
public string ClientName { get; set; }
2942+
[Option("unlock-ip", Required = false, HelpText = "Unlock IP Address? \"add-client\" only")]
2943+
public bool UnlockIP { get; set; }
2944+
[Option("create-expire", Required = false, HelpText = "Device creation expitation in minutes. \"add-client\" only")]
2945+
public int CreateExpire { get; set; }
2946+
[Option("access-expire", Required = false, HelpText = "Device access expitation in minutes. \"add-client\" only")]
2947+
public int AccessExpire { get; set; }
2948+
28872949

2888-
[Value(0, Required = false, HelpText = "KSM command: \"view\", \"create\", \"delete\", \"share\", \"unshare\", \"list\"")]
2950+
[Value(0, Required = false, HelpText = "KSM command: \"view\", \"create\", \"delete\", \"share\", \"unshare\", \"add-client\", \"delete-client\", \"list\"")]
28892951
public string Command { get; set; }
28902952

28912953
[Value(1, Required = false, HelpText = "Secret Manager application UID or Title")]

0 commit comments

Comments
 (0)