Statistics
| Branch: | Revision:

root / trunk / Pithos.Client.WPF / Preferences / AddAccountViewModel.cs @ 84b880b5

History | View | Annotate | Download (12.4 kB)

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.Text.RegularExpressions;
48
using System.Threading.Tasks;
49
using System.Windows;
50
using System.Windows.Forms;
51
using Pithos.Client.WPF.Properties;
52
using Pithos.Interfaces;
53
using Pithos.Network;
54
using MessageBox = System.Windows.MessageBox;
55
using Screen = Caliburn.Micro.Screen;
56

    
57
namespace Pithos.Client.WPF.Preferences
58
{
59
    [Export(typeof(AddAccountViewModel))]
60
    public class AddAccountViewModel:Screen
61
    {
62

    
63
        private readonly List<string> _servers;
64

    
65
        public List<string> Servers
66
        {
67
            get { return Settings.Default.Servers.Select(server => server.ServerUri).ToList(); }
68
        }
69

    
70
        private bool _isValidServer;
71
        public bool IsValidServer
72
        {
73
            get { return _isValidServer; }
74
            set
75
            {
76
                _isValidServer = value;
77
                NotifyOfPropertyChange(()=>IsValidServer);
78
            }
79
        }
80

    
81

    
82
        private string _currentServer;
83
        public string CurrentServer
84
        {
85
            get { return _currentServer; }
86
            set
87
            {
88
                if (!Uri.IsWellFormedUriString(value, UriKind.Absolute))
89
                {
90
                    IsValidServer = false;
91
                    throw new UriFormatException();
92
                }
93
                _currentServer = value;
94
                IsValidServer = true;
95
                HasValidCredentials = false;
96
                IsConfirmed = false;
97
                NotifyOfPropertyChange(()=>CurrentServer);
98
            }
99
        }
100

    
101
        private string _accountName;
102
        public string AccountName
103
        {
104
            get { return _accountName; }
105
            set
106
            {
107
                _accountName = value;
108

    
109
                NotifyOfPropertyChange(()=>AccountName);
110
                NotifyOfPropertyChange(() => HasCredentials);
111
            }
112
        }
113

    
114
        private string _token;
115
        public string Token
116
        {
117
            get { return _token; }
118
            set
119
            {
120
                _token = value;
121
                NotifyOfPropertyChange(()=>Token);
122
                NotifyOfPropertyChange(() => HasCredentials);
123
            }
124
        }
125

    
126
        private string _accountPath;
127
        public string AccountPath
128
        {
129
            get { return _accountPath; }
130
            set
131
            {
132
                _accountPath = value;
133
                NotifyOfPropertyChange(() => AccountPath);
134
                NotifyOfPropertyChange(() => HasAccountPath);
135
            }
136
        }
137

    
138

    
139
        public bool HasAccountPath
140
        {
141
            get { return !String.IsNullOrWhiteSpace(AccountPath); }
142
        }
143

    
144
        public bool HasCredentials
145
        {
146
            get { return !(String.IsNullOrWhiteSpace(AccountName) || String.IsNullOrWhiteSpace(Token) ) ; }
147
        }
148

    
149

    
150
        private bool  _isConfirmed;
151

    
152
        public bool IsConfirmed
153
        {
154
            get { return _isConfirmed; }
155
            set
156
            {
157
                _isConfirmed = value;
158
                HasValidCredentials = false;
159
                NotifyOfPropertyChange(() => IsConfirmed);
160
            }
161
        }
162

    
163

    
164
        private bool _isAccountActive;
165

    
166
        public bool IsAccountActive
167
        {
168
            get { return _isAccountActive; }
169
            set
170
            {
171
                _isAccountActive = value;
172
                NotifyOfPropertyChange(() => IsAccountActive);
173
            }
174
        }
175

    
176

    
177
        private bool _shouldCreateOkeanosFolder;
178
        public bool ShouldCreateOkeanosFolder
179
        {
180
            get { return _shouldCreateOkeanosFolder; }
181
            set
182
            {
183
                _shouldCreateOkeanosFolder = value;
184
                NotifyOfPropertyChange(()=>ShouldCreateOkeanosFolder);
185
            }
186
        }
187

    
188
        bool HasNoParentWithCache(DirectoryInfo info)
189
        {
190
            if (info == null)
191
                return false;
192
            var parent = info.Parent;
193
            if (parent == null)
194
                return true;
195
            if (parent.EnumerateDirectories(FolderConstants.CacheFolder).Any())
196
            {
197
                return false;
198
            }
199
            return HasNoParentWithCache(parent);
200
        }
201

    
202
        string GetLowestAboveCache(string path)
203
        {
204
            if (String.IsNullOrWhiteSpace(path))
205
                return null;
206
            var info = new DirectoryInfo(path);
207
            if (!info.Exists)
208
                return path;
209
            while (!HasNoParentWithCache(info))
210
            {
211
                info = info.Parent;
212
            }
213
            if (info == null)
214
                return null;
215
            else
216
                return info.FullName;
217
        }
218

    
219
        public void SelectAccount()
220
        {
221
            using (var dlg = new FolderBrowserDialog{Description=Resources.AddAccountViewModel_SelectAccount_Please_select_a_folder})
222
            {
223
                //Ask the user to select a folder
224
                //Note: We need a parent window here, which we retrieve with GetView            
225
                var view = (Window)GetView();
226
                if (DialogResult.OK != dlg.ShowDialog(new Wpf32Window(view)))
227
                    return;
228

    
229
                //If the selected path is under an account folder, ie a folder containint a .pithos.cache subfolder, try to locate
230
                //the cache's parent folder
231
                var selectedPath = GetLowestAboveCache(dlg.SelectedPath);
232

    
233
                //If the path  ends with /okeanos#/pithos, replace with /okeanos#
234
                var match = _okeanosRegex.Match(selectedPath);
235
                if (match.Success)
236
                {
237
                    selectedPath = match.Groups[1].Value;                    
238
                }
239

    
240
                AccountPath= selectedPath;
241

    
242

    
243

    
244
                ShouldCreateOkeanosFolder=Directory.EnumerateFileSystemEntries(AccountPath).Any();                
245
            }
246
        }
247

    
248

    
249
        public void RetrieveCredentials()
250
        {
251
            SetBusy("Waiting for credentials.", "Please enter your credentials in the Pithos logon page");
252
            IsConfirmed = false;
253

    
254
            try
255
            {
256
                var loginUri = PithosAccount.GetLoginUri(CurrentServer);
257
                var credentials = PithosAccount.RetrieveCredentials(loginUri.ToString());
258
                if (credentials == null)
259
                    return;
260
                //AccountName = credentials.UserName;
261
                Token = credentials.Password;
262
                AccountName = PithosAccount.GetUserID(new Uri(CurrentServer), Token);
263

    
264
                IsConfirmed = true;
265

    
266
            }
267
            catch (PithosException exc)
268
            {
269
                ClearBusy();
270
                MessageBox.Show(exc.Message, "Unable to retrieve the credentials");
271
            }
272
            catch (Exception exc)
273
            {
274
                IsConfirmed = false;
275
                MessageBox.Show(exc.ToString(), "Error");
276
                throw;
277
            }
278
            finally
279
            {
280
                ClearBusy();
281
                
282
                ((Window) GetView()).Activate();
283
            }
284

    
285
            if (IsConfirmed)
286
                TaskEx.Run(()=>TestAccount());
287

    
288
        }
289

    
290
        public AddAccountViewModel()
291
        {
292
            _servers=new List<string>
293
                         {
294
                             Settings.Default.ProductionServer, 
295
                             Settings.Default.DevelopmentServer
296
                         };
297
            CurrentServer = _servers[0];
298
            DisplayName = "Add Pithos+ Account";
299
        }
300

    
301
        private bool _hasValidCredentials;
302
        public bool HasValidCredentials
303
        {
304
            get { return _hasValidCredentials; }
305
            set
306
            {
307
                _hasValidCredentials = value;
308
                NotifyOfPropertyChange(()=>HasValidCredentials);
309
            }
310
        }
311

    
312
        private string _validationMessage;
313
        public string ValidationMessage
314
        {
315
            get { return _validationMessage; }
316
            set
317
            {
318
                _validationMessage = value;
319
                NotifyOfPropertyChange(()=>ValidationMessage);
320
            }
321
        }
322

    
323
        private bool _isWorking;
324
        public bool IsWorking
325
        {
326
            get { return _isWorking; }
327
            set
328
            {
329
                _isWorking = value;
330
                NotifyOfPropertyChange(()=>IsWorking);
331
            }
332
        }
333

    
334
        private string _busyTitle;
335
        public string BusyTitle
336
        {
337
            get { return _busyTitle; }
338
            set
339
            {
340
                _busyTitle = value;
341
                NotifyOfPropertyChange(()=>BusyTitle);
342
            }
343
        }
344

    
345
        private string _busyDetail;
346
        private Regex _okeanosRegex = new Regex(@"(.*okeanos[0-9]*)\\pithos$");
347

    
348
        public string BusyDetail
349
        {
350
            get { return _busyDetail; }
351
            set
352
            {
353
                _busyDetail = value;
354
                NotifyOfPropertyChange(()=>BusyDetail);
355
            }
356
        }
357

    
358
        private void SetBusy(string title,string detail)
359
        {
360
            IsWorking = true;
361
            BusyTitle = title;
362
            BusyDetail = detail;
363
        }
364

    
365
        private void ClearBusy()
366
        {
367
            IsWorking = false;
368
            BusyTitle = "";
369
            BusyDetail = "";
370
            
371
        }
372

    
373
        public async Task TestAccount()
374
        {
375
            try
376
            {
377
                SetBusy("Validating Credentials", "");
378
                var client = new CloudFilesClient(AccountName, Token) { AuthenticationUrl = CurrentServer,/*Proxy=Proxy */};
379
                //MessageBox.Show(AccountName);
380
                //MessageBox.Show(Token);
381
                //MessageBox.Show(CurrentServer);
382
                await client.Authenticate().ConfigureAwait(false);
383
                await client.ListContainers(AccountName).ConfigureAwait(false);
384
                HasValidCredentials = true;
385
                ValidationMessage = "Credentials Validated";
386
            }
387
            catch
388
            {
389
                HasValidCredentials = false;
390
                MessageBox.Show("The account is not valid", "Account Error", MessageBoxButton.OK, MessageBoxImage.Stop);
391
                ValidationMessage = "Credentials validation failed";
392
            }
393
            finally
394
            {
395
                ClearBusy();
396
            }
397
        }
398

    
399
    }
400
}