sparkles: Incorporate all XS code fixes

This commit is contained in:
Hylke Bons 2016-04-08 16:57:11 +01:00
parent dddf593ea8
commit 4617b2fdc8
17 changed files with 85 additions and 107 deletions

View file

@ -202,8 +202,8 @@ namespace SparkleShare {
string config_path = Path.Combine (app_data_path, "org.sparkleshare.SparkleShare");
Config = new Configuration (config_path, "config.xml");
Configuration.DefaultConfig = Config;
Config = new Configuration (config_path, "projects.xml");
Configuration.DefaultConfiguration = Config;
UserAuthenticationInfo = new SSHAuthenticationInfo ();
SSHAuthenticationInfo.DefaultAuthenticationInfo = UserAuthenticationInfo;
@ -449,7 +449,7 @@ namespace SparkleShare {
repo.NewChangeSet += delegate (ChangeSet change_set) {
if (AvatarsEnabled)
change_set.User.AvatarFilePath = Avatars.GetAvatar (change_set.User.Email, 48, Config.FullPath);
change_set.User.AvatarFilePath = Avatars.GetAvatar (change_set.User.Email, 48, Config.DirectoryPath);
NotificationRaised (change_set);
};

View file

@ -595,7 +595,7 @@ namespace SparkleShare {
if (!SparkleShare.Controller.AvatarsEnabled)
return "<!-- $pixmaps-path -->/user-icon-default.png";
string fetched_avatar = Avatars.GetAvatar (user.Email, 48, SparkleShare.Controller.Config.FullPath);
string fetched_avatar = Avatars.GetAvatar (user.Email, 48, SparkleShare.Controller.Config.DirectoryPath);
if (!string.IsNullOrEmpty (fetched_avatar))
return "file://" + fetched_avatar.Replace ("\\", "/");

View file

@ -40,7 +40,7 @@ namespace SparkleShare {
if (SparkleShare.Controller.AvatarsEnabled && !SparkleShare.Controller.FirstRun)
AvatarFilePath = Avatars.GetAvatar (SparkleShare.Controller.CurrentUser.Email,
48, SparkleShare.Controller.Config.FullPath);
48, SparkleShare.Controller.Config.DirectoryPath);
}

8
SparkleShare/Linux/Controller.cs Executable file → Normal file
View file

@ -34,11 +34,11 @@ namespace SparkleShare {
public override bool CreateSparkleShareFolder ()
{
if (Directory.Exists (Configuration.DefaultConfig.FoldersPath))
if (Directory.Exists (Configuration.DefaultConfiguration.FoldersPath))
return false;
Directory.CreateDirectory (Configuration.DefaultConfig.FoldersPath);
Syscall.chmod (Configuration.DefaultConfig.FoldersPath, (FilePermissions) 448); // 448 -> 700
Directory.CreateDirectory (Configuration.DefaultConfiguration.FoldersPath);
Syscall.chmod (Configuration.DefaultConfiguration.FoldersPath, (FilePermissions) 448); // 448 -> 700
return false;
}
@ -46,7 +46,7 @@ namespace SparkleShare {
public override void SetFolderIcon ()
{
var command = new Command ("gvfs-set-attribute", Configuration.DefaultConfig.FoldersPath + " " +
var command = new Command ("gvfs-set-attribute", Configuration.DefaultConfiguration.FoldersPath + " " +
"metadata::custom-icon-name org.sparkleshare.SparkleShare");
command.StartAndWaitForExit ();

View file

@ -67,6 +67,7 @@ namespace SparkleShare {
ShowAll ();
});
};
}

View file

@ -36,7 +36,6 @@ namespace SparkleShare {
NSTextField description_text_field;
public SetupWindow (IntPtr handle) : base (handle) { }
public SetupWindow ()
{

View file

@ -117,7 +117,7 @@ namespace SparkleShare {
this.folder_item.Image.Size = new SizeF (16, 16);
this.add_item = new NSMenuItem () {
Title = "Add Hosted Project…",
Title = "Sync Remote Project…",
Enabled = true
};
@ -127,7 +127,7 @@ namespace SparkleShare {
};
this.link_code_item = new NSMenuItem ();
this.link_code_item.Title = "Client ID";
this.link_code_item.Title = "Computer ID";
if (Controller.LinkCodeItemEnabled) {
this.link_code_submenu = new NSMenu ();

View file

@ -17,9 +17,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using System.Threading;
namespace Sparkles {
@ -58,7 +56,7 @@ namespace Sparkles {
public Uri RemoteUrl { get; protected set; }
public string RequiredFingerprint { get; protected set; }
public readonly bool FetchPriorHistory = false;
public readonly bool FetchPriorHistory;
public string TargetFolder { get; protected set; }
public bool IsActive { get; protected set; }
public string Identifier;
@ -66,13 +64,13 @@ namespace Sparkles {
public string [] Warnings {
get {
return this.warnings.ToArray ();
return warnings.ToArray ();
}
}
public string [] Errors {
get {
return this.errors.ToArray ();
return errors.ToArray ();
}
}
@ -106,10 +104,10 @@ namespace Sparkles {
};
private Thread thread;
Thread thread;
public BaseFetcher (SparkleFetcherInfo info)
protected BaseFetcher (SparkleFetcherInfo info)
{
OriginalFetcherInfo = info;
RequiredFingerprint = info.Fingerprint;
@ -117,10 +115,10 @@ namespace Sparkles {
string remote_path = info.RemotePath.Trim ("/".ToCharArray ());
string address = info.Address;
if (address.EndsWith ("/"))
if (address.EndsWith ("/", StringComparison.InvariantCulture))
address = address.Substring (0, address.Length - 1);
if (!remote_path.StartsWith ("/"))
if (!remote_path.StartsWith ("/", StringComparison.InvariantCulture))
remote_path = "/" + remote_path;
if (!address.Contains ("://"))
@ -145,12 +143,13 @@ namespace Sparkles {
Directory.Delete (TargetFolder, true);
} catch (IOException) {
this.errors.Add ("\"" + TargetFolder + "\" is read-only.");
errors.Add ("\"" + TargetFolder + "\" is read-only.");
Failed ();
return;
}
this.thread = new Thread (() => {
thread = new Thread (() => {
if (Fetch ()) {
Thread.Sleep (500);
Logger.LogInfo ("Fetcher", "Finished");
@ -175,7 +174,7 @@ namespace Sparkles {
}
});
this.thread.Start ();
thread.Start ();
}
@ -200,14 +199,15 @@ namespace Sparkles {
// Create an initial change set when the
// user has fetched an empty remote folder
private void CreateInitialChangeSet ()
void CreateInitialChangeSet ()
{
string n = Environment.NewLine;
string file_path = Path.Combine (TargetFolder, "SparkleShare.txt");
string n = Environment.NewLine;
UriBuilder uri_builder = new UriBuilder (RemoteUrl);
var uri_builder = new UriBuilder (RemoteUrl);
if (RemoteUrl.Scheme.Contains ("http")) {
// Don't expose possible username or password
if (RemoteUrl.Scheme.StartsWith ("http", StringComparison.InvariantCultureIgnoreCase)) {
uri_builder.UserName = "";
uri_builder.Password = "";
}
@ -215,7 +215,7 @@ namespace Sparkles {
string text = "Congratulations, you've successfully created a SparkleShare repository!" + n +
n +
"Any files you add or change in this folder will be automatically synced to " + n +
uri_builder.ToString () + " and everyone connected to it." + n +
uri_builder.Uri + " and everyone connected to it." + n +
n +
"SparkleShare is an Open Source software program that helps people collaborate and " + n +
"share files. If you like what we do, consider buying us a beer: http://www.sparkleshare.org/" + n +
@ -231,14 +231,14 @@ namespace Sparkles {
public static string CreateIdentifier ()
{
return Path.GetRandomFileName ().SHA1 ();
return Path.GetRandomFileName ().SHA256 ();
}
public void Dispose ()
{
if (this.thread != null)
this.thread.Abort ();
if (thread != null)
thread.Abort ();
}
@ -249,15 +249,14 @@ namespace Sparkles {
public static string GetBackend (string address)
{
if (address.StartsWith ("ssh+")) {
string backend = address.Substring (0, address.IndexOf ("://"));
backend = backend.Substring (4);
if (address.StartsWith ("ssh+", StringComparison.InvariantCultureIgnoreCase)) {
string backend = address.Substring (0, address.IndexOf ("://", StringComparison.InvariantCulture));
backend = backend.Substring (4);
return char.ToUpper (backend [0]) + backend.Substring (1);
} else {
return "Git";
}
return "Git";
}
}
}

View file

@ -77,13 +77,13 @@ namespace Sparkles {
public string FullPath {
get {
string custom_path = Configuration.DefaultConfig.GetFolderOptionalAttribute (Name, "path");
string custom_path = Configuration.DefaultConfiguration.GetFolderOptionalAttribute (Name, "path");
if (custom_path != null)
return Path.Combine (custom_path, Name);
return Path.Combine (Configuration.DefaultConfig.FoldersPath,
new Uri (Configuration.DefaultConfig.UrlByName (Name)).Host,
return Path.Combine (Configuration.DefaultConfiguration.FoldersPath,
new Uri (Configuration.DefaultConfiguration.UrlByName (Name)).Host,
Name);
}
}

View file

@ -95,6 +95,8 @@ namespace Sparkles {
string output = StandardError.ReadToEnd ();
WaitForExit ();
StartInfo.RedirectStandardError = false;
return output.TrimEnd ();
}

View file

@ -24,16 +24,6 @@ namespace Sparkles {
public static class Extensions {
public static string SHA1 (this string s)
{
SHA1 sha1 = new SHA1CryptoServiceProvider ();
byte [] bytes = ASCIIEncoding.Default.GetBytes (s);
byte [] sha1_bytes = sha1.ComputeHash (bytes);
return BitConverter.ToString (sha1_bytes).ToLower ().Replace ("-", "");
}
public static string SHA256 (this string s)
{
SHA256 sha256 = new SHA256CryptoServiceProvider ();
@ -69,15 +59,15 @@ namespace Sparkles {
public static string ToSize (this double byte_count)
{
if (byte_count >= 1099511627776)
return String.Format ("{0:##.##} ᴛʙ", Math.Round (byte_count / 1099511627776, 2));
return string.Format ("{0:##.##} ᴛʙ", Math.Round (byte_count / 1099511627776, 2));
else if (byte_count >= 1073741824)
return String.Format ("{0:##.##} ɢʙ", Math.Round (byte_count / 1073741824, 1));
return string.Format ("{0:##.##} ɢʙ", Math.Round (byte_count / 1073741824, 1));
else if (byte_count >= 1048576)
return String.Format ("{0:##.##} ᴍʙ", Math.Round (byte_count / 1048576, 1));
return string.Format ("{0:##.##} ᴍʙ", Math.Round (byte_count / 1048576, 1));
else if (byte_count >= 1024)
return String.Format ("{0:##.##} ᴋʙ", Math.Round (byte_count / 1024, 0));
return string.Format ("{0:##.##} ᴋʙ", Math.Round (byte_count / 1024, 0));
else
return byte_count.ToString () + " ʙ";
return byte_count + " ʙ";
}
@ -91,7 +81,7 @@ namespace Sparkles {
public static string ToPrettyDate (this DateTime timestamp)
{
TimeSpan time_diff = DateTime.Now.Subtract (timestamp);
int day_diff = (int) time_diff.TotalDays;
var day_diff = (int) time_diff.TotalDays;
DateTime yesterday = DateTime.Today.AddDays (-1);
if (timestamp >= yesterday && timestamp < DateTime.Today) {

View file

@ -75,11 +75,11 @@ namespace Sparkles.Git {
return false;
if (FetchPriorHistory) {
git_clone = new GitCommand (Configuration.DefaultConfig.TmpPath,
git_clone = new GitCommand (Configuration.DefaultConfiguration.TmpPath,
"clone --progress --no-checkout \"" + RemoteUrl + "\" \"" + TargetFolder + "\"", auth_info);
} else {
git_clone = new GitCommand (Configuration.DefaultConfig.TmpPath,
git_clone = new GitCommand (Configuration.DefaultConfiguration.TmpPath,
"clone --progress --no-checkout --depth=1 \"" + RemoteUrl + "\" \"" + TargetFolder + "\"", auth_info);
}

View file

@ -28,11 +28,11 @@ namespace Sparkles {
public static BaseListener CreateListener (string folder_name, string folder_identifier)
{
// Check if the user wants to use a global custom notification service
string uri = Configuration.DefaultConfig.GetConfigOption ("announcements_url");
string uri = Configuration.DefaultConfiguration.GetConfigOption ("announcements_url");
// Check if the user wants a use a custom notification service for this folder
if (string.IsNullOrEmpty (uri))
uri = Configuration.DefaultConfig.GetFolderOptionalAttribute (folder_name, "announcements_url");
uri = Configuration.DefaultConfiguration.GetFolderOptionalAttribute (folder_name, "announcements_url");
// This is SparkleShare's centralized notification service.
// It communicates "It's time to sync!" signals between clients.

View file

@ -50,11 +50,11 @@ namespace Sparkles {
lock (debug_lock) {
if (log_size >= 1000) {
File.WriteAllText (Configuration.DefaultConfig.LogFilePath, line + Environment.NewLine);
File.WriteAllText (Configuration.DefaultConfiguration.LogFilePath, line + Environment.NewLine);
log_size = 0;
} else {
File.AppendAllText (Configuration.DefaultConfig.LogFilePath, line + Environment.NewLine);
File.AppendAllText (Configuration.DefaultConfiguration.LogFilePath, line + Environment.NewLine);
log_size++;
}
}
@ -87,8 +87,8 @@ namespace Sparkles {
if (e.InnerException != null)
crash_report += n + e.InnerException.Message + n + e.InnerException.StackTrace + n;
if (Configuration.DefaultConfig != null && File.Exists (Configuration.DefaultConfig.LogFilePath)) {
string debug_log = File.ReadAllText (Configuration.DefaultConfig.LogFilePath);
if (Configuration.DefaultConfiguration != null && File.Exists (Configuration.DefaultConfiguration.LogFilePath)) {
string debug_log = File.ReadAllText (Configuration.DefaultConfiguration.LogFilePath);
string [] debug_lines = debug_log.Split (Environment.NewLine.ToCharArray ());
int line_count = 50;

View file

@ -72,7 +72,6 @@ namespace Sparkles {
}
// TODO: Gitlab preset
public static Preset Create (string name, string description, string address_value,
string address_example, string path_value, string path_example)
{

View file

@ -40,7 +40,7 @@ namespace Sparkles {
public SSHAuthenticationInfo ()
{
Path = IO.Path.Combine (IO.Path.GetDirectoryName (Configuration.DefaultConfig.FullPath), "ssh");
Path = IO.Path.Combine (Configuration.DefaultConfiguration.DirectoryPath, "ssh");
KnownHostsFilePath = IO.Path.Combine (Path, "known_hosts");
KnownHostsFilePath = MakeWindowsDomainAccountSafe (KnownHostsFilePath);
@ -60,7 +60,7 @@ namespace Sparkles {
bool key_found = false;
foreach (string file_path in IO.Directory.GetFiles (Path)) {
if (file_path.EndsWith (".key")) {
if (file_path.EndsWith (".key", StringComparison.InvariantCultureIgnoreCase)) {
PrivateKeyFilePath = file_path;
PublicKeyFilePath = file_path + ".pub";
@ -88,8 +88,11 @@ namespace Sparkles {
string key_file_name = DateTime.Now.ToString ("yyyy-MM-dd_HH\\hmm") + ".key";
string computer_name = Dns.GetHostName ();
if (computer_name.EndsWith (".local") || computer_name.EndsWith (".config"))
computer_name = computer_name.Substring (0, computer_name.LastIndexOf ("."));
if (computer_name.EndsWith (".local", StringComparison.InvariantCultureIgnoreCase) ||
computer_name.EndsWith (".config", StringComparison.InvariantCultureIgnoreCase))
computer_name = computer_name.Substring (0,
computer_name.LastIndexOf (".", StringComparison.InvariantCulture));
string arguments =
"-t rsa " + // Crypto type
@ -118,7 +121,7 @@ namespace Sparkles {
// Use forward slashes in paths when dealing with Windows domain accounts
string MakeWindowsDomainAccountSafe (string path)
{
if (path.StartsWith ("\\\\"))
if (path.StartsWith ("\\\\", StringComparison.InvariantCulture))
return path.Replace ("\\", "/");
return path;

View file

@ -16,7 +16,6 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
@ -24,7 +23,7 @@ namespace Sparkles {
public abstract class SSHFetcher : BaseFetcher {
public SSHFetcher (SparkleFetcherInfo info) : base (info)
protected SSHFetcher (SparkleFetcherInfo info) : base (info)
{
}
@ -34,19 +33,19 @@ namespace Sparkles {
// Tor has special domain names called ".onion addresses". They can only be
// resolved by using a proxy via tor. While the rest of the openssh suite
// fully supports proxying, ssh-keyscan does not, so we can't use it for .onion
if (RemoteUrl.Host.EndsWith (".onion")) {
if (RemoteUrl.Host.EndsWith (".onion", StringComparison.InvariantCultureIgnoreCase)) {
Logger.LogInfo ("Auth", "using tor .onion address skipping ssh-keyscan");
return true;
}
if (RemoteUrl.Scheme.StartsWith ("http"))
if (RemoteUrl.Scheme.StartsWith ("http", StringComparison.InvariantCultureIgnoreCase))
return true;
string host_key = FetchHostKey ();
if (string.IsNullOrEmpty (RemoteUrl.Host) || host_key == null) {
Logger.LogInfo ("Auth", "Could not fetch host key");
this.errors.Add ("error: Could not fetch host key");
errors.Add ("error: Could not fetch host key");
return false;
}
@ -63,14 +62,14 @@ namespace Sparkles {
// "Unapproved cryptographic algorithms" won't work when FIPS is enabled on Windows.
// Software like Cisco AnyConnect can demand this feature is on, so we show an error
Logger.LogInfo ("Auth", "Unable to derive fingerprint: ", e);
this.errors.Add ("error: Can't check fingerprint due to FIPS being enabled");
errors.Add ("error: Can't check fingerprint due to FIPS being enabled");
return false;
}
if (host_fingerprint == null || !RequiredFingerprint.Equals (host_fingerprint)) {
Logger.LogInfo ("Auth", "Fingerprint doesn't match");
this.errors.Add ("error: Host fingerprint doesn't match");
errors.Add ("error: Host fingerprint doesn't match");
return false;
}
@ -88,33 +87,23 @@ namespace Sparkles {
}
private string FetchHostKey ()
string FetchHostKey ()
{
Logger.LogInfo ("Auth", "Fetching host key for " + RemoteUrl.Host);
Process process = new Process ();
process.StartInfo.FileName = "ssh-keyscan";
process.StartInfo.WorkingDirectory = Configuration.DefaultConfig.TmpPath;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;
process.EnableRaisingEvents = true;
string [] key_types = {"rsa", "dsa", "ecdsa"};
foreach (string key_type in key_types) {
string args = "-t " + key_type + " " + "-p" + " ";
if (RemoteUrl.Port < 1)
process.StartInfo.Arguments = "-t " + key_type + " -p 22 " + RemoteUrl.Host;
args += "22 " + RemoteUrl.Host;
else
process.StartInfo.Arguments = "-t " + key_type + " -p " + RemoteUrl.Port + " " + RemoteUrl.Host;
Logger.LogInfo ("Cmd", process.StartInfo.FileName + " " + process.StartInfo.Arguments);
process.Start ();
string host_key = process.StandardOutput.ReadToEnd ().Trim ();
process.WaitForExit ();
if (process.ExitCode == 0 && !string.IsNullOrWhiteSpace (host_key))
args += RemoteUrl.Port + " " + RemoteUrl.Host;
var ssh_keyscan = new Command ("ssh-keyscan", args);
string host_key = ssh_keyscan.StartAndReadStandardOutput ();
if (ssh_keyscan.ExitCode == 0 && !string.IsNullOrWhiteSpace (host_key))
return host_key;
}
@ -122,7 +111,6 @@ namespace Sparkles {
}
string DeriveFingerprint (string public_key)
{
try {
@ -143,12 +131,9 @@ namespace Sparkles {
}
private void AcceptHostKey (string host_key, bool warn)
void AcceptHostKey (string host_key, bool warn)
{
// TODO: Make a proper member for this
string config_path = Path.GetDirectoryName (Configuration.DefaultConfig.FullPath);
string ssh_config_path = Path.Combine (config_path, "ssh");
string ssh_config_path = Path.Combine (Configuration.DefaultConfiguration.DirectoryPath, "ssh");
string known_hosts_file_path = Path.Combine (ssh_config_path, "known_hosts");
if (!File.Exists (known_hosts_file_path)) {
@ -163,11 +148,11 @@ namespace Sparkles {
string [] known_hosts_lines = File.ReadAllLines (known_hosts_file_path);
foreach (string line in known_hosts_lines) {
if (line.StartsWith (host + " "))
if (line.StartsWith (host + " ", StringComparison.InvariantCulture))
return;
}
if (known_hosts.EndsWith ("\n"))
if (known_hosts.EndsWith ("\n", StringComparison.InvariantCulture))
File.AppendAllText (known_hosts_file_path, host_key + "\n");
else
File.AppendAllText (known_hosts_file_path, "\n" + host_key + "\n");
@ -175,7 +160,7 @@ namespace Sparkles {
Logger.LogInfo ("Auth", "Accepted host key for " + host);
if (warn)
this.warnings.Add ("The following host key has been accepted:\n" + DeriveFingerprint (host_key));
warnings.Add ("The following host key has been accepted:\n" + DeriveFingerprint (host_key));
}
}
}