BowlerKernel
PasswordManager.java
Go to the documentation of this file.
1 package com.neuronrobotics.bowlerstudio.scripting;
2 
3 import java.awt.GraphicsEnvironment;
4 import java.io.BufferedReader;
5 import java.io.Console;
6 import java.io.File;
7 import java.io.IOException;
8 import java.io.InputStreamReader;
9 import java.net.URL;
10 import java.net.URLConnection;
11 import java.nio.charset.StandardCharsets;
12 import java.nio.file.Files;
13 import java.nio.file.Paths;
14 import java.security.GeneralSecurityException;
15 import java.text.DateFormat;
16 import java.text.SimpleDateFormat;
17 import java.util.Arrays;
18 import java.util.Date;
19 import java.util.List;
20 import com.google.crypto.tink.Aead;
21 import com.google.crypto.tink.KeysetHandle;
22 import com.google.crypto.tink.aead.AeadKeyTemplates;
23 import org.eclipse.jgit.transport.CredentialsProvider;
24 import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
25 import org.kohsuke.github.GHAuthorization;
26 import org.kohsuke.github.GitHub;
27 
28 import com.google.crypto.tink.CleartextKeysetHandle;
29 import com.google.crypto.tink.JsonKeysetReader;
30 import com.google.crypto.tink.JsonKeysetWriter;
31 import com.google.crypto.tink.config.TinkConfig;
32 
33 public class PasswordManager {
34  private static IGitHubLoginManager loginManager=null;
36  private static List<String> listOfScopes = Arrays.asList("repo", "gist", "write:packages", "read:packages", "delete:packages",
37  "user", "delete_repo");
39 
40  @Override
41  public String[] prompt(String username) {
42  // new RuntimeException("Login required").printStackTrace();
43 
44  if (username != null) {
45  if (username.equals(""))
46  username = null;
47  }
48  String[] creds = new String[] { "", "" };
49  System.out.println("#Github Login Prompt#");
50  System.out.println("For anynomous mode hit enter twice");
51  System.out.print("Github Username: " + (username != null ? "(" + username + ")" : ""));
52  // create a scanner so we can read the command-line input
53  BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
54 
55  do {
56  try {
57  Thread.sleep(100);
58  } catch (InterruptedException e) {
59  // TODO Auto-generated catch block
60  e.printStackTrace();
61  }
62  try {
63 
64  creds[0] = buf.readLine();
65 
66  } catch (IOException e) {
67  e.printStackTrace();
68  return null;
69  }
70  if (creds[0].equals("") && (username == null)) {
71  System.out.println("No username, using anynomous login");
72  return null;
73  }
74 
75  } while (creds[0] == null);
76 
77  // System.out.print("Github Password: ");
78  try {
79  Console cons;
80  char[] passwd;
81  if ((cons = System.console()) != null
82  && (passwd = cons.readPassword("[%s]", "GitHub Password:")) != null) {
83  creds[1] = new String(passwd);
84  java.util.Arrays.fill(passwd, ' ');
85  }
86  // creds[1] = buf.readLine();
87  if (creds[1].equals("")) {
88  System.out.println("GitHub Password Cleartext:");
89  creds[1] = buf.readLine();
90  if (creds[1].equals("")) {
91  System.out.println("No password, using anynomous login");
92  }
93  }
94  } catch (Exception e) {
95  return null;
96  }
97  return creds;
98  }
99 
100  @Override
101  public String twoFactorAuthCodePrompt() {
102  System.out.print("Github 2 factor temp key: ");
103  // create a scanner so we can read the command-line input
104  BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
105  // TODO Auto-generated method stub
106  try {
107  return buf.readLine().trim();
108  } catch (IOException e) {
109  return null;
110  }
111  }
112  };
113  static {
114 
115  checkInternet();
116  try {
117  TinkConfig.register();
118  } catch (GeneralSecurityException e) {
119  // TODO Auto-generated catch block
120  e.printStackTrace();
121  }
122  }
123 
124  public static void checkInternet() {
125  try {
126  final URL url = new URL("http://github.com");
127  final URLConnection conn = url.openConnection();
128  conn.connect();
129  conn.getInputStream();
130  hasnetwork = true;
131  } catch (Exception e) {
132  // we assuming we have no access to the server and run off of the
133  // chached gists.
134  hasnetwork = false;
135  }
136  }
137 // private static File tokenfile = null;
138 // private static File usernamefile = null;
139 // private static File passfile = null;
140 // private static File keyfile = null;
141  private static File workspace = null;
142  private static String loginID = null;
143  private static String pw = null;
144  private static CredentialsProvider cp;// = new
145  private static GitHub github;
146  private static boolean hasnetwork;
147  private static boolean isLoggedIn = false;
148  private static boolean isAnonMode = false;
149  public static String getPassword() {
150  return pw;
151  }
152 
153  public static GitHub getGithub() {
154  return github;
155  }
156 
157  public static void setGithub(GitHub g) {
158  github = g;
159  }
160 
161  public static String getUsername() {
162  return getLoginID();
163  }
164 
165  public static synchronized void login() throws IOException {
166  checkInternet();
167  if (!hasnetwork)
168  return;
169  boolean b = !hasStoredCredentials();
170  boolean c = !isLoggedIn;
171  boolean c2 = c && b;
172  if (c2) {
173  String[] creds = getLoginManager().prompt(PasswordManager.getUsername());
174  if(creds!=null) {
175  setLoginID(creds[0]);
176  pw = creds[1];
177  }else {
178  //anaon mode
179  setupAnyonmous() ;
180  }
181 
182  } else {
183  try {
185  } catch (Exception e) {
186  throw new RuntimeException(e);
187  }
188  }
189 
190  try {
191  waitForLogin();
192  } catch (Exception e) {
193  // TODO Auto-generated catch block
194  e.printStackTrace();
195  }
196  }
197 
201  public static void waitForLogin() throws Exception {
202 
203  if (!hasnetwork)
204  return;
205  if (loggedIn())
206  return;
207  if (getLoginID() != null && pw != null) {
208 
210 
211  if (!isLoggedIn) {
212  System.out.println("\nERROR: Wrong Password!\n");
213  login();
214  }
215 
216  }
217  }
218 
219  private static void performLogin(String u, String p) throws Exception {
220 
221  github = null;
222  GitHub gh = null;
223  String token=null;
224 
225  if(getTokenfile().exists()) {
226  byte[] passEncrypt = Files.readAllBytes(Paths.get(getTokenfile().toURI()));
227  // 2. Get the primitive.
228  Aead aead = getKey().getPrimitive(Aead.class);
229  // ... or to decrypt a ciphertext.
230  try {
231  byte[] decrypted = aead.decrypt(passEncrypt, null);
232  token = new String(decrypted).trim();
233  } catch (GeneralSecurityException ex) {
234  ex.printStackTrace();
235  try {
236  logout();
237  } catch (IOException e) {
238  // TODO Auto-generated catch block
239  e.printStackTrace();
240  }
241  return;
242  }
243  }else {
244 // DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
245 // String timestamp = dateFormat.format(new Date());
246 //
247 // String string = "BowlerStudio-" + timestamp;
248 // try {
249 // GHAuthorization t=GitHub.connectUsingOAuth( p).createToken(listOfScopes, string, "",()->{
250 // return getLoginManager().twoFactorAuthCodePrompt();
251 // });
252 // token=t.getToken();
253 // }catch(org.kohsuke.github.HttpException wrongpass) {
254 //
255 // isLoggedIn=false;
256 // return;
257 // }
258  token=p;
259  }
260 
261  try {
262  if(hasNetwork()) {
263  gh = GitHub.connect(u, token);
264  try {
265  if (gh.getRateLimit().getRemaining() < 2) {
266  System.err.println("##Github Is Rate Limiting You## Disabling autoupdate");
267  }
268  }catch(java.lang.NoSuchMethodError er) {
269  er.printStackTrace();
270  }
271  u=gh.getMyself().getLogin();
272  }
273  } catch (Throwable e1) {
274  // TODO Auto-generated catch block
275  e1.printStackTrace();
276  logout();
277  return;
278  }
279  setLoginID(u);
280  setGithub(gh);
281  setCredentialProvider(new UsernamePasswordCredentialsProvider(u, token));
282 
283  try {
284  writeData(u, token);
285  writeToken(u, token);
286  System.out.println("\n\nSuccess Login " + u + "\n\n");
287  isLoggedIn = true;
288  setAnonMode(false);
289  } catch (Exception e) {
290  // TODO Auto-generated catch block
291  e.printStackTrace();
292  }
293 
294  }
295 
296  public static boolean loggedIn() {
297  return isLoggedIn;
298  }
299 
300  public static boolean hasStoredCredentials() {
301 
302  if (getUsernamefile() != null && getPassfile() != null) {
303  return getUsernamefile().exists() && getPassfile().exists();
304  }
305  return false;
306  }
307  public static boolean hasStoredToken() {
308  return getUsernamefile().exists() && getTokenfile().exists();
309  }
310  public static void logout() throws IOException {
311 
312  setGithub(null);
313  isLoggedIn = false;
314  isAnonMode = false;
315  if (getPassfile() != null)
316  if (getPassfile().exists())
317  getPassfile().delete();
318  if (getTokenfile() != null)
319  if (getTokenfile().exists())
320  getTokenfile().delete();
321  pw = null;
322  cp = null;
323  }
324 
325  public static GitHub setupAnyonmous() throws IOException {
326  System.err.println("Using anynomous login, autoupdate disabled");
327 
328  logout();
329  setGithub(GitHub.connectAnonymously());
330  setAnonMode(true);
331  return getGithub();
332  }
333 
335  if(loginManager==null)
336  if (GraphicsEnvironment.isHeadless()) {
338  } else {
340  }
341 
342  return loginManager;
343  }
344 
345  public static void setLoginManager(IGitHubLoginManager lm) {
346  loginManager = lm;
347  }
348 
349  public static void loadLoginData(File ws) throws Exception {
350  setWorkspace(ws);
351 
352  if (!getUsernamefile().exists()) {
353  // setUsernamefile(null);
354  } else {
355  List linesu = Files.readAllLines(Paths.get(getUsernamefile().toURI()), StandardCharsets.UTF_8);
356  setLoginID((String) linesu.get(0));
357  }
358  KeysetHandle keysetHandle = getKey();
359 // if (!getPassfile().exists())
360 // setPassfile(null);
361  if (hasStoredCredentials()) {
362 
363  byte[] passEncrypt = Files.readAllBytes(Paths.get(getPassfile().toURI()));
364  // 2. Get the primitive.
365  Aead aead = keysetHandle.getPrimitive(Aead.class);
366  // ... or to decrypt a ciphertext.
367  try {
368  byte[] decrypted = aead.decrypt(passEncrypt, null);
369  String cleartext = new String(decrypted).trim();
370  performLogin(getLoginID(), cleartext);
371  } catch (GeneralSecurityException ex) {
372  ex.printStackTrace();
373  logout();
374  }
375  }
376  }
377 
378 
379  private static KeysetHandle getKey() throws IOException {
380  KeysetHandle keysetHandle = null;
381  File keyfile = new File(getWorkspace().getAbsoluteFile() + "/loadData.json");
382  String keysetFilename = keyfile.getAbsolutePath();
383  if (!keyfile.exists()) {
384  // Generate the key material...
385  // System.err.println("Creating keyfile ");
386  try {
387  keysetHandle = KeysetHandle.generateNew(AeadKeyTemplates.AES128_GCM);
388  // and write it to a file.
389 
390  CleartextKeysetHandle.write(keysetHandle, JsonKeysetWriter.withFile(new File(keysetFilename)));
391  } catch (GeneralSecurityException e) {
392  // TODO Auto-generated catch block
393  e.printStackTrace();
394  }
395  } else {
396  // System.err.println("Loading keyfile ");
397  try {
398  keysetHandle = CleartextKeysetHandle.read(JsonKeysetReader.withFile(new File(keysetFilename)));
399  } catch (GeneralSecurityException e) {
400  // TODO Auto-generated catch block
401  e.printStackTrace();
402  }
403  }
404  return keysetHandle;
405  }
406 
407  private static void writeData(String user, String passcleartext) throws Exception {
408  setLoginID(user);
409  pw = passcleartext;
410  if (!getUsernamefile().exists())
411  getUsernamefile().createNewFile();
412  Files.write(Paths.get(getUsernamefile().toURI()), user.getBytes());
413  KeysetHandle keysetHandle = getKey();
414  if (!getPassfile().exists())
415  getPassfile().createNewFile();
416  // 2. Get the primitive.
417  Aead aead = keysetHandle.getPrimitive(Aead.class);
418  byte[] ciphertext = aead.encrypt(passcleartext.getBytes(), null);
419  Files.write(Paths.get(getPassfile().toURI()), ciphertext);
420 
421  }
422  private static void writeToken(String user, String passcleartext) throws Exception {
423  setLoginID(user);
424  pw = passcleartext;
425  if (!getUsernamefile().exists())
426  getUsernamefile().createNewFile();
427  Files.write(Paths.get(getUsernamefile().toURI()), user.getBytes());
428  KeysetHandle keysetHandle = getKey();
429  if (!getTokenfile().exists())
430  getTokenfile().createNewFile();
431  // 2. Get the primitive.
432  Aead aead = keysetHandle.getPrimitive(Aead.class);
433  byte[] ciphertext = aead.encrypt(passcleartext.getBytes(), null);
434  Files.write(Paths.get(getTokenfile().toURI()), ciphertext);
435 
436  }
437  public static CredentialsProvider getCredentialProvider() {
438  return cp;
439  }
440 
441  private static void setCredentialProvider(CredentialsProvider cp) {
443  }
444 
445  public static boolean hasNetwork() {
446  return hasnetwork;
447  }
448 
449  public static String getLoginID() {
450  return loginID;
451  }
452 
453  private static void setLoginID(String loginID) {
454  // new RuntimeException(loginID).printStackTrace();
456  }
457 
458  public static File getWorkspace() {
459  if (workspace == null)
460  workspace = new File(System.getProperty("user.home") + "/bowler-workspace/");
461  return workspace;
462  }
463 
464  public static void setWorkspace(File workspace) {
466  }
467 
468  public static File getUsernamefile() {
469  return new File(getWorkspace().getAbsoluteFile() + "/username.json");
470  }
471 
472  public static File getPassfile() {
473 
474  return new File(getWorkspace().getAbsoluteFile() + "/timestamp.json");
475  }
476 
477  public static File getTokenfile() {
478 
479  return new File(getWorkspace().getAbsoluteFile() + "/token.json");
480  }
481 
482  public static boolean isAnonMode() {
483  return isAnonMode;
484  }
485 
486  private static void setAnonMode(boolean isAnonMode) {
488  }
489 
490  public static List<String> getListOfScopes() {
491  return listOfScopes;
492  }
493 
494  public static void setListOfScopes(List<String> listOfScopes) {
496  }
497 }
static void writeData(String user, String passcleartext)
static void writeToken(String user, String passcleartext)
static void setListOfScopes(List< String > listOfScopes)
static void setCredentialProvider(CredentialsProvider cp)