884ee7b0e0d9ed6ae295d9d84f36a89d5cdb4676
[pithos-ms-client] / trunk%2FPithos.Client.WPF%2FPreferences%2FAddAccountViewModel.cs
1 #region
2 /* -----------------------------------------------------------------------
3  * <copyright file="AddAccountViewModel.cs" company="GRNet">
4  * 
5  * Copyright 2011-2012 GRNET S.A. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or
8  * without modification, are permitted provided that the following
9  * conditions are met:
10  *
11  *   1. Redistributions of source code must retain the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer.
14  *
15  *   2. Redistributions in binary form must reproduce the above
16  *      copyright notice, this list of conditions and the following
17  *      disclaimer in the documentation and/or other materials
18  *      provided with the distribution.
19  *
20  *
21  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
22  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
25  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * The views and conclusions contained in the software and
35  * documentation are those of the authors and should not be
36  * interpreted as representing official policies, either expressed
37  * or implied, of GRNET S.A.
38  * </copyright>
39  * -----------------------------------------------------------------------
40  */
41 #endregion
42 using System;
43 using System.Collections.Generic;
44 using System.ComponentModel.Composition;
45 using System.IO;
46 using System.Linq;
47 using System.Threading.Tasks;
48 using System.Windows;
49 using System.Windows.Forms;
50 using Pithos.Client.WPF.Properties;
51 using Pithos.Network;
52 using MessageBox = System.Windows.MessageBox;
53 using Screen = Caliburn.Micro.Screen;
54
55 namespace Pithos.Client.WPF.Preferences
56 {
57     [Export(typeof(AddAccountViewModel))]
58     public class AddAccountViewModel:Screen
59     {
60
61         private readonly List<string> _servers;
62
63         public List<string> Servers
64         {
65             get { return _servers; }
66         }
67
68         private bool _isValidServer;
69         public bool IsValidServer
70         {
71             get { return _isValidServer; }
72             set
73             {
74                 _isValidServer = value;
75                 NotifyOfPropertyChange(()=>IsValidServer);
76             }
77         }
78
79
80         private string _currentServer;
81         public string CurrentServer
82         {
83             get { return _currentServer; }
84             set
85             {
86                 if (!Uri.IsWellFormedUriString(value, UriKind.Absolute))
87                 {
88                     IsValidServer = false;
89                     throw new UriFormatException();
90                 }
91                 _currentServer = value;
92                 IsValidServer = true;
93                 HasValidCredentials = false;
94                 IsConfirmed = false;
95                 NotifyOfPropertyChange(()=>CurrentServer);
96             }
97         }
98
99         private string _accountName;
100         public string AccountName
101         {
102             get { return _accountName; }
103             set
104             {
105                 _accountName = value;
106                 NotifyOfPropertyChange(()=>AccountName);
107                 NotifyOfPropertyChange(() => HasCredentials);
108             }
109         }
110
111         private string _token;
112         public string Token
113         {
114             get { return _token; }
115             set
116             {
117                 _token = value;
118                 NotifyOfPropertyChange(()=>Token);
119                 NotifyOfPropertyChange(() => HasCredentials);
120             }
121         }
122
123         private string _accountPath;
124         public string AccountPath
125         {
126             get { return _accountPath; }
127             set
128             {
129                 _accountPath = value;
130                 NotifyOfPropertyChange(() => AccountPath);
131                 NotifyOfPropertyChange(() => HasAccountPath);
132             }
133         }
134
135
136         public bool HasAccountPath
137         {
138             get { return !String.IsNullOrWhiteSpace(AccountPath); }
139         }
140
141         public bool HasCredentials
142         {
143             get { return !(String.IsNullOrWhiteSpace(AccountName) || String.IsNullOrWhiteSpace(Token) ) ; }
144         }
145
146
147         private bool  _isConfirmed;
148
149         public bool IsConfirmed
150         {
151             get { return _isConfirmed; }
152             set
153             {
154                 _isConfirmed = value;
155                 HasValidCredentials = false;
156                 NotifyOfPropertyChange(() => IsConfirmed);
157             }
158         }
159
160
161         private bool _isAccountActive;
162
163         public bool IsAccountActive
164         {
165             get { return _isAccountActive; }
166             set
167             {
168                 _isAccountActive = value;
169                 NotifyOfPropertyChange(() => IsAccountActive);
170             }
171         }
172
173
174         private bool _shouldCreateOkeanosFolder;
175         public bool ShouldCreateOkeanosFolder
176         {
177             get { return _shouldCreateOkeanosFolder; }
178             set
179             {
180                 _shouldCreateOkeanosFolder = value;
181                 NotifyOfPropertyChange(()=>ShouldCreateOkeanosFolder);
182             }
183         }
184
185         public void SelectAccount()
186         {
187             using (var dlg = new FolderBrowserDialog{Description=Resources.AddAccountViewModel_SelectAccount_Please_select_a_folder})
188             {
189                 //Ask the user to select a folder
190                 //Note: We need a parent window here, which we retrieve with GetView            
191                 var view = (Window)GetView();
192                 if (DialogResult.OK != dlg.ShowDialog(new Wpf32Window(view)))
193                     return;
194
195                 AccountPath= dlg.SelectedPath;
196
197                 ShouldCreateOkeanosFolder=Directory.EnumerateFileSystemEntries(AccountPath).Any();                
198             }
199         }
200
201
202         public void RetrieveCredentials()
203         {
204             SetBusy("Waiting for credentials.", "Please enter your credentials in the Pithos logon page");
205             IsConfirmed = false;
206
207             try
208             {
209                 var loginUri=new Uri(new Uri(CurrentServer) , "login");
210                 var credentials = PithosAccount.RetrieveCredentials(loginUri.ToString());
211                 if (credentials == null)
212                     return;
213                 AccountName = credentials.UserName;
214                 Token = credentials.Password;
215
216                 IsConfirmed = true;
217
218             }
219             catch (PithosException exc)
220             {
221                 ClearBusy();
222                 MessageBox.Show(exc.Message, "Unable to retrieve credentials");
223             }
224             catch (Exception exc)
225             {
226                 IsConfirmed = false;
227                 MessageBox.Show(exc.ToString(), "Error");
228                 throw;
229             }
230             finally
231             {
232                 ClearBusy();
233                 
234                 ((Window) GetView()).Activate();
235             }
236
237             if (IsConfirmed)
238                 TaskEx.Run(TestAccount);
239
240         }
241
242         public AddAccountViewModel()
243         {
244             _servers=new List<string>
245                          {
246                              Settings.Default.ProductionServer, 
247                              Settings.Default.DevelopmentServer
248                          };
249             CurrentServer = _servers[0];
250         }
251
252         private bool _hasValidCredentials;
253         public bool HasValidCredentials
254         {
255             get { return _hasValidCredentials; }
256             set
257             {
258                 _hasValidCredentials = value;
259                 NotifyOfPropertyChange(()=>HasValidCredentials);
260             }
261         }
262
263         private string _validationMessage;
264         public string ValidationMessage
265         {
266             get { return _validationMessage; }
267             set
268             {
269                 _validationMessage = value;
270                 NotifyOfPropertyChange(()=>ValidationMessage);
271             }
272         }
273
274         private bool _isWorking;
275         public bool IsWorking
276         {
277             get { return _isWorking; }
278             set
279             {
280                 _isWorking = value;
281                 NotifyOfPropertyChange(()=>IsWorking);
282             }
283         }
284
285         private string _busyTitle;
286         public string BusyTitle
287         {
288             get { return _busyTitle; }
289             set
290             {
291                 _busyTitle = value;
292                 NotifyOfPropertyChange(()=>BusyTitle);
293             }
294         }
295
296         private string _busyDetail;
297         public string BusyDetail
298         {
299             get { return _busyDetail; }
300             set
301             {
302                 _busyDetail = value;
303                 NotifyOfPropertyChange(()=>BusyDetail);
304             }
305         }
306
307         private void SetBusy(string title,string detail)
308         {
309             IsWorking = true;
310             BusyTitle = title;
311             BusyDetail = detail;
312         }
313
314         private void ClearBusy()
315         {
316             IsWorking = false;
317             BusyTitle = "";
318             BusyDetail = "";
319             
320         }
321
322         public async void TestAccount()
323         {
324             try
325             {
326                 SetBusy("Validating Credentials", "");
327                 var client = new CloudFilesClient(AccountName, Token) { AuthenticationUrl = CurrentServer,/*Proxy=Proxy */};                
328                 await TaskEx.Run(() =>
329                                      {
330                                          client.Authenticate();
331                                          return client.ListContainers(AccountName);
332                                      });
333                 HasValidCredentials = true;
334                 ValidationMessage = "Credentials Validated";
335             }
336             catch
337             {
338                 HasValidCredentials = false;
339                 MessageBox.Show("The account is not valid", "Account Error", MessageBoxButton.OK, MessageBoxImage.Stop);
340                 ValidationMessage = "Credentials validation failed";
341             }
342             finally
343             {
344                 ClearBusy();
345             }
346         }
347
348     }
349 }