def __init__(self, email, secrets_dir, server_url=None, db_path=None): if not has_etesync: raise exceptions.UserError('Dependencies for etesync are not ' 'installed.') server_url = server_url or etesync.API_URL self.email = email self.secrets_dir = os.path.join(secrets_dir, email + '/') self._auth_token_path = os.path.join(self.secrets_dir, 'auth_token') self._key_path = os.path.join(self.secrets_dir, 'key') auth_token = self._get_auth_token() if not auth_token: password = click.prompt('Enter service password for {}'.format( self.email), hide_input=True) auth_token = etesync.Authenticator(server_url) \ .get_auth_token(self.email, password) self._set_auth_token(auth_token) self._db_path = db_path or os.path.join(self.secrets_dir, 'db.sqlite') self.etesync = etesync.EteSync(email, auth_token, remote=server_url, db_path=self._db_path) key = self._get_key() if not key: password = click.prompt('Enter key password', hide_input=True) click.echo('Deriving key for {}'.format(self.email)) self.etesync.derive_key(password) self._set_key(self.etesync.cipher_key) else: self.etesync.cipher_key = key
def __init__(self, email, userPassword, remoteUrl, uid, authToken, cipher_key=None, silent=True): """Initialize Parameters ---------- email : etesync username(email) userPassword : etesync encryption password remoteUrl : url of etesync server uid : uid of calendar authToken : authentication token for etesync server """ self.etesync = api.EteSync(email, authToken, remote=remoteUrl) if cipher_key: self.etesync.cipher_key = cipher_key else: self.etesync.derive_key(userPassword) # needs to be done once on any machine # else the get on the next line fails silent or print("Syncing with server. Please wait") self.etesync.sync() silent or print("Syncing completed.") self.journal = self.etesync.get(uid) self.calendar = self.journal.collection
def add(self, username, login_password, encryption_password): exists = self.validate_username(username) if exists: raise RuntimeError( "User already exists. Delete first if you'd like to override settings." ) print("Fetching auth token") auth_token = api.Authenticator(self.remote_url).get_auth_token( username, login_password) print("Deriving password") etesync = api.EteSync(username, auth_token, remote=self.remote_url, db_path=':memory:') cipher_key = etesync.derive_key(encryption_password) print("Saving config") generated_password = self._generate_pasword() self.htpasswd.set(username, generated_password) self.creds.set(username, auth_token, cipher_key) self.htpasswd.save() self.creds.save() return self.get(username)
def test_collection_shared(self, etesync): from etesync import service, crypto a = api.Calendar.create(etesync, get_random_uid(self), {'displayName': 'fööböö'}) a.save() ev = api.Event.create(a, ('BEGIN:VCALENDAR\r\n' 'BEGIN:VEVENT\r\n' 'UID:test @ foo ät bar град сатану\r\n' 'SUMMARY:FÖÖBÖÖ\r\n' 'END:VEVENT\r\n' 'END:VCALENDAR\r\n')) ev.save() journal_manager = service.JournalManager(etesync.remote, etesync.auth_token) etesync.sync() key_pair = crypto.AsymmetricCryptoManager.generate_key_pair() asymmetric_crypto_manager = crypto.AsymmetricCryptoManager(key_pair) # FIXME: Hack, shouldn't calculate it here cipher_key = hmac256(a.journal.uid.encode(), etesync.cipher_key) encrypted_key = asymmetric_crypto_manager.encrypt( key_pair.public_key, cipher_key) member = service.Member(USER2_EMAIL, encrypted_key) # Second user auth = api.Authenticator(TEST_REMOTE) token = auth.get_auth_token(USER2_EMAIL, USER_PASSWORD) etesync2 = api.EteSync(USER2_EMAIL, token, remote=TEST_REMOTE, db_path=TEST_DB) headers = {'Authorization': 'Token ' + etesync2.auth_token} response = requests.post(TEST_REMOTE + 'reset/', headers=headers, allow_redirects=False) assert response.status_code == 200 journal_manager.member_add(a.journal._cache_obj, member) info_manager = service.UserInfoManager(etesync2.remote, etesync2.auth_token) crypto_manager = crypto.CryptoManager(crypto.CURRENT_VERSION, etesync2.cipher_key, b"userInfo") user_info = service.RawUserInfo(crypto_manager, USER2_EMAIL, key_pair.public_key) user_info.update(key_pair.private_key) user_info.verify() info_manager.add(user_info) etesync2.sync() journal_list = list(etesync2.list()) assert len(journal_list) == 1 assert journal_list[0].uid == a.journal.uid
def _get_etesync_for_user(cls, user): if user in cls._etesync_cache: return cls._etesync_cache[user] remote_url = cls.configuration.get(CONFIG_SECTION, "remote_url") db_path = cls.configuration.get(CONFIG_SECTION, "database_filename") creds_path = cls.configuration.get(CONFIG_SECTION, "credentials_filename") creds = Credentials(creds_path) auth_token, cipher_key = creds.get(user) etesync = api.EteSync(user, auth_token, remote=remote_url, db_path=db_path) etesync.cipher_key = cipher_key cls._etesync_cache[user] = etesync return etesync
def __init__(self, email, userPassword, remoteUrl, uid, authToken, cipher_key=None): """Initialize Parameters ---------- email : etesync username(email) userPassword : etesync encryption password remoteUrl : url of etesync server uid : uid of calendar authToken : authentication token for etesync server """ self.etesync = api.EteSync(email, authToken, remote=remoteUrl) if cipher_key: self.etesync.cipher_key = cipher_key else: self.etesync.derive_key(userPassword) self.journal = self.etesync.get(uid) self.calendar = self.journal.collection
def add(self, username, login_password, encryption_password): exists = self.validate_username(username) if exists: raise RuntimeError( "User already exists. Delete first if you'd like to override settings." ) print("Fetching auth token") auth_token = api.Authenticator(self.remote_url).get_auth_token( username, login_password) print("Deriving password") etesync = api.EteSync(username, auth_token, remote=self.remote_url, db_path=':memory:') cipher_key = etesync.derive_key(encryption_password) print("Saving config") generated_password = self._generate_pasword() self.htpasswd.set(username, generated_password) self.creds.set(username, auth_token, cipher_key) self.htpasswd.save() self.creds.save() print("Initializing account") try: with etesync_for_user(username) as (etesync, _): etesync.get_or_create_user_info(force_fetch=True) etesync.sync_journal_list() if not list(etesync.list()): collection_info = { "displayName": "Default", "description": "" } collection_name = hashlib.sha256( str(time.time()).encode()).hexdigest() inst = api.Calendar.create(etesync, collection_name, collection_info) inst.save() collection_name = hashlib.sha256( str(time.time()).encode()).hexdigest() inst = api.TaskList.create(etesync, collection_name, collection_info) inst.save() collection_name = hashlib.sha256( str(time.time()).encode()).hexdigest() inst = api.AddressBook.create(etesync, collection_name, collection_info) inst.save() etesync.sync_journal_list() except Exception as e: # Remove the username on error self.htpasswd.delete(username) self.creds.delete(username) self.htpasswd.save() self.creds.save() raise e return self.get(username)
def etesync(): return api.EteSync(USER_EMAIL, '', remote=TEST_REMOTE, db_path=TEST_DB)
def printEntry(entry): print("UID {}".format(entry.uid)) print("CONTENT {}".format(entry.content)) print() try: _, email, servicePassword, userPassword, remoteUrl = sys.argv except ValueError: sys.exit('Incorrect arguments!\nRequired: <email> <servicePassword> ' '<userPassword> <remoteUrl>') # Token should be saved intead of requested every time authToken = api.Authenticator(remoteUrl).get_auth_token(email, servicePassword) etesync = api.EteSync(email, authToken, remote=remoteUrl) print("Deriving key") # Very slow operation, should probably be securely cached etesync.derive_key(userPassword) print("Syncing") etesync.sync() print("Syncing done") if len(sys.argv) == 6: journal = etesync.get(sys.argv[5]) # Enable if you'd like to dump the journal if False: for entry in journal.list(): printEntry(entry)
def etesync(): auth = api.Authenticator(TEST_REMOTE) token = auth.get_auth_token(USER_EMAIL, USER_PASSWORD) return api.EteSync(USER_EMAIL, token, remote=TEST_REMOTE, db_path=TEST_DB)