Change webmodule to have async return value
This commit is contained in:
@@ -43,7 +43,7 @@ public class ListBackupsModule : IWebModule
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IDictionary<string, string> Execute(IDictionary<string, string?> options)
|
||||
public async Task<IDictionary<string, string>> Execute(IDictionary<string, string?> options, CancellationToken cancellationToken)
|
||||
{
|
||||
var opts = new Dictionary<string, string?>(options);
|
||||
|
||||
@@ -71,7 +71,7 @@ public class ListBackupsModule : IWebModule
|
||||
using var backend = new DuplicatiBackend(url, opts);
|
||||
return new Dictionary<string, string>()
|
||||
{
|
||||
{ "folders", JsonSerializer.Serialize( backend.ListBackupFolders(CancellationToken.None).ToArrayAsync().Await()) }
|
||||
{ "folders", JsonSerializer.Serialize( await backend.ListBackupFolders(cancellationToken).ToArrayAsync(cancellationToken) ) }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public class GetApiKeyModule : IWebModule
|
||||
];
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDictionary<string, string> Execute(IDictionary<string, string?> options)
|
||||
public async Task<IDictionary<string, string>> Execute(IDictionary<string, string?> options, CancellationToken cancellationToken)
|
||||
{
|
||||
options.TryGetValue("filen-operation", out var operation);
|
||||
if (operation != "GetApiKey")
|
||||
@@ -71,7 +71,7 @@ public class GetApiKeyModule : IWebModule
|
||||
newOpts[key] = uri.QueryParameters[key];
|
||||
|
||||
var backend = new FilenBackend(url, newOpts);
|
||||
var apiKey = backend.GetApiKey(CancellationToken.None).Await();
|
||||
var apiKey = await backend.GetApiKey(cancellationToken).ConfigureAwait(false);
|
||||
return new Dictionary<string, string> { { "api-key", apiKey ?? string.Empty } };
|
||||
}
|
||||
|
||||
|
||||
@@ -42,11 +42,11 @@ namespace Duplicati.Library.Backend.GoogleServices
|
||||
|
||||
#region IWebModule implementation
|
||||
|
||||
public IDictionary<string, string?> Execute(IDictionary<string, string?> options)
|
||||
public Task<IDictionary<string, string?>> Execute(IDictionary<string, string?> options, CancellationToken cancellationToken)
|
||||
{
|
||||
var ct = Utility.Utility.ParseEnumOption(options.AsReadOnly(), KEY_CONFIGTYPE, DEFAULT_CONFIG_TYPE);
|
||||
GetLookups().TryGetValue(ct.ToString(), out var dict);
|
||||
return dict ?? new Dictionary<string, string?>();
|
||||
return Task.FromResult(dict ?? new Dictionary<string, string?>());
|
||||
}
|
||||
|
||||
public string Key => "gcs-getconfig";
|
||||
|
||||
@@ -38,11 +38,11 @@ namespace Duplicati.Library.Backend.OpenStack
|
||||
{
|
||||
}
|
||||
|
||||
public IDictionary<string, string?> Execute(IDictionary<string, string?> options)
|
||||
public Task<IDictionary<string, string?>> Execute(IDictionary<string, string?> options, CancellationToken cancellationToken)
|
||||
{
|
||||
var ct = Utility.Utility.ParseEnumOption(options.AsReadOnly(), KEY_CONFIGTYPE, DEFAULT_CONFIG_TYPE);
|
||||
GetLookups().TryGetValue(ct.ToString(), out var dict);
|
||||
return dict ?? new Dictionary<string, string?>();
|
||||
return Task.FromResult(dict ?? new Dictionary<string, string?>());
|
||||
}
|
||||
|
||||
public string Key => "openstack-getconfig";
|
||||
|
||||
@@ -43,11 +43,11 @@ namespace Duplicati.Library.Backend
|
||||
|
||||
#region IWebModule implementation
|
||||
|
||||
public IDictionary<string, string?> Execute(IDictionary<string, string?> options)
|
||||
public Task<IDictionary<string, string?>> Execute(IDictionary<string, string?> options, CancellationToken cancellationToken)
|
||||
{
|
||||
var ct = Utility.Utility.ParseEnumOption(options.AsReadOnly(), KEY_CONFIGTYPE, DEFAULT_CONFIG_TYPE);
|
||||
GetLookups().TryGetValue(ct.ToString(), out var dict);
|
||||
return dict ?? new Dictionary<string, string?>();
|
||||
return Task.FromResult(dict ?? new Dictionary<string, string?>());
|
||||
}
|
||||
|
||||
public string Key => "s3-getconfig";
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Duplicati.Library.Backend
|
||||
new CommandLineArgument(KEY_PASSWORD, CommandLineArgument.ArgumentType.String, Strings.S3IAM.PasswordShort, Strings.S3IAM.PasswordLong)
|
||||
]);
|
||||
|
||||
public IDictionary<string, string> Execute(IDictionary<string, string> options)
|
||||
public async Task<IDictionary<string, string>> Execute(IDictionary<string, string> options, CancellationToken cancellationToken)
|
||||
{
|
||||
options.TryGetValue(KEY_OPERATION, out var operationstring);
|
||||
options.TryGetValue(KEY_USERNAME, out var username);
|
||||
@@ -98,12 +98,12 @@ namespace Duplicati.Library.Backend
|
||||
ValidateArgument(username, KEY_USERNAME);
|
||||
ValidateArgument(password, KEY_PASSWORD);
|
||||
ValidateArgument(path, KEY_PATH);
|
||||
return CreateUnprivilegedUser(username!, password!, path!);
|
||||
return await CreateUnprivilegedUser(username!, password!, path!, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
default:
|
||||
ValidateArgument(username, KEY_USERNAME);
|
||||
ValidateArgument(password, KEY_PASSWORD);
|
||||
return CanCreateUser(username!, password!);
|
||||
return await CanCreateUser(username!, password!, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ namespace Duplicati.Library.Backend
|
||||
}
|
||||
|
||||
|
||||
private static bool DetermineIfCreateUserIsAllowed(User user, AmazonIdentityManagementServiceClient cl)
|
||||
private static async Task<bool> DetermineIfCreateUserIsAllowed(User user, AmazonIdentityManagementServiceClient cl, CancellationToken cancellationToken)
|
||||
{
|
||||
var simulatePrincipalPolicy = new SimulatePrincipalPolicyRequest
|
||||
{
|
||||
@@ -146,13 +146,12 @@ namespace Duplicati.Library.Backend
|
||||
ActionNames = new[] { "iam:CreateUser" }.ToList()
|
||||
};
|
||||
|
||||
return cl.SimulatePrincipalPolicyAsync(simulatePrincipalPolicy)
|
||||
.GetAwaiter().GetResult()
|
||||
.EvaluationResults.First()
|
||||
.EvalDecision == PolicyEvaluationDecisionType.Allowed;
|
||||
return (await cl.SimulatePrincipalPolicyAsync(simulatePrincipalPolicy, cancellationToken).ConfigureAwait(false))
|
||||
.EvaluationResults.First()
|
||||
.EvalDecision == PolicyEvaluationDecisionType.Allowed;
|
||||
}
|
||||
|
||||
private static IDictionary<string, string> GetCreateUserDict(User user, AmazonIdentityManagementServiceClient cl)
|
||||
private static async Task<IDictionary<string, string>> GetCreateUserDict(User user, AmazonIdentityManagementServiceClient cl, CancellationToken cancellationToken)
|
||||
{
|
||||
var resultDict = new Dictionary<string, string>
|
||||
{
|
||||
@@ -164,7 +163,7 @@ namespace Duplicati.Library.Backend
|
||||
|
||||
try
|
||||
{
|
||||
resultDict["isroot"] = DetermineIfCreateUserIsAllowed(user, cl).ToString();
|
||||
resultDict["isroot"] = (await DetermineIfCreateUserIsAllowed(user, cl, cancellationToken)).ToString();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -180,13 +179,13 @@ namespace Duplicati.Library.Backend
|
||||
return resultDict;
|
||||
}
|
||||
|
||||
private static IDictionary<string, string> CanCreateUser(string awsid, string awskey)
|
||||
private static async Task<IDictionary<string, string>> CanCreateUser(string awsid, string awskey, CancellationToken cancellationToken)
|
||||
{
|
||||
var cl = new AmazonIdentityManagementServiceClient(awsid, awskey);
|
||||
User user;
|
||||
try
|
||||
{
|
||||
user = cl.GetUserAsync().Await().User;
|
||||
user = (await cl.GetUserAsync(cancellationToken).ConfigureAwait(false)).User;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -198,10 +197,10 @@ namespace Duplicati.Library.Backend
|
||||
};
|
||||
}
|
||||
|
||||
return GetCreateUserDict(user, cl);
|
||||
return await GetCreateUserDict(user, cl, cancellationToken);
|
||||
}
|
||||
|
||||
private static IDictionary<string, string> CreateUnprivilegedUser(string awsid, string awskey, string path)
|
||||
private static async Task<IDictionary<string, string>> CreateUnprivilegedUser(string awsid, string awskey, string path, CancellationToken cancellationToken)
|
||||
{
|
||||
var now = Utility.Utility.SerializeDateTime(DateTime.Now);
|
||||
var username = string.Format("duplicati-autocreated-backup-user-{0}", now);
|
||||
@@ -209,13 +208,13 @@ namespace Duplicati.Library.Backend
|
||||
var policydoc = GeneratePolicyDoc(path);
|
||||
|
||||
var cl = new AmazonIdentityManagementServiceClient(awsid, awskey);
|
||||
var user = cl.CreateUserAsync(new CreateUserRequest(username)).GetAwaiter().GetResult().User;
|
||||
cl.PutUserPolicyAsync(new PutUserPolicyRequest(
|
||||
var user = (await cl.CreateUserAsync(new CreateUserRequest(username), cancellationToken).ConfigureAwait(false)).User;
|
||||
await cl.PutUserPolicyAsync(new PutUserPolicyRequest(
|
||||
user.UserName,
|
||||
policyname,
|
||||
policydoc
|
||||
)).GetAwaiter().GetResult();
|
||||
var key = cl.CreateAccessKeyAsync(new CreateAccessKeyRequest { UserName = user.UserName }).GetAwaiter().GetResult().AccessKey;
|
||||
)).ConfigureAwait(false);
|
||||
var key = (await cl.CreateAccessKeyAsync(new CreateAccessKeyRequest { UserName = user.UserName }, cancellationToken).ConfigureAwait(false)).AccessKey;
|
||||
|
||||
return new Dictionary<string, string>
|
||||
{
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace Duplicati.Library.Backend
|
||||
}
|
||||
|
||||
#region IWebModule implementation
|
||||
public IDictionary<string, string> Execute(IDictionary<string, string> options)
|
||||
public Task<IDictionary<string, string>> Execute(IDictionary<string, string> options, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!options.TryGetValue(KEY_TYPE_NAME, out var keytype))
|
||||
keytype = DEFAULT_KEYTYPE;
|
||||
@@ -174,7 +174,7 @@ namespace Duplicati.Library.Backend
|
||||
key.Modulus ?? []
|
||||
};
|
||||
|
||||
return OutputKey(EncodeDER(privateEntries), EncodePEM(publicEntries), KEY_TEMPLATE_RSA, PUB_KEY_FORMAT_RSA, username);
|
||||
return Task.FromResult(OutputKey(EncodeDER(privateEntries), EncodePEM(publicEntries), KEY_TEMPLATE_RSA, PUB_KEY_FORMAT_RSA, username));
|
||||
}
|
||||
else if (KEYTYPE_DSA.Equals(keytype, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -195,7 +195,7 @@ namespace Duplicati.Library.Backend
|
||||
key.Y ?? []
|
||||
};
|
||||
|
||||
return OutputKey(EncodeDER(privateEntries), EncodePEM(publicEntries), KEY_TEMPLATE_DSA, PUB_KEY_FORMAT_DSA, username);
|
||||
return Task.FromResult(OutputKey(EncodeDER(privateEntries), EncodePEM(publicEntries), KEY_TEMPLATE_DSA, PUB_KEY_FORMAT_DSA, username));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Duplicati.Library.Backend
|
||||
|
||||
#region IWebModule implementation
|
||||
|
||||
public IDictionary<string, string> Execute(IDictionary<string, string> options)
|
||||
public async Task<IDictionary<string, string>> Execute(IDictionary<string, string> options, CancellationToken cancellationToken)
|
||||
{
|
||||
var res = new Dictionary<string, string>();
|
||||
|
||||
@@ -65,20 +65,20 @@ namespace Duplicati.Library.Backend
|
||||
|
||||
using (var connection = new SSHv2(url, (Dictionary<string, string?>)options))
|
||||
{
|
||||
var client = connection.CreateConnection(CancellationToken.None).Await();
|
||||
var client = await connection.CreateConnection(cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
client.ChangeDirectory(SSH_FOLDER);
|
||||
await client.ChangeDirectoryAsync(SSH_FOLDER, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
client.CreateDirectory(SSH_FOLDER);
|
||||
await client.CreateDirectoryAsync(SSH_FOLDER, cancellationToken).ConfigureAwait(false);
|
||||
client.ChangePermissions(SSH_FOLDER, SSH_FOLDER_PERMISSIONS);
|
||||
client.ChangeDirectory(SSH_FOLDER);
|
||||
await client.ChangeDirectoryAsync(SSH_FOLDER, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var sshfolder = client.ListDirectory(".").First(x => x.Name == ".");
|
||||
client.ChangeDirectory("..");
|
||||
var sshfolder = (await client.ListDirectoryAsync(".", cancellationToken).ToListAsync(cancellationToken)).First(x => x.Name == ".");
|
||||
await client.ChangeDirectoryAsync("..", cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!sshfolder.OwnerCanRead || !sshfolder.OwnerCanWrite)
|
||||
client.ChangePermissions(SSH_FOLDER, SSH_FOLDER_PERMISSIONS);
|
||||
@@ -86,12 +86,12 @@ namespace Duplicati.Library.Backend
|
||||
var authorized_keys = "";
|
||||
byte[]? authorized_keys_bytes = null;
|
||||
|
||||
var existing_authorized_keys = client.ListDirectory(SSH_FOLDER).Any(x => x.Name == AUTHORIZED_KEYS_FILE);
|
||||
var existing_authorized_keys = (await client.ListDirectoryAsync(SSH_FOLDER, cancellationToken).ToListAsync(cancellationToken)).Any(x => x.Name == AUTHORIZED_KEYS_FILE);
|
||||
if (existing_authorized_keys)
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
client.DownloadFile(AUTHORIZED_KEYS_PATH, ms);
|
||||
await client.DownloadFileAsync(AUTHORIZED_KEYS_PATH, ms, cancellationToken).ConfigureAwait(false);
|
||||
authorized_keys_bytes = ms.ToArray();
|
||||
authorized_keys = System.Text.Encoding.ASCII.GetString(authorized_keys_bytes);
|
||||
}
|
||||
@@ -120,12 +120,12 @@ namespace Duplicati.Library.Backend
|
||||
{
|
||||
var filename = AUTHORIZED_KEYS_PATH + ".backup-" + Utility.Utility.SerializeDateTime(DateTime.UtcNow);
|
||||
using (var ms = new MemoryStream(authorized_keys_bytes))
|
||||
client.UploadFile(ms, filename);
|
||||
await client.UploadFileAsync(ms, filename, cancellationToken).ConfigureAwait(false);
|
||||
client.ChangePermissions(filename, AUTHORIZED_KEYS_BACKUP_PERMISSIONS);
|
||||
}
|
||||
|
||||
using (var ms = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(new_file)))
|
||||
client.UploadFile(ms, AUTHORIZED_KEYS_PATH);
|
||||
await client.UploadFileAsync(ms, AUTHORIZED_KEYS_PATH, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!existing_authorized_keys)
|
||||
client.ChangePermissions(AUTHORIZED_KEYS_PATH, AUTHORIZED_KEYS_PERMISSIONS);
|
||||
|
||||
@@ -48,11 +48,11 @@ namespace Duplicati.Library.Backend.Storj
|
||||
new CommandLineArgument(KEY_CONFIGTYPE, CommandLineArgument.ArgumentType.Enumeration, LC.L("The config to get"), LC.L("Provide different config values"), DEFAULT_CONFIG_TYPE_STR, Enum.GetNames(typeof(ConfigType)))
|
||||
];
|
||||
|
||||
public IDictionary<string, string?> Execute(IDictionary<string, string?> options)
|
||||
public Task<IDictionary<string, string?>> Execute(IDictionary<string, string?> options, CancellationToken cancellationToken)
|
||||
{
|
||||
var ct = Utility.Utility.ParseEnumOption(options.AsReadOnly(), KEY_CONFIGTYPE, DEFAULT_CONFIG_TYPE);
|
||||
GetLookups().TryGetValue(ct.ToString(), out var dict);
|
||||
return dict ?? new Dictionary<string, string?>();
|
||||
return Task.FromResult(dict ?? new Dictionary<string, string?>());
|
||||
}
|
||||
|
||||
public IDictionary<string, IDictionary<string, string?>> GetLookups()
|
||||
|
||||
@@ -20,32 +20,20 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Duplicati.Library.Interface
|
||||
{
|
||||
public interface IWebModule : IDynamicModule
|
||||
public interface IWebModule : ICommonModule
|
||||
{
|
||||
/// <summary>
|
||||
/// The module key, used to activate or deactivate the module on the commandline
|
||||
/// </summary>
|
||||
string Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A localized string describing the module with a friendly name
|
||||
/// </summary>
|
||||
string DisplayName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A localized description of the module
|
||||
/// </summary>
|
||||
string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Execute the specified command with the given options.
|
||||
/// </summary>
|
||||
/// <param name="options">The options to use</param>
|
||||
/// <param name="cancellationToken">The cancellation token</param>
|
||||
/// <returns>A list of output values</returns>
|
||||
IDictionary<string, string> Execute(IDictionary<string, string> options);
|
||||
Task<IDictionary<string, string>> Execute(IDictionary<string, string> options, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Returns lookup data from the module, if any.
|
||||
|
||||
@@ -63,7 +63,7 @@ public record WebModules : IEndpointV1
|
||||
|
||||
return new Dto.WebModuleOutputDto(
|
||||
Status: "OK",
|
||||
Result: m.Execute(options)
|
||||
Result: await m.Execute(options, cancellationToken).ConfigureAwait(false)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user