re-acquire token in OneDrive2FileStorage after expiry, closes https://github.com/PhilippC/keepass2android/issues/983
This commit is contained in:
@@ -294,19 +294,37 @@ namespace keepass2android.Io
|
||||
get { yield return ProtocolId; }
|
||||
}
|
||||
|
||||
Dictionary<String /*userid*/, IGraphServiceClient> mClientByUser =
|
||||
new Dictionary<String /*userid*/, IGraphServiceClient>();
|
||||
class GraphServiceClientWithState
|
||||
{
|
||||
public IGraphServiceClient Client { get; set; }
|
||||
public DateTime TokenExpiryDate { get; set; }
|
||||
public bool RequiresUserInteraction { get; set; }
|
||||
}
|
||||
|
||||
private IGraphServiceClient tryGetMsGraphClient(String path)
|
||||
readonly Dictionary<String /*userid*/, GraphServiceClientWithState> mClientByUser =
|
||||
new Dictionary<String /*userid*/, GraphServiceClientWithState>();
|
||||
|
||||
private async Task<IGraphServiceClient> TryGetMsGraphClient(String path, bool tryConnect)
|
||||
{
|
||||
String userId = OneDrive2ItemLocation<OneDrive2PrefixContainerType>.FromString(path).User.Id;
|
||||
if (mClientByUser.ContainsKey(userId))
|
||||
return mClientByUser[userId];
|
||||
{
|
||||
GraphServiceClientWithState clientWithState = mClientByUser[userId];
|
||||
if (!(clientWithState.RequiresUserInteraction || (clientWithState.TokenExpiryDate < DateTime.Now) || (clientWithState.Client == null)))
|
||||
return clientWithState.Client;
|
||||
}
|
||||
if (tryConnect)
|
||||
{
|
||||
if (await TryLoginSilent(path) != null)
|
||||
{
|
||||
return mClientByUser[userId].Client;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private IGraphServiceClient buildClient(AuthenticationResult authenticationResult)
|
||||
private IGraphServiceClient BuildClient(AuthenticationResult authenticationResult)
|
||||
{
|
||||
|
||||
logDebug("buildClient...");
|
||||
@@ -321,14 +339,20 @@ namespace keepass2android.Io
|
||||
return Task.FromResult(0);
|
||||
});
|
||||
|
||||
GraphServiceClient graphClient = new GraphServiceClient(authenticationProvider);
|
||||
GraphServiceClientWithState clientWithState = new GraphServiceClientWithState()
|
||||
{
|
||||
Client = new GraphServiceClient(authenticationProvider),
|
||||
RequiresUserInteraction = false,
|
||||
TokenExpiryDate = authenticationResult.ExpiresOn.LocalDateTime
|
||||
};
|
||||
|
||||
|
||||
|
||||
if (authenticationResult.Account == null)
|
||||
throw new Exception("authenticationResult.Account == null!");
|
||||
mClientByUser[authenticationResult.Account.HomeAccountId.Identifier] = graphClient;
|
||||
mClientByUser[authenticationResult.Account.HomeAccountId.Identifier] = clientWithState;
|
||||
|
||||
return graphClient;
|
||||
return clientWithState.Client;
|
||||
}
|
||||
|
||||
|
||||
@@ -341,7 +365,7 @@ namespace keepass2android.Io
|
||||
|
||||
protected abstract string SpecialFolder { get; }
|
||||
|
||||
private PathItemBuilder GetPathItemBuilder(String path)
|
||||
private async Task<PathItemBuilder> GetPathItemBuilder(String path)
|
||||
{
|
||||
PathItemBuilder result = new PathItemBuilder(SpecialFolder);
|
||||
|
||||
@@ -351,12 +375,13 @@ namespace keepass2android.Io
|
||||
{
|
||||
throw new Exception("path does not contain user");
|
||||
}
|
||||
result.client = null;
|
||||
if (!mClientByUser.TryGetValue(result.itemLocation.User.Id, out result.client))
|
||||
{
|
||||
throw new Exception("failed to get client for " + result.itemLocation.User.Id);
|
||||
}
|
||||
|
||||
result.client = await TryGetMsGraphClient(path, true);
|
||||
|
||||
if (result.client == null)
|
||||
throw new Exception("Failed to connect or authenticate to OneDrive!");
|
||||
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
@@ -400,10 +425,14 @@ namespace keepass2android.Io
|
||||
{
|
||||
try
|
||||
{
|
||||
PathItemBuilder pathItemBuilder = GetPathItemBuilder(ioc.Path);
|
||||
Task.Run(async () => await pathItemBuilder.getPathItem()
|
||||
.Request()
|
||||
.DeleteAsync()).Wait();
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(ioc.Path);
|
||||
await pathItemBuilder.getPathItem()
|
||||
.Request()
|
||||
.DeleteAsync();
|
||||
}).Wait();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -426,13 +455,17 @@ namespace keepass2android.Io
|
||||
try
|
||||
{
|
||||
string path = ioc.Path;
|
||||
PathItemBuilder clientAndpath = GetPathItemBuilder(path);
|
||||
|
||||
logDebug("openFileForRead. Path=" + path);
|
||||
Stream result = Task.Run(async () => await clientAndpath
|
||||
.getPathItem()
|
||||
.Content
|
||||
.Request()
|
||||
.GetAsync()).Result;
|
||||
Stream result = Task.Run(async () =>
|
||||
{
|
||||
PathItemBuilder clientAndpath = await GetPathItemBuilder(path);
|
||||
return await clientAndpath
|
||||
.getPathItem()
|
||||
.Content
|
||||
.Request()
|
||||
.GetAsync();
|
||||
}).Result;
|
||||
logDebug("ok");
|
||||
return result;
|
||||
|
||||
@@ -479,14 +512,16 @@ namespace keepass2android.Io
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
PathItemBuilder pathItemBuilder = GetPathItemBuilder(path);
|
||||
Task.Run(async () => await
|
||||
pathItemBuilder
|
||||
.getPathItem()
|
||||
.Content
|
||||
.Request()
|
||||
.PutAsync<DriveItem>(stream)).Wait();
|
||||
Task.Run(async () =>
|
||||
{
|
||||
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(path);
|
||||
return await
|
||||
pathItemBuilder
|
||||
.getPathItem()
|
||||
.Content
|
||||
.Request()
|
||||
.PutAsync<DriveItem>(stream);
|
||||
}).Wait();
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -530,15 +565,16 @@ namespace keepass2android.Io
|
||||
driveItem.Name = newDirName;
|
||||
driveItem.Folder = new Folder();
|
||||
|
||||
PathItemBuilder pathItemBuilder = GetPathItemBuilder(parentIoc.Path);
|
||||
DriveItem res = Task.Run(async () =>
|
||||
{
|
||||
|
||||
|
||||
logDebug("building request for " + pathItemBuilder.itemLocation);
|
||||
|
||||
DriveItem res = Task.Run(async () => await pathItemBuilder.getPathItem()
|
||||
.Children
|
||||
.Request()
|
||||
.AddAsync(driveItem)).Result;
|
||||
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(parentIoc.Path);
|
||||
|
||||
return await pathItemBuilder.getPathItem()
|
||||
.Children
|
||||
.Request()
|
||||
.AddAsync(driveItem);
|
||||
}).Result;
|
||||
|
||||
|
||||
}
|
||||
@@ -552,43 +588,8 @@ namespace keepass2android.Io
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
PathItemBuilder pathItemBuilder = GetPathItemBuilder(ioc.Path);
|
||||
|
||||
logDebug("listing files for " + ioc.Path);
|
||||
if (!pathItemBuilder.hasShare() && !pathItemBuilder.hasOneDrivePath())
|
||||
{
|
||||
logDebug("listing shares.");
|
||||
return ListShares(pathItemBuilder.itemLocation, pathItemBuilder.client);
|
||||
}
|
||||
|
||||
logDebug("listing regular children.");
|
||||
List<FileDescription> result = new List<FileDescription>();
|
||||
/*logDebug("parent before:" + parentPath);
|
||||
parentPath = parentPath.substring(getProtocolPrefix().length());
|
||||
logDebug("parent after: " + parentPath);*/
|
||||
|
||||
IDriveItemChildrenCollectionPage itemsPage = Task.Run(async () => await pathItemBuilder.getPathItem()
|
||||
.Children
|
||||
.Request()
|
||||
.GetAsync()).Result;
|
||||
while (true)
|
||||
{
|
||||
IList<DriveItem> items = itemsPage.CurrentPage;
|
||||
if (!items.Any())
|
||||
return result;
|
||||
|
||||
foreach (DriveItem i in items)
|
||||
{
|
||||
var e = GetFileDescription(pathItemBuilder.itemLocation.BuildLocalChildLocation(i.Name, i.Id, i.ParentReference?.DriveId), i);
|
||||
result.Add(e);
|
||||
}
|
||||
var nextPageReqBuilder = itemsPage.NextPageRequest;
|
||||
if (nextPageReqBuilder == null)
|
||||
return result;
|
||||
itemsPage = Task.Run(async () => await nextPageReqBuilder.GetAsync()).Result;
|
||||
|
||||
}
|
||||
return Task.Run(async () => await ListContentsAsync(ioc)).Result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -596,6 +597,46 @@ namespace keepass2android.Io
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<FileDescription>> ListContentsAsync(IOConnectionInfo ioc)
|
||||
{
|
||||
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(ioc.Path);
|
||||
|
||||
logDebug("listing files for " + ioc.Path);
|
||||
if (!pathItemBuilder.hasShare() && !pathItemBuilder.hasOneDrivePath())
|
||||
{
|
||||
logDebug("listing shares.");
|
||||
return await ListShares(pathItemBuilder.itemLocation, pathItemBuilder.client);
|
||||
}
|
||||
|
||||
logDebug("listing regular children.");
|
||||
List<FileDescription> result = new List<FileDescription>();
|
||||
/*logDebug("parent before:" + parentPath);
|
||||
parentPath = parentPath.substring(getProtocolPrefix().length());
|
||||
logDebug("parent after: " + parentPath);*/
|
||||
|
||||
IDriveItemChildrenCollectionPage itemsPage = await pathItemBuilder.getPathItem()
|
||||
.Children
|
||||
.Request()
|
||||
.GetAsync();
|
||||
while (true)
|
||||
{
|
||||
IList<DriveItem> items = itemsPage.CurrentPage;
|
||||
if (!items.Any())
|
||||
return result;
|
||||
|
||||
foreach (DriveItem i in items)
|
||||
{
|
||||
var e = GetFileDescription(pathItemBuilder.itemLocation.BuildLocalChildLocation(i.Name, i.Id, i.ParentReference?.DriveId), i);
|
||||
result.Add(e);
|
||||
}
|
||||
var nextPageReqBuilder = itemsPage.NextPageRequest;
|
||||
if (nextPageReqBuilder == null)
|
||||
return result;
|
||||
itemsPage = Task.Run(async () => await nextPageReqBuilder.GetAsync()).Result;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private FileDescription GetFileDescription(OneDrive2ItemLocation<OneDrive2PrefixContainerType> path, DriveItem i)
|
||||
{
|
||||
@@ -620,24 +661,7 @@ namespace keepass2android.Io
|
||||
{
|
||||
try
|
||||
{
|
||||
string filename = ioc.Path;
|
||||
PathItemBuilder pathItemBuilder = GetPathItemBuilder(filename);
|
||||
|
||||
if (!pathItemBuilder.itemLocation.LocalPath.Any()
|
||||
&& !pathItemBuilder.hasShare())
|
||||
{
|
||||
FileDescription rootEntry = new FileDescription();
|
||||
rootEntry.CanRead = rootEntry.CanWrite = true;
|
||||
rootEntry.Path = filename;
|
||||
rootEntry.DisplayName = pathItemBuilder.itemLocation.User.Name;
|
||||
rootEntry.IsDirectory = true;
|
||||
return rootEntry;
|
||||
}
|
||||
|
||||
IDriveItemRequestBuilder pathItem = pathItemBuilder.getPathItem();
|
||||
|
||||
DriveItem item = Task.Run(async () => await pathItem.Request().GetAsync()).Result;
|
||||
return GetFileDescription(pathItemBuilder.itemLocation, item);
|
||||
return Task.Run(async() => await GetFileDescriptionAsync(ioc)).Result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -645,6 +669,28 @@ namespace keepass2android.Io
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<FileDescription> GetFileDescriptionAsync(IOConnectionInfo ioc)
|
||||
{
|
||||
string filename = ioc.Path;
|
||||
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(filename);
|
||||
|
||||
if (!pathItemBuilder.itemLocation.LocalPath.Any()
|
||||
&& !pathItemBuilder.hasShare())
|
||||
{
|
||||
FileDescription rootEntry = new FileDescription();
|
||||
rootEntry.CanRead = rootEntry.CanWrite = true;
|
||||
rootEntry.Path = filename;
|
||||
rootEntry.DisplayName = pathItemBuilder.itemLocation.User.Name;
|
||||
rootEntry.IsDirectory = true;
|
||||
return rootEntry;
|
||||
}
|
||||
|
||||
IDriveItemRequestBuilder pathItem = pathItemBuilder.getPathItem();
|
||||
|
||||
DriveItem item = await pathItem.Request().GetAsync();
|
||||
return GetFileDescription(pathItemBuilder.itemLocation, item);
|
||||
}
|
||||
|
||||
public bool RequiresSetup(IOConnectionInfo ioConnection)
|
||||
{
|
||||
return false;
|
||||
@@ -663,13 +709,13 @@ namespace keepass2android.Io
|
||||
}
|
||||
|
||||
|
||||
private bool isConnected(String path)
|
||||
private async Task<bool> IsConnectedAsync(string path, bool tryConnect)
|
||||
{
|
||||
try
|
||||
{
|
||||
logDebug("isConnected? " + path);
|
||||
|
||||
return tryGetMsGraphClient(path) != null;
|
||||
return (await TryGetMsGraphClient(path, tryConnect)) != null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -679,11 +725,15 @@ namespace keepass2android.Io
|
||||
|
||||
}
|
||||
|
||||
public bool IsConnected(string path)
|
||||
{
|
||||
return Task.Run(async () => await IsConnectedAsync(path, false)).Result;
|
||||
}
|
||||
|
||||
public void PrepareFileUsage(IFileStorageSetupInitiatorActivity activity, IOConnectionInfo ioc, int requestCode,
|
||||
bool alwaysReturnSuccess)
|
||||
{
|
||||
if (isConnected(ioc.Path))
|
||||
if (IsConnected(ioc.Path))
|
||||
{
|
||||
Intent intent = new Intent();
|
||||
intent.PutExtra(FileStorageSetupDefs.ExtraPath, ioc.Path);
|
||||
@@ -698,7 +748,7 @@ namespace keepass2android.Io
|
||||
|
||||
public void PrepareFileUsage(Context ctx, IOConnectionInfo ioc)
|
||||
{
|
||||
if (!isConnected(ioc.Path))
|
||||
if (!Task.Run(async() => await IsConnectedAsync(ioc.Path, true)).Result)
|
||||
{
|
||||
throw new Exception("MsGraph login required");
|
||||
}
|
||||
@@ -714,7 +764,7 @@ namespace keepass2android.Io
|
||||
|
||||
}
|
||||
|
||||
protected void finishActivityWithSuccess(
|
||||
protected void FinishActivityWithSuccess(
|
||||
IFileStorageSetupActivity setupActivity)
|
||||
{
|
||||
//Log.d("KP2AJ", "Success with authenticating!");
|
||||
@@ -751,19 +801,50 @@ namespace keepass2android.Io
|
||||
|
||||
if (activity.ProcessName.Equals(FileStorageSetupDefs.ProcessNameFileUsageSetup))
|
||||
activity.State.PutString(FileStorageSetupDefs.ExtraPath, activity.Ioc.Path);
|
||||
string rootPathForUser = await TryLoginSilent(activity.Ioc.Path);
|
||||
if (rootPathForUser != null)
|
||||
{
|
||||
FinishActivityWithSuccess(activity, rootPathForUser);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
logDebug("try interactive");
|
||||
AuthenticationResult res = await _publicClientApp.AcquireTokenInteractive(Scopes)
|
||||
.WithParentActivityOrWindow((Activity)activity)
|
||||
.ExecuteAsync();
|
||||
logDebug("ok interactive");
|
||||
BuildClient(res);
|
||||
FinishActivityWithSuccess(activity, BuildRootPathForUser(res));
|
||||
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logDebug("authenticating not successful: " + e);
|
||||
Intent data = new Intent();
|
||||
data.PutExtra(FileStorageSetupDefs.ExtraErrorMessage, "authenticating not successful");
|
||||
((Activity)activity).SetResult(Result.Canceled, data);
|
||||
((Activity)activity).Finish();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private async Task<string> TryLoginSilent(string iocPath)
|
||||
{
|
||||
|
||||
IAccount account = null;
|
||||
try
|
||||
{
|
||||
String userId = OneDrive2ItemLocation<OneDrive2PrefixContainerType>.FromString(activity.Ioc.Path).User?.Id;
|
||||
if (mClientByUser.ContainsKey(userId))
|
||||
|
||||
if (IsConnected(iocPath))
|
||||
{
|
||||
finishActivityWithSuccess(activity);
|
||||
return;
|
||||
return iocPath;
|
||||
}
|
||||
|
||||
String userId = OneDrive2ItemLocation<OneDrive2PrefixContainerType>.FromString(iocPath).User?.Id;
|
||||
logDebug("needs acquire token");
|
||||
logDebug("trying silent login " + activity.Ioc.Path);
|
||||
logDebug("trying silent login " + iocPath);
|
||||
|
||||
account = Task.Run(async () => await _publicClientApp.GetAccountAsync(userId)).Result;
|
||||
logDebug("getting user ok.");
|
||||
@@ -783,54 +864,46 @@ namespace keepass2android.Io
|
||||
.ExecuteAsync();
|
||||
|
||||
logDebug("AcquireTokenSilent ok.");
|
||||
var graphClient = buildClient(authResult);
|
||||
BuildClient(authResult);
|
||||
/*User me = await graphClient.Me.Request().WithForceRefresh(true).GetAsync();
|
||||
logDebug("received name " + me.DisplayName);*/
|
||||
|
||||
finishActivityWithSuccess(activity, authResult);
|
||||
return;
|
||||
return BuildRootPathForUser(authResult);
|
||||
|
||||
}
|
||||
catch (MsalUiRequiredException ex)
|
||||
{
|
||||
logDebug("ui required");
|
||||
|
||||
GraphServiceClientWithState clientWithState = new GraphServiceClientWithState()
|
||||
{
|
||||
Client = null,
|
||||
RequiresUserInteraction = true
|
||||
};
|
||||
|
||||
|
||||
mClientByUser[account.HomeAccountId.Identifier] = clientWithState;
|
||||
logDebug("ui required");
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logDebug("silent login failed: " + ex.ToString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
logDebug("try interactive");
|
||||
AuthenticationResult res = await _publicClientApp.AcquireTokenInteractive(Scopes)
|
||||
.WithParentActivityOrWindow((Activity)activity)
|
||||
.ExecuteAsync();
|
||||
logDebug("ok interactive");
|
||||
buildClient(res);
|
||||
finishActivityWithSuccess(activity, res);
|
||||
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logDebug("authenticating not successful: " + e);
|
||||
Intent data = new Intent();
|
||||
data.PutExtra(FileStorageSetupDefs.ExtraErrorMessage, "authenticating not successful");
|
||||
((Activity)activity).SetResult(Result.Canceled, data);
|
||||
((Activity)activity).Finish();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
string buildRootPathForUser(AuthenticationResult res)
|
||||
string BuildRootPathForUser(AuthenticationResult res)
|
||||
{
|
||||
return OneDrive2ItemLocation<OneDrive2PrefixContainerType>.RootForUser(res.Account.Username, res.Account.HomeAccountId.Identifier).ToString();
|
||||
}
|
||||
|
||||
|
||||
private void finishActivityWithSuccess(IFileStorageSetupActivity activity, AuthenticationResult authResult)
|
||||
private void FinishActivityWithSuccess(IFileStorageSetupActivity activity, string rootPathForUser)
|
||||
{
|
||||
activity.State.PutString(FileStorageSetupDefs.ExtraPath, buildRootPathForUser(authResult));
|
||||
finishActivityWithSuccess(activity);
|
||||
activity.State.PutString(FileStorageSetupDefs.ExtraPath, rootPathForUser);
|
||||
FinishActivityWithSuccess(activity);
|
||||
}
|
||||
|
||||
public void OnActivityResult(IFileStorageSetupActivity activity, int requestCode, int resultCode, Intent data)
|
||||
@@ -871,13 +944,13 @@ namespace keepass2android.Io
|
||||
}
|
||||
|
||||
|
||||
private List<FileDescription> ListShares(OneDrive2ItemLocation<OneDrive2PrefixContainerType> parentPath, IGraphServiceClient client)
|
||||
private async Task<List<FileDescription>> ListShares(OneDrive2ItemLocation<OneDrive2PrefixContainerType> parentPath, IGraphServiceClient client)
|
||||
{
|
||||
|
||||
List<FileDescription> result = new List<FileDescription>();
|
||||
|
||||
|
||||
DriveItem root = Task.Run(async () => await client.Me.Drive.Root.Request().GetAsync()).Result;
|
||||
DriveItem root = await client.Me.Drive.Root.Request().GetAsync();
|
||||
FileDescription myEntry = GetFileDescription(parentPath.BuildShare("me","me","me", root.ParentReference?.DriveId), root);
|
||||
myEntry.DisplayName = MyOneDriveDisplayName;
|
||||
|
||||
@@ -888,8 +961,7 @@ namespace keepass2android.Io
|
||||
|
||||
|
||||
|
||||
IDriveSharedWithMeCollectionPage sharedWithMeCollectionPage =
|
||||
Task.Run(async () => await client.Me.Drive.SharedWithMe().Request().GetAsync()).Result;
|
||||
IDriveSharedWithMeCollectionPage sharedWithMeCollectionPage = await client.Me.Drive.SharedWithMe().Request().GetAsync();
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -905,7 +977,7 @@ namespace keepass2android.Io
|
||||
}
|
||||
var b = sharedWithMeCollectionPage.NextPageRequest;
|
||||
if (b == null) break;
|
||||
sharedWithMeCollectionPage = Task.Run(async () => await b.GetAsync()).Result;
|
||||
sharedWithMeCollectionPage = await b.GetAsync();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -945,29 +1017,7 @@ namespace keepass2android.Io
|
||||
{
|
||||
try
|
||||
{
|
||||
DriveItem driveItem = new DriveItem();
|
||||
driveItem.Name = newFilename;
|
||||
driveItem.File = new File();
|
||||
PathItemBuilder pathItemBuilder = GetPathItemBuilder(parent);
|
||||
|
||||
//see if such a file exists already:
|
||||
var item = TryFindFile(pathItemBuilder, newFilename);
|
||||
if (item != null)
|
||||
{
|
||||
return pathItemBuilder.itemLocation.BuildLocalChildLocation(item.Name, item.Id, item.ParentReference?.DriveId).ToString();
|
||||
|
||||
}
|
||||
//doesn't exist. Create:
|
||||
logDebug("building request for " + pathItemBuilder.itemLocation);
|
||||
|
||||
DriveItem res = Task.Run(async () => await pathItemBuilder.getPathItem()
|
||||
.Children
|
||||
.Request()
|
||||
.AddAsync(driveItem)).Result;
|
||||
|
||||
return pathItemBuilder.itemLocation.BuildLocalChildLocation(res.Name, res.Id, res.ParentReference?.DriveId).ToString();
|
||||
|
||||
|
||||
return Task.Run(async() => await CreateFilePathAsync(parent, newFilename)).Result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -976,6 +1026,32 @@ namespace keepass2android.Io
|
||||
|
||||
}
|
||||
|
||||
private async Task<string> CreateFilePathAsync(string parent, string newFilename)
|
||||
{
|
||||
DriveItem driveItem = new DriveItem();
|
||||
driveItem.Name = newFilename;
|
||||
driveItem.File = new File();
|
||||
PathItemBuilder pathItemBuilder = await GetPathItemBuilder(parent);
|
||||
|
||||
//see if such a file exists already:
|
||||
var item = TryFindFile(pathItemBuilder, newFilename);
|
||||
if (item != null)
|
||||
{
|
||||
return pathItemBuilder.itemLocation.BuildLocalChildLocation(item.Name, item.Id, item.ParentReference?.DriveId)
|
||||
.ToString();
|
||||
}
|
||||
//doesn't exist. Create:
|
||||
logDebug("building request for " + pathItemBuilder.itemLocation);
|
||||
|
||||
DriveItem res = await pathItemBuilder.getPathItem()
|
||||
.Children
|
||||
.Request()
|
||||
.AddAsync(driveItem);
|
||||
|
||||
return pathItemBuilder.itemLocation.BuildLocalChildLocation(res.Name, res.Id, res.ParentReference?.DriveId)
|
||||
.ToString();
|
||||
}
|
||||
|
||||
public IOConnectionInfo GetParentPath(IOConnectionInfo ioc)
|
||||
{
|
||||
return IOConnectionInfo.FromPath(OneDrive2ItemLocation<OneDrive2PrefixContainerType>.FromString(ioc.Path).Parent.ToString());
|
||||
|
Reference in New Issue
Block a user