示例#1
0
    def validate(self):
        super().validate()
        try:
            auth_client = AuthClient(
                username=self.username.data,
                password=self.password.data,
                **app.config['auth'],
            )
            response = auth_client.token.new(expiration=60 * 60 * 12)
            auth_client.set_token(response['token'])
            user = auth_client.users.get(response['metadata']['uuid'])
            user['password'] = self.password.data
            user['instance_uuid'] = response['xivo_uuid']
            session['user'] = user
        except HTTPError as e:
            if unauthorized(e):
                self.username.errors.append(USERNAME_PASSWORD_ERROR)
                self.password.errors.append(USERNAME_PASSWORD_ERROR)
                return False
            raise ValidationError(
                l_('Error with Wazo authentication server: %(error)s',
                   error=e.message))
        except requests.ConnectionError:
            raise ValidationError(
                l_('Wazo authentication server connection error'))

        self.user = UserUI(response['token'], response['auth_id'])
        self.user.set_tenant(response['metadata']['tenant_uuid'])
        self.user.set_instance_config(app.config)

        return True
示例#2
0
def migrate_tenants():
    config = _load_config()
    auth_client = AuthClient(**config['auth'])
    token = auth_client.token.new(expiration=5 * 60)['token']
    auth_client.set_token(token)
    confd = ConfdClient(token=token, **config['confd'])

    body = {
        'contexts': [
            {"context": context['name'], "tenant_uuid": context['tenant_uuid']}
            for context in confd.contexts.list(recurse=True)["items"]
        ]
    }

    with _migration_plugin(config['call_logd']):
        url = 'https://{host}:{port}/{version}/tenant-migration'.format(**config['call_logd'])
        result = requests.post(
            url,
            data=json.dumps(body),
            headers={'X-Auth-Token': token, 'Content-Type': 'application/json'},
            verify=False,
        )

        if result.status_code != 200:
            print(
                'call_logd tenant migration failed, status-code {}:\n'
                '{}\ncheck /var/log/wazo-call-logd.log for more info'
                .format(result.status_code, result.text)
            )
            sys.exit(2)
示例#3
0
def do_migration(config):
    with closing(psycopg2.connect(config['db_uri'])) as conn:
        tenants = _build_tenant_bodies_from_entities(conn.cursor())

    auth_client = AuthClient(**config['auth'])
    token = auth_client.token.new(expiration=36000)['token']
    auth_client.set_token(token)

    existing_tenants = _get_existing_tenants(auth_client)

    for tenant in tenants:
        if tenant['name'] in existing_tenants.keys():
            continue
        tenant = auth_client.tenants.new(**tenant)

        existing_tenants[tenant['name']] = tenant['uuid']

    with closing(psycopg2.connect(config['db_uri'])) as conn:
        cursor = conn.cursor()
        for name, tenant_uuid in existing_tenants.items():
            if not name:
                # wazo-auth allow tenants without names but those do not map to entities
                continue

            _upsert_tenant(cursor, tenant_uuid)
            conn.commit()
            _update_entity_tenant_uuid(cursor, name, tenant_uuid)
            conn.commit()

    auth_client.token.revoke(token)
示例#4
0
def migrate_tenants():
    config = _load_config()
    auth_client = AuthClient(**config['auth'])
    token = auth_client.token.new('wazo_user', expiration=5 * 60)['token']
    auth_client.set_token(token)

    body = [
        {"owner_user_uuid": user['uuid'], "owner_tenant_uuid": user['tenant_uuid']}
        for user in auth_client.users.list(recurse=True)["items"]
    ]

    with _migration_plugin(config['webhookd']):
        url = 'https://{host}:{port}/{version}/tenant-migration'.format(**config['webhookd'])
        result = requests.post(
            url,
            data=json.dumps(body),
            headers={'X-Auth-Token': token, 'Content-Type': 'application/json'},
            verify=False,
        )

        if result.status_code != 200:
            print(
                'webhookd tenant migration failed, status-code {}:\n'
                '{}\ncheck /var/log/wazo-webhookd.log for more info'
                .format(result.status_code, result.text)
            )
            sys.exit(2)
示例#5
0
def migrate_tenants():
    config = _load_config()
    auth_client = AuthClient(**config['auth'])
    token = auth_client.token.new('wazo_user', expiration=5 * 60)['token']
    auth_client.set_token(token)

    auth_tenants = auth_client.tenants.list()
    body = [{
        'uuid': t['uuid'],
        'name': t['name']
    } for t in auth_tenants['items']]

    with _migration_plugin(config['dird']):
        url = 'https://{host}:{port}/{version}/phonebook_move_tenant'.format(
            **config['dird'])
        result = requests.post(
            url,
            data=json.dumps(body),
            headers={
                'X-Auth-Token': token,
                'Content-Type': 'application/json'
            },
            verify=False,
        )

        if result.status_code != 200:
            print(
                'dird tenant migration failed, check /var/log/wazo-dird.log for more info'
            )
            sys.exit(2)
示例#6
0
class WazoAuthKeys(App):

    DEFAULT_VERBOSE_LEVEL = 0

    def __init__(self):
        super().__init__(
            description='A wrapper to wazo-auth-cli to manage internal users',
            command_manager=CommandManager('wazo_auth_keys.commands'),
            version='1.0.0',
        )
        self._token = None
        self._client = None

    def build_option_parser(self, *args, **kwargs):
        parser = super().build_option_parser(*args, **kwargs)
        parser.add_argument(
            '--wazo-auth-cli-config',
            default=os.getenv('WAZO_AUTH_CLI_CONFIG',
                              '/root/.config/wazo-auth-cli'),
            help=
            'Extra configuration directory to override the wazo-auth-cli configuration',
        )
        parser.add_argument(
            '--base-dir',
            default='/var/lib/wazo-auth-keys',
            help='The base directory of the file keys',
        )
        parser.add_argument(
            '--config',
            default='/etc/wazo-auth-keys/config.yml',
            help='The wazo-auth-keys configuration file',
        )
        return parser

    @property
    def client(self):
        if not self._client:
            self._client = Client(**self._auth_config)

        if not self._token:
            self._token = self._client.token.new('wazo_user',
                                                 expiration=600)['token']

        self._client.set_token(self._token)
        return self._client

    def initialize_app(self, argv):
        self.LOG.debug('wazo-auth-keys')
        self.LOG.debug('options=%s', self.options)

        conf = config.build(self.options)
        self.LOG.debug('Starting with config: %s', conf)

        self.LOG.debug('client args: %s', conf['auth'])
        self._auth_config = dict(conf['auth'])

        with open(self.options.config, 'r') as f:
            self.services = yaml.safe_load(f)
        self.file_manager = FileManager(self, self.options.base_dir)
示例#7
0
 def setUp(self):
     super().setUp()
     self.docker_exec(['wazo-auth-bootstrap'])
     self.key = self.docker_exec(['cat', '/var/lib/wazo-auth/init.key'
                                  ]).decode('utf-8')
     self.client = Client(self.auth_host,
                          port=self.auth_port,
                          verify_certificate=False)
示例#8
0
def main():
    args = parse_args()
    verify_certificate = _extract_verify_certificate(args.verify_certificate)

    password = os.getenv('PORTAL_PASSWORD', None)
    if not password:
        password = getpass()

    kwargs = {}
    if args.timeout:
        kwargs['timeout'] = args.timeout

    auth_client = AuthClient(args.host,
                             port=443,
                             prefix='/api/auth',
                             verify_certificate=verify_certificate,
                             username=args.username,
                             password=password,
                             **kwargs)
    token = auth_client.token.new()['token']
    auth_client.set_token(token)

    confd_client = ConfdClient(args.host,
                               port=443,
                               prefix='/api/confd',
                               verify_certificate=verify_certificate,
                               token=token,
                               **kwargs)
    rcl = []
    if args.rcl:
        rcl = detect_desync_rcl(auth_client, confd_client)

    users = []
    if args.users:
        users = detect_desync_users(auth_client, confd_client)

    if args.delete_orphan_users:
        delete_desync_users(confd_client, users)

    if not rcl and not users:
        sys.exit(0)

    if args.output:
        output_file = open(args.output, "w")
    else:
        output_file = sys.stdout

    fieldnames = ['uuid', 'type', 'name']
    writer = csv.DictWriter(output_file, fieldnames=fieldnames)
    writer.writeheader()
    for row in rcl + users:
        writer.writerow(row)

    if args.output:
        output_file.close()

    sys.exit(1)
示例#9
0
 def get_auth(cls, config):
     auth_config = dict(config['auth'])
     # FIXME(sileht): Keep the certificate
     auth_config['verify_certificate'] = False
     auth = AuthClient(**auth_config)
     token = auth.token.new('wazo_user', expiration=3600)
     auth.set_token(token["token"])
     auth.username = None
     auth.password = None
     return auth
示例#10
0
    def client(self):
        if not self._client:
            self._client = Client(**self._auth_config)

        if not self._token:
            self._token = self._client.token.new('wazo_user',
                                                 expiration=600)['token']

        self._client.set_token(self._token)
        return self._client
示例#11
0
 def load_token(token):
     try:
         response = AuthClient(**auth_config).token.get(token)
     except HTTPError:
         return None
     except requests.ConnectionError:
         logger.warning('Wazo authentication server connection error')
         return None
     token = response.get('token')
     if not token:
         return None
     return UserUI(token, response.get('auth_id'))
示例#12
0
def _auto_create_config():
    config = _load_config()
    auth_client = AuthClient(**config['auth'])
    token = auth_client.token.new('wazo_user', expiration=36000)['token']
    auth_client.set_token(token)
    confd_client = ConfdClient(token=token, **config['confd'])

    tenants = auth_client.tenants.list()['items']

    base_url = 'https://{host}:{port}/{version}'.format(**config['dird'])
    profiles_url = '{}/profiles'.format(base_url)
    conference_url = '{}/backends/conference/sources'.format(base_url)
    headers = {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'X-Auth-Token': token,
    }
    for tenant in tenants:
        name = tenant['name']
        if name == 'master':
            continue

        headers['Wazo-Tenant'] = tenant['uuid']

        conference_body = dict(name='auto_conference_{}'.format(name),
                               **CONFERENCE_SOURCE_BODY)
        conference = requests.post(
            conference_url,
            headers=headers,
            json=conference_body,
            verify=config['dird']['verify_certificate'],
        ).json()

        response = requests.get(
            profiles_url,
            headers={
                'Accept': 'application/json',
                'X-Auth-Token': token,
                'Wazo-Tenant': tenant['uuid'],
            },
            verify=config['dird']['verify_certificate'],
        ).json()

        for profile in response['items']:
            profile['services']['lookup']['sources'].append(conference)
            profile['services']['favorites']['sources'].append(conference)
            requests.put(
                '{}/{}'.format(profiles_url, profile['uuid']),
                json=profile,
                headers=headers,
                verify=config['dird']['verify_certificate'],
            )
示例#13
0
def _get_tenants_infos(tenants):
    config = _load_config()
    auth_client = AuthClient(**config['auth'])
    token = auth_client.token.new('wazo_user', expiration=36000)['token']
    auth_client.set_token(token)
    tenant_infos = {}
    for tenant in tenants:
        try:
            tenant_infos[tenant] = auth_client.tenants.get(tenant)
        except requests.HTTPError as e:
            print('Error while getting tenant {}: {}'.format(tenant, e))

    return tenant_infos
示例#14
0
def main(tenant_uuid):
    config = load_config()

    auth_client = AuthClient(**config['auth'])
    auth_client.set_tenant(tenant_uuid)
    token_data = auth_client.token.new(expiration=300)
    confd_client = ConfdClient(token=token_data['token'], **config['confd'])
    confd_client.set_tenant(tenant_uuid)

    endpoints_to_update = list_broken_endpoints(confd_client)
    print('updating', len(endpoints_to_update), 'endpoints')
    for endpoint_uuid in endpoints_to_update:
        print('.', end='')
        fix_endpoint(confd_client, endpoint_uuid)
    print('done')
示例#15
0
    def setUpClass(cls):
        super().setUpClass()
        port = cls.service_port(9497, 'auth')
        key = cls.docker_exec(['cat',
                               '/var/lib/wazo-auth/init.key']).decode('utf-8')
        url = 'https://localhost:{}/0.1/init'.format(port)
        headers = {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        }
        body = {'key': key, 'username': cls.username, 'password': cls.password}
        response = requests.post(url, json=body, headers=headers, verify=False)
        response.raise_for_status()

        cls.client = Client(
            'localhost',
            port=port,
            verify_certificate=False,
            username=cls.username,
            password=cls.password,
        )
        token_data = cls.client.token.new(backend='wazo_user', expiration=7200)
        cls.admin_user_uuid = token_data['metadata']['uuid']
        cls.client.set_token(token_data['token'])

        cls.top_tenant_uuid = cls.get_top_tenant()['uuid']
示例#16
0
    def setUpClass(cls):
        super().setUpClass()

        database = cls.new_db_client()
        until.true(database.is_up,
                   timeout=5,
                   message='Postgres did not come back up')
        bootstrap.create_initial_user(
            database.uri,
            cls.username,
            cls.password,
            bootstrap.PURPOSE,
            bootstrap.DEFAULT_POLICY_NAME,
        )

        port = cls.service_port(9497, 'auth')
        cls.client = Client(
            'localhost',
            port=port,
            prefix=None,
            https=False,
            username=cls.username,
            password=cls.password,
        )
        token_data = cls.client.token.new(backend='wazo_user', expiration=7200)
        cls.admin_user_uuid = token_data['metadata']['uuid']
        cls.client.set_token(token_data['token'])

        cls.top_tenant_uuid = cls.get_top_tenant()['uuid']
示例#17
0
    def client(self):
        if not (self._auth_config or self._auth_client):
            raise RuntimeError('AuthVerifier is not configured')

        if not self._auth_client:
            self._auth_client = Client(**self._auth_config)
        return self._auth_client
示例#18
0
def _import_wazo_user(users):
    config = _load_config()
    auth_client = AuthClient(**config['auth'])
    token = auth_client.token.new(expiration=36000)['token']
    auth_client.set_token(token)

    with closing(psycopg2.connect(config['db_uri'])) as conn:
        cursor = conn.cursor()
        entity_to_tenant_map = _build_entity_tenant_map(cursor)

    print('migrating users to wazo-auth', end='', flush=True)
    for user in users:
        _create_user(auth_client, entity_to_tenant_map, user)
        print('.', end='', flush=True)
    print('\ndone')

    auth_client.token.revoke(token)
示例#19
0
    def new_auth_client(cls, username=None, password=None):
        kwargs = {'port': cls.auth_port, 'prefix': '', 'https': False}

        if username and password:
            kwargs['username'] = username
            kwargs['password'] = password

        return Client(cls.auth_host, **kwargs)
示例#20
0
def _import_wazo_user(users):
    config = _load_config()
    auth_client = AuthClient(**config['auth'])
    token = auth_client.token.new('wazo_user', expiration=36000)['token']
    auth_client.set_token(token)

    with closing(psycopg2.connect(config['db_uri'])) as conn:
        cursor = conn.cursor()
        tenant_uuid = _find_older_tenant_uuid(cursor)

    print('migrating services access to wazo-auth', end='', flush=True)
    for user in users:
        _create_user(auth_client, tenant_uuid, user)
        print('.', end='', flush=True)
    print('\ndone')

    auth_client.token.revoke(token)
示例#21
0
    def new_auth_client(cls, username=None, password=None):
        kwargs = {'port': cls.auth_port, 'verify_certificate': False}

        if username and password:
            kwargs['username'] = username
            kwargs['password'] = password

        return Client(cls.auth_host, **kwargs)
示例#22
0
    def get_visible_tenants(self, tenant):
        token = request.headers['X-Auth-Token']
        auth_client = AuthClient(**self.auth_config)
        auth_client.set_token(token)

        try:
            visible_tenants = auth_client.tenants.list(
                tenant_uuid=tenant)['items']
        except HTTPError as e:
            response = getattr(e, 'response', None)
            status_code = getattr(response, 'status_code', None)
            if status_code == 401:
                logger.warning(
                    'a user is doing multi-tenant queries without the tenant list ACL'
                )
                return [tenant]
            raise

        return [tenant['uuid'] for tenant in visible_tenants]
def test_csv_import():
    auth_client = AuthClient(constants.HOST,
                             verify_certificate=False,
                             username='******',
                             password='******')
    dird_client = DirdClient(constants.HOST,
                             https=True,
                             verify_certificate=False,
                             timeout=MAX_TIME)

    token_data = auth_client.token.new(expiration=300)
    token = token_data['token']
    auth_client.set_token(token)

    try:
        auth_client.users.new(
            username=USERNAME,
            password=PASSWORD,
            tenant_uuid=token_data['metadata']['tenant_uuid'],
        )
    except requests.HTTPError as e:
        if e.response.status_code == 409:
            pass
        else:
            raise

    user_auth_client = AuthClient(
        constants.HOST,
        verify_certificate=False,
        username=USERNAME,
        password=PASSWORD,
    )
    token = user_auth_client.token.new('wazo_user', expiration=300)['token']

    result, time_to_complete = upload_csv(dird_client, token)

    assert 'created' in result, 'The result does not contain created contacts'
    assert len(result['created']
               ) == 1000, 'expected 1000 created contacts: {}'.format(
                   len(result['created']))
    assert time_to_complete < MAX_TIME, 'The import took too long {}s > {}s'.format(
        time_to_complete, MAX_TIME)
示例#24
0
    def client(self):
        if not self._auth_client:
            self._auth_client = Auth(**self._auth_config)

        if not self._current_token:
            self._backend = self._auth_config.pop('backend',
                                                  None) or self._backend
            self._auth_client = Auth(**self._auth_config)
            args = {'expiration': 3600}
            if self._backend:
                args['backend'] = self._backend
            token_data = self._auth_client.token.new(**args)
            self._current_token = token_data['token']

        self._auth_client.set_token(self._current_token)

        self._client = Amid(**self._amid_config)
        self._client.set_token(self._current_token)

        return self._client
def migrate_new_status():
    config = _load_config()
    _wait_for_provd(config['provd'])

    auth_client = AuthClient(**config['auth'])
    token = auth_client.token.new('wazo_user', expiration=5 * 60)
    auth_client.set_token(token['token'])

    master_tenant_uuid = token['metadata']['tenant_uuid']

    # Migrate devices
    for dir_entry in os.scandir(PROVD_JSONDB_DEVICES_DIR):
        device_id = dir_entry.name
        try:
            _migrate_device(device_id, master_tenant_uuid)
        except json.JSONDecodeError:
            print(device_id, 'is not a valid JSON file. Skipping.')
            continue

    subprocess.run(['systemctl', 'restart', 'xivo-provd'])
示例#26
0
 def test_that_the_email_can_be_used_to_get_a_token(self, u1):
     client = Client(
         'localhost',
         port=self.auth_port,
         prefix=None,
         https=False,
         username='******',
         password='******',
     )
     token_data = client.token.new(backend='wazo_user', expiration=1)
     assert_that(token_data, has_entries(token=not_(None)))
示例#27
0
    def make_auth_client(cls, username=None, password=None):
        try:
            port = cls.service_port(9497, service_name='auth')
        except (NoSuchService, NoSuchPort):
            return WrongClient('auth')
        kwargs = {'port': port, 'prefix': '', 'https': False}

        if username and password:
            kwargs['username'] = username
            kwargs['password'] = password

        return Client(cls.auth_host, **kwargs)
示例#28
0
def main():
    config = _load_config()

    auth_client = AuthClient(**config['auth'])
    token = auth_client.token.new('wazo_user', expiration=5 * 60)
    auth_client.set_token(token['token'])

    master_tenant_uuid = token['metadata']['tenant_uuid']
    all_tenants = [
        tenant['uuid'] for tenant in auth_client.tenants.list()['items']
    ]

    for dir_entry in os.scandir(PROVD_JSONDB_DEVICES_DIR):
        device_id = dir_entry.name
        try:
            _change_device_tenant_if_orphan(device_id, master_tenant_uuid,
                                            all_tenants)
        except json.JSONDecodeError:
            print(device_id, 'is not a valid JSON file. Skipping.')
            continue

    subprocess.run(['systemctl', 'restart', 'wazo-provd'])
示例#29
0
def migrate_tenants():
    config = _load_config()
    _wait_for_provd(config['provd'])

    auth_client = AuthClient(**config['auth'])
    token = auth_client.token.new('wazo_user', expiration=5*60)
    auth_client.set_token(token['token'])
    confd = ConfdClient(token=token['token'], **config['confd'])

    master_tenant_uuid = token['metadata']['tenant_uuid']

    # Migrate associated devices
    devices_migrated = []
    lines = confd.lines.list(recurse=True)['items']
    for line in lines:
        device_id = line['device_id']

        if device_id and device_id not in devices_migrated:
            try:
                _migrate_device(device_id, line['tenant_uuid'])
            except json.JSONDecodeError:
                print(device_id, 'is not a valid JSON file. Skipping.')
                continue
            except IOError as e:
                print('Skipping device "{}": {}'.format(device_id, e))
                continue
            devices_migrated.append(device_id)

    # Migrate autoprov devices
    for dir_entry in os.scandir(PROVD_JSONDB_DEVICES_DIR):
        device_id = dir_entry.name
        if device_id not in devices_migrated:
            try:
                _migrate_device(device_id, master_tenant_uuid)
            except json.JSONDecodeError:
                print(device_id, 'is not a valid JSON file. Skipping.')
                continue

    subprocess.run(['systemctl', 'restart', 'xivo-provd'])
示例#30
0
class TestInit(BaseTestCase):

    asset = 'base'

    def setUp(self):
        super().setUp()
        self.docker_exec(['wazo-auth-bootstrap'])
        self.key = self.docker_exec(['cat', '/var/lib/wazo-auth/init.key'
                                     ]).decode('utf-8')
        self.client = Client(self.auth_host,
                             port=self.auth_port,
                             verify_certificate=False)

    def test_post(self):
        body = {'username': '******', 'password': '******', 'key': INVALID_KEY}
        assert_http_error(401, self.client.init.run, **body)
        assert_http_error(400, self.client.init.run,
                          **copy_without(body, 'username'))
        assert_http_error(400, self.client.init.run,
                          **copy_without(body, 'password'))
        assert_http_error(400, self.client.init.run,
                          **copy_without(body, 'key'))

        result = self.client.init.run(username='******',
                                      password='******',
                                      key=self.key)
        assert_that(result,
                    has_entries(uuid=ANY_UUID, emails=empty(), username='******'))

        token_data = self._post_token('foo', 'bar', expiration=10)
        self.client.set_token(token_data['token'])

        user_tenants = self.client.users.get_tenants(result['uuid'])
        assert_that(
            user_tenants,
            has_entries(items=contains(self.get_top_tenant()), total=1))

    def get_top_tenant(self):
        return self.client.tenants.list(name='master')['items'][0]