001/*
002 *  $URL: $
003 *  $Author: $
004 *  $Revision: $
005 *  $Date: $
006 */
007/*
008 *
009 *  Written by Tom Gutwin - WebARTS Design.
010 *  Copyright (C) 20133 WebARTS Design, North Vancouver Canada
011 *  http://www.webarts.bc.ca
012 *
013 *  This program is free software; you can redistribute it and/or modify
014 *  it under the terms of the GNU General Public License as published by
015 *  the Free Software Foundation; either version 2 of the License, or
016 *  (at your option) any later version.
017 *
018 *  This program is distributed in the hope that it will be useful,
019 *  but WITHOUT ANY WARRANTY; without_ even the implied warranty of
020 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
021 *  GNU General Public License for more details.
022 *
023 *  You should have received a copy of the GNU General Public License
024 *  along with this program; if not, write to the Free Software
025 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
026 */
027package ca.bc.webarts.tools.gapi;
028
029import com.google.api.client.auth.oauth2.Credential;
030import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
031import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
032import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
033import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
034import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets.Details;
035import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
036import com.google.api.client.googleapis.media.MediaHttpDownloader;
037import com.google.api.client.googleapis.media.MediaHttpUploader;
038import com.google.api.client.googleapis.media.MediaHttpDownloaderProgressListener;
039import com.google.api.client.googleapis.media.MediaHttpUploaderProgressListener;
040import com.google.api.client.http.FileContent;
041import com.google.api.client.http.GenericUrl;
042import com.google.api.client.http.HttpTransport;
043import com.google.api.client.json.JsonFactory;
044import com.google.api.client.json.jackson2.JacksonFactory;
045import com.google.api.client.util.Preconditions;
046import com.google.api.client.util.store.DataStoreFactory;
047import com.google.api.client.util.store.FileDataStoreFactory;
048import com.google.api.services.drive.Drive;
049import com.google.api.services.drive.DriveScopes;
050import com.google.api.services.drive.model.File;
051
052import java.io.FileOutputStream;
053import java.io.IOException;
054import java.io.InputStreamReader;
055import java.io.OutputStream;
056import java.security.GeneralSecurityException;
057import java.text.NumberFormat;
058import java.util.Collections;
059import java.util.List;
060import java.util.Properties;
061import java.util.Vector;
062
063import es.vocali.util.AESCrypt;
064
065/**
066 * A simple application that sends and receives encrypted files against the Drive API.
067   *  all you need to do is:
068   *  <pre>
069   *  String fileNameToUpload = "someFile.txt";
070   *  GDriveCrypter instance = new GDriveCrypter(fileNameToUpload);
071   *  //Authorize GDrive
072   *  instance.initDrive(instance.authorize());
073   *
074   *  // Encrypt
075   * String encryptedFilename = instance.encrypt(instance.getloadFilePath());
076   *  if (encryptedFilename!=null && !encryptedFilename.equals(""))
077   *  {
078   *    // Send File to GDrive
079   *    instance.setloadFilePath(encryptedFilename);
080   *    File uploadedFile = instance.uploadFile(false);
081   *  }
082   *  </pre>
083   *
084   **/
085public class GDriveCrypter extends GDriver
086{
087
088  /**  A holder This classes name (used when logging).  */
089  private static String CLASSNAME = "ca.bc.webarts.tools.gapi.GDriveCrypter";
090
091  /** The Extension to use on the filename to markk it as AESEncrypted. **/
092  protected static final String ECRYPT_FILEMARKER="etbg";
093
094  /** Password for the AES Encryption **/
095  private String eCryptPass = "k2yaRe9~hQ2g^43kL;p[;@3dnldiqnhyw68nayiqgT351TQ[P]ov_QbjqU8&6.+/?0^5%1~";
096
097
098  /** Default constructor that gets all the basic class settimgs setup and gives you a class instance to do the work.
099   *  Then all you need to do is:
100   *  <pre>
101   *  GDriveCrypter instance = new GDriveCrypter(); // uses the DEFAULT_LOAD_FILENAME
102   *  //Authorize GDrive
103   *  instance.initDrive(instance.authorize());
104   *
105   *  // Encrypt
106   * String encryptedFilename = instance.encrypt(instance.getloadFilePath());
107   *  if (encryptedFilename!=null && !encryptedFilename.equals(""))
108   *  {
109   *    // Send File to GDrive
110   *    instance.setloadFilePath(encryptedFilename);
111   *    File uploadedFile = instance.uploadFile(false);
112   *  }
113   *  </pre>
114   *
115   **/
116  public  GDriveCrypter() throws GeneralSecurityException, IOException
117  {
118    super();
119  }
120
121
122  /** Constructor that gets all the basic class settimgs setup, setsup the filename to upload and gives you a class instance to do the work.
123   *  Then all you need to do is:
124   *  <pre>
125   *  String fileNameToUpload = "someFile.txt";
126   *  GDriveCrypter instance = new GDriveCrypter(fileNameToUpload);
127
128   *  //Authorize GDrive
129   *  instance.initDrive(instance.authorize());
130   *
131   *  // Encrypt
132   * String encryptedFilename = instance.encrypt(instance.getloadFilePath());
133   *  if (encryptedFilename!=null && !encryptedFilename.equals(""))
134   *  {
135   *    // Send File to GDrive
136   *    instance.setloadFilePath(encryptedFilename);
137   *    File uploadedFile = instance.uploadFile(false);
138   *  }
139   *  </pre>
140   *
141   **/
142  public  GDriveCrypter(String filenameToLoad) throws GeneralSecurityException, IOException
143  {
144    super();
145  }
146
147
148  /** set the eCryptPass password used for encryption. **/
149  private void seteCryptPass(String pass)
150  {
151      eCryptPass = pass;
152  }
153  /** get the eCryptPass password used for encryption. **/
154  private String geteCryptPass() { return eCryptPass; }
155
156
157  public String encrypt(String filename) { return encrypt(geteCryptPass(), filename);}
158  public String encrypt(String pass, String filename)
159  {
160    String retVal = "";
161    String encryptedFilename = loadFilePath_+"_"+ECRYPT_FILEMARKER;
162    try
163    {
164      AESCrypt aes = new AESCrypt(true, pass);
165      if (loadFilePath_.lastIndexOf(".")!= -1)
166      {
167        encryptedFilename = loadFilePath_.substring(0,loadFilePath_.lastIndexOf("."))+
168                                 "_"+ECRYPT_FILEMARKER+"."+
169                                 loadFilePath_.substring(loadFilePath_.lastIndexOf(".")+1);
170      }
171      //else
172      //  encryptedFilename = loadFilePath_+"_"+ECRYPT_FILEMARKER;
173      aes.encrypt(2, loadFilePath_, encryptedFilename);
174      retVal = encryptedFilename;
175    }
176    catch(Exception ex)
177    {
178      System.err.println("did NOT encrypt "+loadFilePath_ + " to "+encryptedFilename);
179      ex.printStackTrace();
180    }
181    return retVal;
182  }
183
184
185  public String decrypt(String filename) { return decrypt(geteCryptPass(), filename);}
186  public String decrypt(String pass, String filename)
187  {
188    String retVal = "";
189    String decryptedFilename = filename.substring(0,filename.lastIndexOf("_"+ECRYPT_FILEMARKER)) +
190                               filename.substring( filename.lastIndexOf("_"+ECRYPT_FILEMARKER) +
191                                                   ("_"+ECRYPT_FILEMARKER).length()+1);
192    try
193    {
194      AESCrypt aes = new AESCrypt(true, pass);
195      aes.decrypt( filename, decryptedFilename);
196      if(new java.io.File(decryptedFilename).length()>0)
197        retVal = decryptedFilename;
198      //new java.io.File(decryptedFilename).length();
199    }
200    catch(Exception ex)
201    {
202      System.err.println("did NOT decrypt "+filename);
203      ex.printStackTrace();
204    }
205    return retVal;
206  }
207
208
209  public static void main(String[] args)
210  {
211    boolean encrypting = false;
212    GDriveCrypter instance = null;
213    try
214    {
215      if (args.length>0)
216      {
217        System.out.println(args[0]);
218        instance = new GDriveCrypter(args[0]);
219      }
220      else
221           instance = new GDriveCrypter();
222      if (args.length>1) instance.seteCryptPass(args[1]);
223
224      if (instance.getloadFilePath().lastIndexOf(instance.ECRYPT_FILEMARKER) == -1)
225        encrypting=true;
226
227      Preconditions.checkArgument (!instance.loadFilePath_.startsWith("Enter ") &&
228                                   !instance.dirForDownload_.startsWith("Enter "),
229                                   "Please enter the upload file path and download directory in %s", GDriveCrypter.class);
230      // authorization
231      Credential credential = instance.authorize();
232      instance.initDrive(credential);
233
234      if(encrypting)
235      {
236        // Encrypt
237        View.header1("encrypting File:"+instance.getloadFilePath());
238        String encryptedFilename = instance.encrypt(instance.getloadFilePath());
239        if (encryptedFilename!=null && !encryptedFilename.equals(""))
240        {
241          // BZip it
242          View.header1("BZipping encrypted File:"+encryptedFilename);
243          if (bzip2It(new java.io.File(encryptedFilename))>0L)
244          {
245            View.header1("Success");
246            encryptedFilename=encryptedFilename+ ".bz2";
247          }
248          // Send File to GDrive
249            instance.setloadFilePath(encryptedFilename);
250            View.header1("Starting Resumable Media Upload: "+ encryptedFilename);
251            File uploadedFile = instance.uploadFile(false);
252
253            /*
254            View.header1("Updating Uploaded File Name");
255            File updatedFile = updateFileWithTestSuffix(uploadedFile.getId());
256
257            View.header1("Starting Resumable Media Download");
258            downloadFile(false, updatedFile);
259
260            View.header1("Starting Simple Media Upload");
261            uploadedFile = uploadFile(true);
262
263            View.header1("Starting Simple Media Download");
264            downloadFile(true, uploadedFile);
265            */
266
267            View.header1("Success!");
268        }
269        return;
270      }
271      else // download and decrypt
272      {
273        //download file from GDrive
274        java.io.File downloadedFile = new java.io.File(instance.getloadFilePath());
275
276        View.header1("Listing Drive _"+ instance.ECRYPT_FILEMARKER+" Files");
277
278        //List<File> result = new java.util.ArrayList<File>();
279        Drive.Files.List listRequest = instance.drive_.files().list();
280        //listRequest.setQ("mimeType != 'application/vnd.google-apps.folder' and "+
281         //                "title contains '_"+ instance.ECRYPT_FILEMARKER+"'"); //"'root'" + " in parents");
282        listRequest.setQ("'root'" + " in parents");
283
284        com.google.api.services.drive.model.FileList files = null;
285        files = listRequest.execute();
286
287        for (com.google.api.services.drive.model.File element : files.getItems())
288        {
289            System.out.println(element.getTitle());
290        }
291        //instance.downloadFile(true, instance.loadFile_);
292
293        if (downloadedFile.length()>0)
294        {
295          View.header1("Uncompressing ");
296          //uncompress it
297          instance.unBzip2It(downloadedFile);
298
299          View.header1("decrypting "+instance.getloadFilePath().substring(0,instance.getloadFilePath().lastIndexOf(".bz2")));
300          //decrypting
301          instance.decrypt(instance.getloadFilePath().substring(0,instance.getloadFilePath().lastIndexOf(".bz2")));
302        }
303      }
304    }
305    catch (GeneralSecurityException gSecEx)
306    {
307      System.err.println(gSecEx.getMessage());
308    }
309    catch (IOException e)
310    {
311      System.err.println(e.getMessage());
312    }
313    catch (Throwable t)
314    {
315      t.printStackTrace();
316    }
317    System.exit(1);
318  }
319
320}