Пример #1
0
    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')
Пример #2
0
    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
Пример #3
0
    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)
Пример #4
0
    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
Пример #5
0
    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()
Пример #6
0
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)
Пример #7
0
    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)
Пример #8
0

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():
Пример #9
0
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)