from __future__ import print_function import pickle import os.path from googleapiclient.discovery import build from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request from email.mime.text import MIMEText import base64 from time import sleep import threading import logging import database def init_email_sending(): SCOPES = ['https://www.googleapis.com/auth/gmail.send'] creds = None try: if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES) creds = flow.run_console() with open('token.pickle', 'wb') as token: pickle.dump(creds, token) service = build('gmail', 'v1', credentials=creds) return True except Exception as e: print(e) return False def stop_history_watch(): SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'] creds = None try: if os.path.exists('history_token.pickle'): with open('history_token.pickle', 'rb') as token: creds = pickle.load(token) if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES) creds = flow.run_console() with open('history_token.pickle', 'wb') as token: pickle.dump(creds, token) service = build('gmail', 'v1', credentials=creds) results = service.users().stop(userId='me').execute() print(results) return True except Exception as e: print(e) return False def init_history_watch(): SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'] creds = None try: if os.path.exists('history_token.pickle'): with open('history_token.pickle', 'rb') as token: creds = pickle.load(token) if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES) creds = flow.run_console() with open('history_token.pickle', 'wb') as token: pickle.dump(creds, token) request = { 'labelIds': ['Label_4696745878389955477'], 'topicName': 'projects/trusat-256517/topics/TruSat' } service = build('gmail', 'v1', credentials=creds) results = service.users().labels().list(userId='me').execute() labels = results.get('labels', []) if not labels: print('No labels found.') else: print('Labels:') for label in labels: print(label['name']) print(label['id']) results = service.users().watch(userId='me', body=request).execute() print(results) return True except Exception as e: print(e) return False def create_message(sender, to, subject, message_text): message_text = 'Save this email: TruSat account recovery info for ' + to + '\n\n' + \ 'To log into TruSat, you\'ll need your password AND this secret code:\n\n' + message_text + \ '\n\nThis email is the only time we can send you this code. TruSat cannot reset your password for you. Please save this email forever and make a note of the password you used.\n\n' + \ 'Login here: trusat.org/login\n\n' + \ 'Why do we do it this way? Read more (trusat.org/faq)\n\n' + \ 'Questions? Please email: Help@Beta.TruSat.org' message = MIMEText(message_text) message['to'] = to message['from'] = sender message['subject'] = subject return {'raw': base64.urlsafe_b64encode(message.as_string().encode('utf-8'))} def send_message(service, user_id, message): message["raw"] = message["raw"].decode('utf-8') try: message = (service.users().messages().send(userId=user_id, body=message).execute()) return message except Exception as error: print('An error occurred: %s' % error) return False def send_email(to, message_text): SCOPES = ['https://www.googleapis.com/auth/gmail.send'] creds = None try: if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES) creds = flow.run_console() with open('token.pickle', 'wb') as token: pickle.dump(creds, token) service = build('gmail', 'v1', credentials=creds) message_to_send = create_message('kenan.oneal@consensys.net', to, 'TruSat - Save this email: Recovery Info', message_text) sent_message = send_message(service, 'me', message_to_send) if sent_message == False: return False return True except: return False def create_recovery_message(sender, to, subject, message_text): message_text = 'Please use the following link to verify your ownership of the following email ' + \ to + '\n\n' + message_text + '\nThis link will expire in 30 minutes.' + \ '\n\nIf you did not request recovery of your account please contact us at:\nHelp@Beta.TruSat.org\n' message = MIMEText(message_text) message['to'] = to message['from'] = sender message['subject'] = subject return {'raw': base64.urlsafe_b64encode(message.as_string().encode('utf-8'))} def send_recovery_email(to, message_text): SCOPES = ['https://www.googleapis.com/auth/gmail.send'] creds = None try: if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES) creds = flow.run_console() with open('token.pickle', 'wb') as token: pickle.dump(creds, token) service = build('gmail', 'v1', credentials=creds) message_to_send = create_recovery_message('kenan.oneal@consensys.net', to, 'TruSat - Recover Account', message_text) sent_message = send_message(service, 'me', message_to_send) if sent_message == False: return False return True except: return False def get_email_history(history_id): thread_to_use = threading.Thread(target=wait_for_email, args=(history_id,)) thread_to_use.start() return history_id def wait_for_email(history_id): sleep(600) SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'] creds = None if os.path.exists('history_token.pickle'): with open('history_token.pickle', 'rb') as token: creds = pickle.load(token) if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES) creds = flow.run_console() with open('history_token.pickle', 'wb') as token: pickle.dump(creds, token) service = build('gmail', 'v1', credentials=creds) CONFIG = os.path.abspath("../../trusat-config.yaml") db = database.Database(CONFIG) try: history = (service.users().history().list(userId='me', startHistoryId=history_id).execute()) changes = history['history'] if 'history' in history else [] try: change_id = [] messages = [] for i in changes: tmp_id = i['messages'][0]['id'] if 'messages' in i else '' if tmp_id != '': change_id.append(tmp_id) if len(change_id) != 0: for i in change_id: try: message = service.users().messages().get(userId='me', id=i).execute() for label in message['labelIds']: if label == 'Label_4696745878389955477': messages.append(message['snippet']) for j in message["payload"]["parts"]: if j["mimeType"] == "text/plain": email_body_base64 = j["body"]["data"] email_body = base64.urlsafe_b64decode(email_body_base64).decode('utf-8') body = email_body.replace('\r\n', '\n') (success, errors) = db.addObserverParsedIOD(body) print("SUCCESS") print(success) print("ERRORS") print(errors) for j in message["payload"]["headers"]: if j["name"] == "From": email_from_unparsed = j["value"] email_from = email_from_unparsed.split("\u003c")[1].split("\u003e")[0] elif j["name"] == "To": email_to_unparsed = j["value"] email_to = email_to_unparsed.split("\u003c")[1].split("\u003e")[0] elif j["name"] == "Date": email_timestamp = j["value"] except Exception as e: print(e) pass else: messages = [] except Exception as e: print(e) messages = None db.clean() return messages except Exception as e: print(e) db.clean() return []