Support file based authorization (Issue: #524) (#525)

* support file based authorization
* remove generated files after authentication
This commit is contained in:
Norbert Preining 2019-06-11 16:12:36 +09:00 committed by abraunegg
parent e4ab9e7316
commit aa2e2245f0
3 changed files with 34 additions and 4 deletions

View file

@ -18,6 +18,11 @@ A complete tool to interact with OneDrive on Linux.
.SH OPTIONS .SH OPTIONS
Without any option given, no sync is done and the program exits. Without any option given, no sync is done and the program exits.
.TP .TP
\fB\-\-auth\-files\fP ARG
Perform authorization via two files passed in as \fBARG\fP in the format \fBauthUrl:responseUrl\fP.
The authorization URL is written to the \fBauthUrl\fP, then \fBonedrive\fP waits for
the file \fBresponseUrl\fP to be present, and reads the response from that file.
.TP
\fB\-\-check\-for\-nomount\fP \fB\-\-check\-for\-nomount\fP
Check for the presence of .nosync in the syncdir root. If found, do not perform sync. Check for the presence of .nosync in the syncdir root. If found, do not perform sync.
.br .br

View file

@ -151,6 +151,7 @@ final class Config
stringValues["remove_directory"] = ""; stringValues["remove_directory"] = "";
stringValues["single_directory"] = ""; stringValues["single_directory"] = "";
stringValues["source_directory"] = ""; stringValues["source_directory"] = "";
stringValues["auth_files"] = "";
boolValues["display_config"] = false; boolValues["display_config"] = false;
boolValues["display_sync_status"] = false; boolValues["display_sync_status"] = false;
boolValues["resync"] = false; boolValues["resync"] = false;
@ -169,6 +170,9 @@ final class Config
args, args,
std.getopt.config.bundling, std.getopt.config.bundling,
std.getopt.config.caseSensitive, std.getopt.config.caseSensitive,
"auth-files",
"Perform authentication not via interactive dialog but via files read/writes to these files.",
&stringValues["auth_files"],
"check-for-nomount", "check-for-nomount",
"Check for the presence of .nosync in the syncdir root. If found, do not perform sync.", "Check for the presence of .nosync in the syncdir root. If found, do not perform sync.",
&boolValues["check_nomount"], &boolValues["check_nomount"],

View file

@ -1,7 +1,8 @@
import std.net.curl; import std.net.curl;
import etc.c.curl: CurlOption; import etc.c.curl: CurlOption;
import std.datetime, std.exception, std.file, std.json, std.path; import std.datetime, std.exception, std.file, std.json, std.path;
import std.stdio, std.string, std.uni, std.uri; import std.stdio, std.string, std.uni, std.uri, std.file;
import std.array: split;
import core.stdc.stdlib; import core.stdc.stdlib;
import core.thread, std.conv, std.math; import core.thread, std.conv, std.math;
import progress; import progress;
@ -161,9 +162,29 @@ final class OneDriveApi
import std.stdio, std.regex; import std.stdio, std.regex;
char[] response; char[] response;
string url = authUrl ~ "?client_id=" ~ clientId ~ "&scope=files.readwrite%20files.readwrite.all%20offline_access&response_type=code&redirect_uri=" ~ redirectUrl; string url = authUrl ~ "?client_id=" ~ clientId ~ "&scope=files.readwrite%20files.readwrite.all%20offline_access&response_type=code&redirect_uri=" ~ redirectUrl;
log.log("Authorize this app visiting:\n"); string authFilesString = cfg.getValueString("auth_files");
write(url, "\n\n", "Enter the response uri: "); if (authFilesString == "") {
readln(response); log.log("Authorize this app visiting:\n");
write(url, "\n\n", "Enter the response uri: ");
readln(response);
} else {
string[] authFiles = authFilesString.split(":");
string authUrl = authFiles[0];
string responseUrl = authFiles[1];
auto authUrlFile = File(authUrl, "w");
authUrlFile.write(url);
authUrlFile.close();
while (!exists(responseUrl)) {
Thread.sleep(dur!("msecs")(100));
}
response = cast(char[]) read(responseUrl);
try {
std.file.remove(authUrl);
std.file.remove(responseUrl);
} catch (FileException e) {
log.error("Cannot remove files ", authUrl, " ", responseUrl);
}
}
// match the authorization code // match the authorization code
auto c = matchFirst(response, r"(?:[\?&]code=)([\w\d-]+)"); auto c = matchFirst(response, r"(?:[\?&]code=)([\w\d-]+)");
if (c.empty) { if (c.empty) {