summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/glue/password_model_associator.h
blob: 303df9f552b6d357be1af5f3b0dafe1b2c4c49d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_SYNC_GLUE_PASSWORD_MODEL_ASSOCIATOR_H_
#define CHROME_BROWSER_SYNC_GLUE_PASSWORD_MODEL_ASSOCIATOR_H_

#include <map>
#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/synchronization/lock.h"
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/sync/glue/data_type_error_handler.h"
#include "chrome/browser/sync/glue/model_associator.h"
#include "sync/protocol/password_specifics.pb.h"

class MessageLoop;
class PasswordStore;
class ProfileSyncService;

namespace content {
struct PasswordForm;
}

namespace syncer {
class WriteNode;
class WriteTransaction;
}

namespace browser_sync {

extern const char kPasswordTag[];

// Contains all model association related logic:
// * Algorithm to associate password model and sync model.
// * Persisting model associations and loading them back.
// We do not check if we have local data before this runs; we always
// merge and sync.
class PasswordModelAssociator
  : public PerDataTypeAssociatorInterface<std::string, std::string> {
 public:
  typedef std::vector<content::PasswordForm> PasswordVector;

  static syncer::ModelType model_type() { return syncer::PASSWORDS; }
  PasswordModelAssociator(ProfileSyncService* sync_service,
                          PasswordStore* password_store,
                          DataTypeErrorHandler* error_handler);
  virtual ~PasswordModelAssociator();

  // PerDataTypeAssociatorInterface implementation.
  //
  // Iterates through the sync model looking for matched pairs of items.
  virtual syncer::SyncError AssociateModels(
      syncer::SyncMergeResult* local_merge_result,
      syncer::SyncMergeResult* syncer_merge_result) OVERRIDE;

  // Delete all password nodes.
  bool DeleteAllNodes(syncer::WriteTransaction* trans);

  // Clears all associations.
  virtual syncer::SyncError DisassociateModels() OVERRIDE;

  // The has_nodes out param is true if the sync model has nodes other
  // than the permanent tagged nodes.
  virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes) OVERRIDE;

  // See ModelAssociator interface.
  virtual void AbortAssociation() OVERRIDE;

  // See ModelAssociator interface.
  virtual bool CryptoReadyIfNecessary() OVERRIDE;

  // Not implemented.
  virtual const std::string* GetChromeNodeFromSyncId(int64 sync_id) OVERRIDE;

  // Not implemented.
  virtual bool InitSyncNodeFromChromeId(const std::string& node_id,
                                        syncer::BaseNode* sync_node) OVERRIDE;

  // Returns the sync id for the given password name, or syncer::kInvalidId
  // if the password name is not associated to any sync id.
  virtual int64 GetSyncIdFromChromeId(const std::string& node_id) OVERRIDE;

  // Associates the given password name with the given sync id.
  virtual void Associate(const std::string* node, int64 sync_id) OVERRIDE;

  // Remove the association that corresponds to the given sync id.
  virtual void Disassociate(int64 sync_id) OVERRIDE;

  // Returns whether a node with the given permanent tag was found and update
  // |sync_id| with that node's id.
  virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);

  syncer::SyncError WriteToPasswordStore(const PasswordVector* new_passwords,
                                 const PasswordVector* updated_passwords,
                                 const PasswordVector* deleted_passwords);

  static std::string MakeTag(const content::PasswordForm& password);
  static std::string MakeTag(const sync_pb::PasswordSpecificsData& password);
  static std::string MakeTag(const std::string& origin_url,
                             const std::string& username_element,
                             const std::string& username_value,
                             const std::string& password_element,
                             const std::string& signon_realm);

  static void CopyPassword(const sync_pb::PasswordSpecificsData& password,
                           content::PasswordForm* new_password);

  static bool MergePasswords(const sync_pb::PasswordSpecificsData& password,
                             const content::PasswordForm& password_form,
                             content::PasswordForm* new_password);
  static void WriteToSyncNode(const content::PasswordForm& password_form,
                              syncer::WriteNode* node);

  // Called at various points in model association to determine if the
  // user requested an abort.
  bool IsAbortPending();

 private:
  typedef std::map<std::string, int64> PasswordToSyncIdMap;
  typedef std::map<int64, std::string> SyncIdToPasswordMap;

  ProfileSyncService* sync_service_;
  PasswordStore* password_store_;
  int64 password_node_id_;

  // Abort association pending flag and lock.  If this is set to true
  // (via the AbortAssociation method), return from the
  // AssociateModels method as soon as possible.
  base::Lock abort_association_pending_lock_;
  bool abort_association_pending_;

  MessageLoop* expected_loop_;

  PasswordToSyncIdMap id_map_;
  SyncIdToPasswordMap id_map_inverse_;
  DataTypeErrorHandler* error_handler_;

  DISALLOW_COPY_AND_ASSIGN(PasswordModelAssociator);
};

}  // namespace browser_sync

#endif  // CHROME_BROWSER_SYNC_GLUE_PASSWORD_MODEL_ASSOCIATOR_H_