-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.ComponentModel.Composition;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Forms;
-using Pithos.Client.WPF.Properties;
-using Pithos.Core;
-using MessageBox = System.Windows.MessageBox;
-using Screen = Caliburn.Micro.Screen;
-
-namespace Pithos.Client.WPF.Preferences
-{
- [Export(typeof(AddAccountViewModel))]
- public class AddAccountViewModel:Screen
- {
- private string _accountName;
- public string AccountName
- {
- get { return _accountName; }
- set
- {
- _accountName = value;
- NotifyOfPropertyChange(()=>AccountName);
- NotifyOfPropertyChange(() => HasCredentials);
- }
- }
-
- private string _token;
- public string Token
- {
- get { return _token; }
- set
- {
- _token = value;
- NotifyOfPropertyChange(()=>Token);
- NotifyOfPropertyChange(() => HasCredentials);
- }
- }
-
- private string _accountPath;
- public string AccountPath
- {
- get { return _accountPath; }
- set
- {
- _accountPath = value;
- NotifyOfPropertyChange(() => AccountPath);
- NotifyOfPropertyChange(() => HasAccountPath);
- }
- }
-
-
- public bool HasAccountPath
- {
- get { return !String.IsNullOrWhiteSpace(AccountPath); }
- }
-
- public bool HasCredentials
- {
- get { return !(String.IsNullOrWhiteSpace(AccountName) || String.IsNullOrWhiteSpace(Token) ) ; }
- }
-
-
- private bool _isConfirmed;
-
- public bool IsConfirmed
- {
- get { return _isConfirmed; }
- set
- {
- _isConfirmed = value;
- NotifyOfPropertyChange(() => IsConfirmed);
- }
- }
-
-
- private bool _isAccountActive;
-
- public bool IsAccountActive
- {
- get { return _isAccountActive; }
- set
- {
- _isAccountActive = value;
- NotifyOfPropertyChange(() => IsAccountActive);
- }
- }
-
- public void SelectAccount()
- {
- using (var dlg = new FolderBrowserDialog())
- {
- //Ask the user to select a folder
- //Note: We need a parent window here, which we retrieve with GetView
- var view = (Window)GetView();
- if (DialogResult.OK != dlg.ShowDialog(new Wpf32Window(view)))
- return;
-
- AccountPath= dlg.SelectedPath;
- }
- }
-
-
- private bool _isRetrieving;
- public bool IsRetrieving
- {
- get { return _isRetrieving; }
- set
- {
- _isRetrieving = value;
- NotifyOfPropertyChange(() => IsRetrieving);
- }
- }
-
- public async void RetrieveCredentials()
- {
- IsRetrieving = true;
- IsConfirmed = false;
-
- try
- {
- var credentials = await PithosAccount.RetrieveCredentialsAsync(Settings.Default.PithosLoginUrl);
- AccountName = credentials.UserName;
- Token = credentials.Password;
-
- IsConfirmed = true;
- }
- catch (Exception exc)
- {
- IsConfirmed = false;
- MessageBox.Show(exc.ToString(), "Error");
- throw;
- }
- IsRetrieving = false;
-
- }
-
-
- }
-}
+#region\r
+/* -----------------------------------------------------------------------\r
+ * <copyright file="AddAccountViewModel.cs" company="GRNet">\r
+ * \r
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer.\r
+ *\r
+ * 2. Redistributions in binary form must reproduce the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer in the documentation and/or other materials\r
+ * provided with the distribution.\r
+ *\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS\r
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\r
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\r
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * The views and conclusions contained in the software and\r
+ * documentation are those of the authors and should not be\r
+ * interpreted as representing official policies, either expressed\r
+ * or implied, of GRNET S.A.\r
+ * </copyright>\r
+ * -----------------------------------------------------------------------\r
+ */\r
+#endregion\r
+using System;\r
+using System.Collections.Generic;\r
+using System.ComponentModel.Composition;\r
+using System.IO;\r
+using System.Linq;\r
+using System.Text.RegularExpressions;\r
+using System.Threading.Tasks;\r
+using System.Windows;\r
+using System.Windows.Forms;\r
+using Pithos.Client.WPF.Properties;\r
+using Pithos.Interfaces;\r
+using Pithos.Network;\r
+using MessageBox = System.Windows.MessageBox;\r
+using Screen = Caliburn.Micro.Screen;\r
+\r
+namespace Pithos.Client.WPF.Preferences\r
+{\r
+ [Export(typeof(AddAccountViewModel))]\r
+ public class AddAccountViewModel:Screen\r
+ {\r
+\r
+ private readonly List<string> _servers;\r
+\r
+ public List<string> Servers\r
+ {\r
+ get { return Settings.Default.Servers.Select(server => server.ServerUri).ToList(); }\r
+ }\r
+\r
+ private bool _isValidServer;\r
+ public bool IsValidServer\r
+ {\r
+ get { return _isValidServer; }\r
+ set\r
+ {\r
+ _isValidServer = value;\r
+ NotifyOfPropertyChange(()=>IsValidServer);\r
+ }\r
+ }\r
+\r
+\r
+ private string _currentServer;\r
+ public string CurrentServer\r
+ {\r
+ get { return _currentServer; }\r
+ set\r
+ {\r
+ if (!Uri.IsWellFormedUriString(value, UriKind.Absolute))\r
+ {\r
+ IsValidServer = false;\r
+ throw new UriFormatException();\r
+ }\r
+ _currentServer = value;\r
+ IsValidServer = true;\r
+ HasValidCredentials = false;\r
+ IsConfirmed = false;\r
+ NotifyOfPropertyChange(()=>CurrentServer);\r
+ }\r
+ }\r
+\r
+ private string _accountName;\r
+ public string AccountName\r
+ {\r
+ get { return _accountName; }\r
+ set\r
+ {\r
+ _accountName = value;\r
+ NotifyOfPropertyChange(()=>AccountName);\r
+ NotifyOfPropertyChange(() => HasCredentials);\r
+ }\r
+ }\r
+\r
+ private string _token;\r
+ public string Token\r
+ {\r
+ get { return _token; }\r
+ set\r
+ {\r
+ _token = value;\r
+ NotifyOfPropertyChange(()=>Token);\r
+ NotifyOfPropertyChange(() => HasCredentials);\r
+ }\r
+ }\r
+\r
+ private string _accountPath;\r
+ public string AccountPath\r
+ {\r
+ get { return _accountPath; }\r
+ set\r
+ {\r
+ _accountPath = value;\r
+ NotifyOfPropertyChange(() => AccountPath);\r
+ NotifyOfPropertyChange(() => HasAccountPath);\r
+ }\r
+ }\r
+\r
+\r
+ public bool HasAccountPath\r
+ {\r
+ get { return !String.IsNullOrWhiteSpace(AccountPath); }\r
+ }\r
+\r
+ public bool HasCredentials\r
+ {\r
+ get { return !(String.IsNullOrWhiteSpace(AccountName) || String.IsNullOrWhiteSpace(Token) ) ; }\r
+ }\r
+\r
+\r
+ private bool _isConfirmed;\r
+\r
+ public bool IsConfirmed\r
+ {\r
+ get { return _isConfirmed; }\r
+ set\r
+ {\r
+ _isConfirmed = value;\r
+ HasValidCredentials = false;\r
+ NotifyOfPropertyChange(() => IsConfirmed);\r
+ }\r
+ }\r
+\r
+\r
+ private bool _isAccountActive;\r
+\r
+ public bool IsAccountActive\r
+ {\r
+ get { return _isAccountActive; }\r
+ set\r
+ {\r
+ _isAccountActive = value;\r
+ NotifyOfPropertyChange(() => IsAccountActive);\r
+ }\r
+ }\r
+\r
+\r
+ private bool _shouldCreateOkeanosFolder;\r
+ public bool ShouldCreateOkeanosFolder\r
+ {\r
+ get { return _shouldCreateOkeanosFolder; }\r
+ set\r
+ {\r
+ _shouldCreateOkeanosFolder = value;\r
+ NotifyOfPropertyChange(()=>ShouldCreateOkeanosFolder);\r
+ }\r
+ }\r
+\r
+ bool HasNoParentWithCache(DirectoryInfo info)\r
+ {\r
+ if (info == null)\r
+ return false;\r
+ var parent = info.Parent;\r
+ if (parent == null)\r
+ return true;\r
+ if (parent.EnumerateDirectories(FolderConstants.CacheFolder).Any())\r
+ {\r
+ return false;\r
+ }\r
+ return HasNoParentWithCache(parent);\r
+ }\r
+\r
+ string GetLowestAboveCache(string path)\r
+ {\r
+ if (String.IsNullOrWhiteSpace(path))\r
+ return null;\r
+ var info = new DirectoryInfo(path);\r
+ if (!info.Exists)\r
+ return path;\r
+ while (!HasNoParentWithCache(info))\r
+ {\r
+ info = info.Parent;\r
+ }\r
+ if (info == null)\r
+ return null;\r
+ else\r
+ return info.FullName;\r
+ }\r
+\r
+ public void SelectAccount()\r
+ {\r
+ using (var dlg = new FolderBrowserDialog{Description=Resources.AddAccountViewModel_SelectAccount_Please_select_a_folder})\r
+ {\r
+ //Ask the user to select a folder\r
+ //Note: We need a parent window here, which we retrieve with GetView \r
+ var view = (Window)GetView();\r
+ if (DialogResult.OK != dlg.ShowDialog(new Wpf32Window(view)))\r
+ return;\r
+\r
+ //If the selected path is under an account folder, ie a folder containint a .pithos.cache subfolder, try to locate\r
+ //the cache's parent folder\r
+ var selectedPath = GetLowestAboveCache(dlg.SelectedPath);\r
+\r
+ //If the path ends with /okeanos#/pithos, replace with /okeanos#\r
+ var match = _okeanosRegex.Match(selectedPath);\r
+ if (match.Success)\r
+ {\r
+ selectedPath = match.Groups[1].Value; \r
+ }\r
+\r
+ AccountPath= selectedPath;\r
+\r
+\r
+\r
+ ShouldCreateOkeanosFolder=Directory.EnumerateFileSystemEntries(AccountPath).Any(); \r
+ }\r
+ }\r
+\r
+\r
+ public void RetrieveCredentials()\r
+ {\r
+ SetBusy("Waiting for credentials.", "Please enter your credentials in the Pithos logon page");\r
+ IsConfirmed = false;\r
+\r
+ try\r
+ {\r
+ var loginUri=new Uri(CurrentServer).Combine("login");\r
+ var credentials = PithosAccount.RetrieveCredentials(loginUri.ToString());\r
+ if (credentials == null)\r
+ return;\r
+ AccountName = credentials.UserName;\r
+ Token = credentials.Password;\r
+\r
+ IsConfirmed = true;\r
+\r
+ }\r
+ catch (PithosException exc)\r
+ {\r
+ ClearBusy();\r
+ MessageBox.Show(exc.Message, "Unable to retrieve credentials");\r
+ }\r
+ catch (Exception exc)\r
+ {\r
+ IsConfirmed = false;\r
+ MessageBox.Show(exc.ToString(), "Error");\r
+ throw;\r
+ }\r
+ finally\r
+ {\r
+ ClearBusy();\r
+ \r
+ ((Window) GetView()).Activate();\r
+ }\r
+\r
+ if (IsConfirmed)\r
+ TaskEx.Run(()=>TestAccount());\r
+\r
+ }\r
+\r
+ public AddAccountViewModel()\r
+ {\r
+ _servers=new List<string>\r
+ {\r
+ Settings.Default.ProductionServer, \r
+ Settings.Default.DevelopmentServer\r
+ };\r
+ CurrentServer = _servers[0];\r
+ DisplayName = "Add Pithos+ Account";\r
+ }\r
+\r
+ private bool _hasValidCredentials;\r
+ public bool HasValidCredentials\r
+ {\r
+ get { return _hasValidCredentials; }\r
+ set\r
+ {\r
+ _hasValidCredentials = value;\r
+ NotifyOfPropertyChange(()=>HasValidCredentials);\r
+ }\r
+ }\r
+\r
+ private string _validationMessage;\r
+ public string ValidationMessage\r
+ {\r
+ get { return _validationMessage; }\r
+ set\r
+ {\r
+ _validationMessage = value;\r
+ NotifyOfPropertyChange(()=>ValidationMessage);\r
+ }\r
+ }\r
+\r
+ private bool _isWorking;\r
+ public bool IsWorking\r
+ {\r
+ get { return _isWorking; }\r
+ set\r
+ {\r
+ _isWorking = value;\r
+ NotifyOfPropertyChange(()=>IsWorking);\r
+ }\r
+ }\r
+\r
+ private string _busyTitle;\r
+ public string BusyTitle\r
+ {\r
+ get { return _busyTitle; }\r
+ set\r
+ {\r
+ _busyTitle = value;\r
+ NotifyOfPropertyChange(()=>BusyTitle);\r
+ }\r
+ }\r
+\r
+ private string _busyDetail;\r
+ private Regex _okeanosRegex = new Regex(@"(.*okeanos[0-9]*)\\pithos$");\r
+\r
+ public string BusyDetail\r
+ {\r
+ get { return _busyDetail; }\r
+ set\r
+ {\r
+ _busyDetail = value;\r
+ NotifyOfPropertyChange(()=>BusyDetail);\r
+ }\r
+ }\r
+\r
+ private void SetBusy(string title,string detail)\r
+ {\r
+ IsWorking = true;\r
+ BusyTitle = title;\r
+ BusyDetail = detail;\r
+ }\r
+\r
+ private void ClearBusy()\r
+ {\r
+ IsWorking = false;\r
+ BusyTitle = "";\r
+ BusyDetail = "";\r
+ \r
+ }\r
+\r
+ public async Task TestAccount()\r
+ {\r
+ try\r
+ {\r
+ SetBusy("Validating Credentials", "");\r
+ var client = new CloudFilesClient(AccountName, Token) { AuthenticationUrl = CurrentServer,/*Proxy=Proxy */};\r
+ await client.Authenticate().ConfigureAwait(false);\r
+ await client.ListContainers(AccountName).ConfigureAwait(false);\r
+ HasValidCredentials = true;\r
+ ValidationMessage = "Credentials Validated";\r
+ }\r
+ catch\r
+ {\r
+ HasValidCredentials = false;\r
+ MessageBox.Show("The account is not valid", "Account Error", MessageBoxButton.OK, MessageBoxImage.Stop);\r
+ ValidationMessage = "Credentials validation failed";\r
+ }\r
+ finally\r
+ {\r
+ ClearBusy();\r
+ }\r
+ }\r
+\r
+ }\r
+}\r