!Alle folgenden Funktionen (außer Login und Logout) müssen in einem authentifizierten Kontext aufgerufen werden. Verwenden Sie also zuerst die Login-Funktion, bevor Sie eine der folgenden Funktionen ausführen.
Mit Benutzername und Passwort einloggen
private static async Task Login()
{
// Accept invalid certificates - until .NET Framework 4.6
// When using .NET Framework 4.7 or higher, you need to
// create an own HttpClientHandler and set the callback there
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
Console.Write("Enter your endpoint IP's to proceed (xxx.xxx.xxx.xxx): ");
var endpointIp = Console.ReadLine();
var psrApi = new PsrApi($"{endpointIp}:11016");
Console.WriteLine($"Available databases: {string.Join(", ", await psrApi.GetActiveDatabaseNames())}");
Console.Write("Database: ");
var database = Console.ReadLine();
Console.Write("Username: ");
var username = Console.ReadLine();
Console.Write("Password: ");
var password = ReadPassword();
var mfaRequest = await psrApi.AuthenticationManager.Login(database, username, password);
if (mfaRequest != null)
{
await PerformMultiFactorAuth(mfaRequest, psrApi, database, username, password);
}
psrApi.ServerStatusChanged += (sender, status) => Console.WriteLine(status);
psrApi.SessionExpired += async (sender, e) =>
{
Console.WriteLine("Session has expired");
//For example, you could relogin here...
};
Console.WriteLine($"Logged in; Session expiring at: { psrApi.SessionExpirationUtc?.ToLocalTime() }");
psrApi.RealtimeEventManager.ServerMessageReceived += (sender, args) =>
Console.WriteLine(args.ServerMessage.Message + $" was received ({args.ServerMessage.MessageType.ToString()})");
psrApi.RealtimeEventManager.ContainerChanged += (sender, args) =>
Console.WriteLine(args.Container.DataName() + $" was changed ({args.EventType.ToString()})");
psrApi.RealtimeEventManager.RoleChanged += (sender, args) =>
Console.WriteLine(args.Role.DataName() + $" was changed ({args.EventType.ToString()})");
psrApi.RealtimeEventManager.UserChanged += (sender, args) =>
Console.WriteLine(args.User.DataName() + $" was changed ({args.EventType.ToString()})");
psrApi.RealtimeEventManager.GroupChanged += (sender, args) =>
Console.WriteLine(args.Group.DataName() + $" was changed ({args.EventType.ToString()})");
psrApi.RealtimeEventManager.DataBindingChanged += (sender, args) =>
Console.WriteLine(args.DataBinding.DataId + $" was changed ({args.EventType.ToString()})");
_psrApi = psrApi;
}
private static async Task PerformMultiFactorAuth(PsrMultiFactorAuthenticationRequest mfaRequest, PsrApi psrApi, string database, string username, string password)
{
if (mfaRequest.AuthenticatorType == PsrMultiFactorAuthType.Pki)
{
var pkiFields = GetCertificatePkiFields(mfaRequest);
mfaRequest.RequiredFields.ToList().Find(f => f.Type == PsrMultiFactorField.SignedDataId).Value = pkiFields.SignedDataId;
mfaRequest.RequiredFields.ToList().Find(f => f.Type == PsrMultiFactorField.CertificateThumbPrint).Value = pkiFields.CertificateThumbPrint;
}
else
{
foreach (var field in mfaRequest.RequiredFields)
{
Console.Write($"Enter 2nd factor '{mfaRequest.DisplayName}' ({field.Type.ToString()}): ");
var mfa = field.Type == PsrMultiFactorField.Pin || field.Type == PsrMultiFactorField.NewPinRequired
? ReadPassword()
: Console.ReadLine();
field.Value = mfa;
}
}
await psrApi.AuthenticationManager.Login(database, username, password, mfaRequest.RequiredFields);
}
private static PkiFields GetCertificatePkiFields(PsrMultiFactorAuthenticationRequest mfaRequest)
{
Console.WriteLine("Select a certificate from the store");
var store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.IncludeArchived);
var collection = store.Certificates.Find(X509FindType.FindByKeyUsage, X509KeyUsageFlags.KeyEncipherment, true);
var selectedCert = X509Certificate2UI.SelectFromCollection(collection, "Select a certificate from the store", "",
X509SelectionFlag.SingleSelection)[0];
if (!(selectedCert.PrivateKey is RSACryptoServiceProvider csp))
{
throw new Exception();
}
string signedHash;
using (var hashAlgo = HashAlgorithm.Create(HashAlgorithms.Sha1.ToString()))
{
if (hashAlgo == null)
{
throw new Exception();
}
var hash = hashAlgo.ComputeHash(mfaRequest.DataToSign);
var oid = CryptoConfig.MapNameToOID(HashAlgorithms.Sha1.ToString());
var bytes = csp.SignHash(hash, oid);
signedHash = Convert.ToBase64String(bytes);
}
return new PkiFields()
{
SignedDataId = signedHash,
CertificateThumbPrint = selectedCert.Thumbprint
};
}
Ausloggen
await _psrApi.AuthenticationManager.Logout();
Console.WriteLine("PsrApi logged out")
Ein Passwort für den eigenen Benutzer erstellen
var newPassword = _psrApi.PasswordManager.GeneratePhoneticPassword(20, 3, PasswordGeneratorSeparator.Hyphen, true);
var passwordContainer = new PsrContainer
{
ContainerType = PsrContainerType.Password,
Items = new List<PsrContainerItem>
{
new PsrContainerItem
{
Name = "Name",
ContainerItemType = PsrContainerItemType.ContainerItemText,
Value = "MyPsrApiPassword_SIMPLE",
},
new PsrContainerItem
{
Name = "Password",
ContainerItemType = PsrContainerItemType.ContainerItemPassword,
PlainTextValue = "utlra secret password goes here",
},
}
};
var savedPassword = await _psrApi.ContainerManager.AddContainer(passwordContainer, _psrApi.CurrentUser.Id);
Console.WriteLine($"Password {passwordContainer.DataName()} ({savedPassword.Id}) created");
Ein Passwort für eine Organisationseinheit erstellen
var passwordContainer = new PsrContainer
{
ContainerType = PsrContainerType.Password,
Items = new List<PsrContainerItem>
{
new PsrContainerItem
{
Name = "Name",
ContainerItemType = PsrContainerItemType.ContainerItemText,
Value = "MyPsrApiPassword_SIMPLE",
},
new PsrContainerItem
{
Name = "Password",
ContainerItemType = PsrContainerItemType.ContainerItemPassword,
PlainTextValue = "utlra secret password goes here",
},
}
};
// find the organisational unit to put our new password (we take the most top ou)
var filter = new PsrListFilter
{
DataStates = PsrDataStates.StateActive,
FilterGroups = new List<PsrListFilterGroup>
{
new PsrListFilterGroupOrganisationUnitType
{
TypeFilters = new List<PsrListFilterObjectOrganisationUnitType>
{
new PsrListFilterObjectOrganisationUnitType
{
FilterActive = true,
OrganisationUnitType = PsrFilterOrganisationUnitType.FilterOrganisationUnitTypeGroup
}
}
}
}
};
var ouGroups = await _psrApi.OrganisationUnitManager.GetOrganisationUnitStructure(filter);
var topLevelOu = ouGroups?.FirstOrDefault();
var targetOu = topLevelOu?.OrganisationUnit ?? _psrApi.CurrentUser;
var savedPassword = await _psrApi.ContainerManager.AddContainer(passwordContainer, targetOu.Id);
Console.WriteLine($"Password {passwordContainer.DataName()} ({savedPassword.Id}) created in OU {targetOu.DataName()}");
Ein Passwort mittels einem bestimmten Formulars für den eigenen Benutzer erstellen
var formsFilter = await _psrApi.ContainerManager.GetContainerListFilter(PsrContainerType.Form, true);
var availableForms = await _psrApi.ContainerManager.GetContainerList(PsrContainerType.Form, formsFilter);
if (!availableForms.Any())
{
Console.WriteLine("no forms found");
return;
}
var passwordContainer = _psrApi.ContainerManager.CreateContainerFromBaseContainer(availableForms.FirstOrDefault(), PsrContainerType.Password);
var textField = passwordContainer.Items.FirstOrDefault(ci => ci.ContainerItemType == PsrContainerItemType.ContainerItemText);
if (textField != null) textField.Value = "MyPsrApiPassword_FORM";
var urlField = passwordContainer.Items.FirstOrDefault(ci => ci.ContainerItemType == PsrContainerItemType.ContainerItemUrl);
if (urlField != null) urlField.Value = "https://www.passwordsafe.de";
var passwordField = passwordContainer.Items.FirstOrDefault(ci => ci.IsPasswordItem());
if (passwordField != null)
{
var newPassword = _psrApi.PasswordManager.GeneratePhoneticPassword(20, 3, PasswordGeneratorSeparator.Hyphen, true);
passwordField.PlainTextValue = newPassword;
}
var savedPassword = await _psrApi.ContainerManager.AddContainer(passwordContainer, _psrApi.CurrentUser.Id);
Console.WriteLine($"Password {passwordContainer.DataName()} ({savedPassword.Id}) created");
Passwörter mit Hilfe der Inhaltssuche finden
var filter = new PsrContainerListFilter
{
DataStates = PsrDataStates.StateActive,
FilterGroups = new List<PsrListFilterGroup>
{
new PsrListFilterGroupContent
{
SearchList = new List<PsrListFilterObjectContent>
{
new PsrListFilterObjectContent
{
FilterActive = true,
Search = "MyPsrApiPassword_",
}
}
}
}
};
var passwords = await _psrApi.ContainerManager.GetContainerList(PsrContainerType.Password, filter);
Console.WriteLine($"{passwords.Count()} Passwords found with Content 'MyPsrApiPassword_'");
Ein Passwort mittels der ID finden
var password = await _psrApi.ContainerManager.GetContainer(id);
if (password != null) Console.WriteLine($"Password {password.DataName()} retrieved by Guid");
Ein Passwort aktualisieren
private static async Task UpdatePassword(PsrContainer updatePassword)
{
var textField = updatePassword.Items.FirstOrDefault(ci => ci.ContainerItemType == PsrContainerItemType.ContainerItemText);
if (textField != null) textField.Value = "MyPsrApiPassword_UPDATE";
var passwordField = updatePassword.Items.FirstOrDefault(ci => ci.IsPasswordItem());
if (passwordField != null)
{
var newPassword = _psrApi.PasswordManager.GeneratePhoneticPassword(20, 3, PasswordGeneratorSeparator.Hyphen, true);
passwordField.PlainTextValue = "UPDATED_SECRET_PASSWORD_" + newPassword;
}
await _psrApi.ContainerManager.UpdateContainer(updatePassword);
Console.WriteLine($"Password {updatePassword.Id} updated");
}
Ein Passwort löschen
await _psrApi.ContainerManager.DeleteContainer(deletePassword);
Console.WriteLine($"Password {deletePassword.Id} deleted");
Benutzer zum Mitglied einer Rolle machen
private static async Task MakeUserRoleMember(Guid userId, Guid roleId)
{
var role = await _psrApi.RoleManager.GetRole(roleId);
var user = await _psrApi.OrganisationUnitManager.GetOrganisationUnitUser(userId);
var rights = (await _psrApi.RightManager.GetLegitimateDataRightsWithTemporalRights(roleId, DateTime.MinValue, DateTime.MaxValue)).ToList();
rights.Add(new PsrDataRight
{
DataId = roleId,
LegitimateId = userId,
Legitimate = user,
IncludeDataRightKey = true,
Rights = PsrRights.RightRead
});
await _psrApi.GenericRightManager.SaveRights(new List<PsrData> { role }, rights, false, false);
}
Eine Organisationseinheit anhand des Namens finden
private static async Task<IEnumerable<PsrOrganisationUnitStructure>> FindOrganisationUnitsByName(string name, PsrOrganisationUnit parent = null)
{
var filterGroups = new List<PsrListFilterGroup>
{
new PsrListFilterGroupContent
{
SearchList = new List<PsrListFilterObjectContent>
{
new PsrListFilterObjectContent
{
FilterActive = true,
Search = name,
}
}
}
};
// if we should search in a specified parent, we have to add this as filter condition as well
if (parent != null)
{
filterGroups.Add(new PsrListFilterGroupOrganisationUnit
{
OrganisationUnitFilter = new PsrListFilterObjectOrganisationUnit
{
FilterActive = true,
SelectedOrganisationUnitId = parent.Id
}
});
}
var ouContentFilter = new PsrListFilter
{
DataStates = PsrDataStates.StateActive,
FilterGroups = filterGroups
};
return (await _psrApi.OrganisationUnitManager.GetOrganisationUnitStructure(ouContentFilter));
}
Erstellen einer Organisationseinheit unterhalb einer bereits existierenden
private static Task<PsrOrganisationUnitGroup> CreateOrgainsationUnitGroup(string name, PsrOrganisationUnit parent = null)
{
var rsa = new PsrRsa();
var group = new PsrOrganisationUnitGroup
{
GroupName = name,
PublicKey = rsa.PublicKey,
};
var encryptedGroupKey = PsrEncryption.EncryptWithPublicKey(_psrApi.CurrentUser.PublicKey, rsa.PrivateKey);
return _psrApi.OrganisationUnitManager.AddOrganisationUnitGroup(group, _psrApi.CurrentUser.PublicKey, encryptedGroupKey, parent?.Id);
}
Überprüfen, ob eine Organisationseinheit unterhalb einer bestimmten Organisationseinheit existiert und wenn nicht Erstellen dieser.
private static async Task<PsrOrganisationUnit> CheckIfOuExists(string parentOuName, string findOrCreateOuName)
{
var myParentOu = (await FindOrganisationUnitsByName(parentOuName)).FirstOrDefault();
if (myParentOu == null)
{
Console.WriteLine("Parent-OU doesn't exist");
return null;
}
var myChildOu = (await FindOrganisationUnitsByName(findOrCreateOuName, myParentOu.OrganisationUnit)).FirstOrDefault();
if (myChildOu != null)
{
Console.WriteLine("ou found -> not creating anything");
return myChildOu.OrganisationUnit;
}
Console.WriteLine("ou not found -> we create now the ou group");
return await CreateOrgainsationUnitGroup(findOrCreateOuName, myParentOu.OrganisationUnit);
}
Alle Benutzer finden, die Datenbank-Administrator sind
private static async Task LoadAllDatabaseAdmins()
{
var onlyUserOus = new PsrListFilter
{
FilterGroups = new List<PsrListFilterGroup>
{
new PsrListFilterGroupOrganisationUnitType
{
TypeFilters = new List<PsrListFilterObjectOrganisationUnitType>
{
new PsrListFilterObjectOrganisationUnitType
{
FilterActive = true,
OrganisationUnitType = PsrFilterOrganisationUnitType.FilterOrganisationUnitTypeUser
}
}
}
}
};
Console.WriteLine($"Following Users have the Database Admin Right:");
var organisationUnitUsers = await _psrApi.OrganisationUnitManager.GetOrganisationUnitStructure(onlyUserOus);
foreach (var user in organisationUnitUsers.Select(ous => ous.OrganisationUnit as PsrOrganisationUnitUser))
{
var rightsOfUsers = await _psrApi.OptionManager.GetOptions(new List<PsrOptionGroup>{PsrOptionGroup.OptionGroupUserRights}, user);
var dbAdminRight = rightsOfUsers.FirstOrDefault(r => r.Name == PsrUserRightDefaults.UserRightIsDatabaseAdministrator);
if (dbAdminRight is PsrOptionBoolean bDbAdminRight && bDbAdminRight.ValueBoolean)
{
Console.WriteLine($"- {user.UserName}");
}
}
}