def test_auth_token(self): auth = api.Authenticator(TEST_REMOTE) token = auth.get_auth_token(USER_EMAIL, USER_PASSWORD) assert len(token) > 0 with pytest.raises(exceptions.UnauthorizedException): token = auth.get_auth_token(USER_EMAIL, 'BadPassword')
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 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 refresh_token(self, username, login_password): server_url = self.creds.get_server_url(username) stored_session = self.creds.get_etebase(username) if stored_session is not None: etebase = local_cache.Etebase(username, stored_session, server_url).etebase etebase.fetch_token() self.creds.set_etebase(username, etebase.save(None), server_url) else: _, cipher_key = self.creds.get(username) if cipher_key is None: raise RuntimeError("User not found in etesync-dav") auth_token = api.Authenticator(server_url).get_auth_token( username, login_password) self.creds.set(username, auth_token, cipher_key, server_url) self.creds.save()
def login(): if logged_in(): return redirect(url_for('account_list')) errors = None form = LoginForm(request.form) if form.validate_on_submit(): try: api.Authenticator(ETESYNC_URL).get_auth_token(form.username.data, form.login_password.data) login_user(form.username.data) return redirect(url_for('account_list')) except Exception as e: errors = str(e) else: errors = form.errors return render_template('login.html', form=form, errors=errors)
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 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():
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)