mobile/android/base/sync/middleware/Crypto5MiddlewareRepositorySession.java

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 package org.mozilla.gecko.sync.middleware;
     7 import java.io.UnsupportedEncodingException;
     8 import java.util.concurrent.ExecutorService;
    10 import org.mozilla.gecko.sync.CryptoRecord;
    11 import org.mozilla.gecko.sync.crypto.CryptoException;
    12 import org.mozilla.gecko.sync.crypto.KeyBundle;
    13 import org.mozilla.gecko.sync.repositories.InactiveSessionException;
    14 import org.mozilla.gecko.sync.repositories.NoStoreDelegateException;
    15 import org.mozilla.gecko.sync.repositories.RecordFactory;
    16 import org.mozilla.gecko.sync.repositories.RepositorySession;
    17 import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecordsDelegate;
    18 import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionStoreDelegate;
    19 import org.mozilla.gecko.sync.repositories.domain.Record;
    21 /**
    22  * It's a RepositorySession that accepts Records as input, producing CryptoRecords
    23  * for submission to a remote service.
    24  * Takes a RecordFactory as a parameter. This is in charge of taking decrypted CryptoRecords
    25  * as input and producing some expected kind of Record as output for local use.
    26  *
    27  *
    31                  +------------------------------------+
    32                  |    Server11RepositorySession       |
    33                  +-------------------------+----------+
    34                            ^               |
    35                            |               |
    36                         Encrypted CryptoRecords
    37                            |               |
    38                            |               v
    39                  +---------+--------------------------+
    40                  | Crypto5MiddlewareRepositorySession |
    41                  +------------------------------------+
    42                            ^               |
    43                            |               |  Decrypted CryptoRecords
    44                            |               |
    45                            |            +---------------+
    46                            |            | RecordFactory |
    47                            |            +--+------------+
    48                            |               |
    49                           Local Record instances
    50                            |               |
    51                            |               v
    52                  +---------+--------------------------+
    53                  |  Local RepositorySession instance  |
    54                  +------------------------------------+
    57  * @author rnewman
    58  *
    59  */
    60 public class Crypto5MiddlewareRepositorySession extends MiddlewareRepositorySession {
    61   private KeyBundle keyBundle;
    62   private RecordFactory recordFactory;
    64   public Crypto5MiddlewareRepositorySession(RepositorySession session, Crypto5MiddlewareRepository repository, RecordFactory recordFactory) {
    65     super(session, repository);
    66     this.keyBundle = repository.keyBundle;
    67     this.recordFactory = recordFactory;
    68   }
    70   public class DecryptingTransformingFetchDelegate implements RepositorySessionFetchRecordsDelegate {
    71     private RepositorySessionFetchRecordsDelegate next;
    72     private KeyBundle keyBundle;
    73     private RecordFactory recordFactory;
    75     DecryptingTransformingFetchDelegate(RepositorySessionFetchRecordsDelegate next, KeyBundle bundle, RecordFactory recordFactory) {
    76       this.next = next;
    77       this.keyBundle = bundle;
    78       this.recordFactory = recordFactory;
    79     }
    81     @Override
    82     public void onFetchFailed(Exception ex, Record record) {
    83       next.onFetchFailed(ex, record);
    84     }
    86     @Override
    87     public void onFetchedRecord(Record record) {
    88       CryptoRecord r;
    89       try {
    90         r = (CryptoRecord) record;
    91       } catch (ClassCastException e) {
    92         next.onFetchFailed(e, record);
    93         return;
    94       }
    95       r.keyBundle = keyBundle;
    96       try {
    97         r.decrypt();
    98       } catch (Exception e) {
    99         next.onFetchFailed(e, r);
   100         return;
   101       }
   102       Record transformed;
   103       try {
   104         transformed = this.recordFactory.createRecord(r);
   105       } catch (Exception e) {
   106         next.onFetchFailed(e, r);
   107         return;
   108       }
   109       next.onFetchedRecord(transformed);
   110     }
   112     @Override
   113     public void onFetchCompleted(final long fetchEnd) {
   114       next.onFetchCompleted(fetchEnd);
   115     }
   117     @Override
   118     public RepositorySessionFetchRecordsDelegate deferredFetchDelegate(ExecutorService executor) {
   119       // Synchronously perform *our* work, passing through appropriately.
   120       RepositorySessionFetchRecordsDelegate deferredNext = next.deferredFetchDelegate(executor);
   121       return new DecryptingTransformingFetchDelegate(deferredNext, keyBundle, recordFactory);
   122     }
   123   }
   125   private DecryptingTransformingFetchDelegate makeUnwrappingDelegate(RepositorySessionFetchRecordsDelegate inner) {
   126     if (inner == null) {
   127       throw new IllegalArgumentException("Inner delegate cannot be null!");
   128     }
   129     return new DecryptingTransformingFetchDelegate(inner, this.keyBundle, this.recordFactory);
   130   }
   132   @Override
   133   public void fetchSince(long timestamp,
   134                          RepositorySessionFetchRecordsDelegate delegate) {
   135     inner.fetchSince(timestamp, makeUnwrappingDelegate(delegate));
   136   }
   138   @Override
   139   public void fetch(String[] guids,
   140                     RepositorySessionFetchRecordsDelegate delegate) throws InactiveSessionException {
   141     inner.fetch(guids, makeUnwrappingDelegate(delegate));
   142   }
   144   @Override
   145   public void fetchAll(RepositorySessionFetchRecordsDelegate delegate) {
   146     inner.fetchAll(makeUnwrappingDelegate(delegate));
   147   }
   149   @Override
   150   public void setStoreDelegate(RepositorySessionStoreDelegate delegate) {
   151     // TODO: it remains to be seen how this will work.
   152     inner.setStoreDelegate(delegate);
   153     this.delegate = delegate;             // So we can handle errors without involving inner.
   154   }
   156   @Override
   157   public void store(Record record) throws NoStoreDelegateException {
   158     if (delegate == null) {
   159       throw new NoStoreDelegateException();
   160     }
   161     CryptoRecord rec = record.getEnvelope();
   162     rec.keyBundle = this.keyBundle;
   163     try {
   164       rec.encrypt();
   165     } catch (UnsupportedEncodingException e) {
   166       delegate.onRecordStoreFailed(e, record.guid);
   167       return;
   168     } catch (CryptoException e) {
   169       delegate.onRecordStoreFailed(e, record.guid);
   170       return;
   171     }
   172     // Allow the inner session to do delegate handling.
   173     inner.store(rec);
   174   }
   175 }

mercurial