1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_SYNC_GLUE_PASSWORD_MODEL_ASSOCIATOR_H_
6#define CHROME_BROWSER_SYNC_GLUE_PASSWORD_MODEL_ASSOCIATOR_H_
7#pragma once
8
9#include <map>
10#include <string>
11#include <vector>
12
13#include "base/basictypes.h"
14#include "base/synchronization/lock.h"
15#include "base/task.h"
16#include "chrome/browser/history/history_types.h"
17#include "chrome/browser/sync/glue/model_associator.h"
18#include "chrome/browser/sync/protocol/password_specifics.pb.h"
19
20class GURL;
21class MessageLoop;
22class PasswordStore;
23class ProfileSyncService;
24
25namespace webkit_glue {
26struct PasswordForm;
27};
28
29namespace sync_api {
30class WriteNode;
31class WriteTransaction;
32};
33
34namespace browser_sync {
35
36class PasswordChangeProcessor;
37class UnrecoverableErrorHandler;
38
39extern const char kPasswordTag[];
40
41// Contains all model association related logic:
42// * Algorithm to associate password model and sync model.
43// * Persisting model associations and loading them back.
44// We do not check if we have local data before this runs; we always
45// merge and sync.
46class PasswordModelAssociator
47  : public PerDataTypeAssociatorInterface<std::string, std::string> {
48 public:
49  typedef std::vector<webkit_glue::PasswordForm> PasswordVector;
50
51  static syncable::ModelType model_type() { return syncable::PASSWORDS; }
52  PasswordModelAssociator(ProfileSyncService* sync_service,
53                          PasswordStore* password_store);
54  virtual ~PasswordModelAssociator();
55
56  // PerDataTypeAssociatorInterface implementation.
57  //
58  // Iterates through the sync model looking for matched pairs of items.
59  virtual bool AssociateModels();
60
61  // Delete all password nodes.
62  bool DeleteAllNodes(sync_api::WriteTransaction* trans);
63
64  // Clears all associations.
65  virtual bool DisassociateModels();
66
67  // The has_nodes out param is true if the sync model has nodes other
68  // than the permanent tagged nodes.
69  virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);
70
71  // See ModelAssociator interface.
72  virtual void AbortAssociation();
73
74  // See ModelAssociator interface.
75  virtual bool CryptoReadyIfNecessary();
76
77  // Not implemented.
78  virtual const std::string* GetChromeNodeFromSyncId(int64 sync_id);
79
80  // Not implemented.
81  virtual bool InitSyncNodeFromChromeId(const std::string& node_id,
82                                        sync_api::BaseNode* sync_node);
83
84  // Returns the sync id for the given password name, or sync_api::kInvalidId
85  // if the password name is not associated to any sync id.
86  virtual int64 GetSyncIdFromChromeId(const std::string& node_id);
87
88  // Associates the given password name with the given sync id.
89  virtual void Associate(const std::string* node, int64 sync_id);
90
91  // Remove the association that corresponds to the given sync id.
92  virtual void Disassociate(int64 sync_id);
93
94  // Returns whether a node with the given permanent tag was found and update
95  // |sync_id| with that node's id.
96  virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);
97
98  bool WriteToPasswordStore(const PasswordVector* new_passwords,
99                            const PasswordVector* updated_passwords,
100                            const PasswordVector* deleted_passwords);
101
102  static std::string MakeTag(const webkit_glue::PasswordForm& password);
103  static std::string MakeTag(const sync_pb::PasswordSpecificsData& password);
104  static std::string MakeTag(const std::string& origin_url,
105                             const std::string& username_element,
106                             const std::string& username_value,
107                             const std::string& password_element,
108                             const std::string& signon_realm);
109
110  static void CopyPassword(const sync_pb::PasswordSpecificsData& password,
111                           webkit_glue::PasswordForm* new_password);
112
113  static bool MergePasswords(const sync_pb::PasswordSpecificsData& password,
114                             const webkit_glue::PasswordForm& password_form,
115                             webkit_glue::PasswordForm* new_password);
116  static void WriteToSyncNode(const webkit_glue::PasswordForm& password_form,
117                              sync_api::WriteNode* node);
118
119  // Called at various points in model association to determine if the
120  // user requested an abort.
121  bool IsAbortPending();
122
123 private:
124  typedef std::map<std::string, int64> PasswordToSyncIdMap;
125  typedef std::map<int64, std::string> SyncIdToPasswordMap;
126
127  ProfileSyncService* sync_service_;
128  PasswordStore* password_store_;
129  int64 password_node_id_;
130
131  // Abort association pending flag and lock.  If this is set to true
132  // (via the AbortAssociation method), return from the
133  // AssociateModels method as soon as possible.
134  base::Lock abort_association_pending_lock_;
135  bool abort_association_pending_;
136
137  MessageLoop* expected_loop_;
138
139  PasswordToSyncIdMap id_map_;
140  SyncIdToPasswordMap id_map_inverse_;
141
142  DISALLOW_COPY_AND_ASSIGN(PasswordModelAssociator);
143};
144
145}  // namespace browser_sync
146
147#endif  // CHROME_BROWSER_SYNC_GLUE_PASSWORD_MODEL_ASSOCIATOR_H_
148