Exemple #1
0
class DominionsScreen(Frame):
    def setup(self, **context) -> 'DominionsScreen':
        self.injector = context['injector']
        self.authark_informer = self.injector['StandardInformer']
        self.dominion = None
        return super().setup(**context) and self

    def build(self) -> None:
        self.modal = None
        self.title = 'Dominions'
        self.style(Color.SUCCESS())
        Button(self, content='\U00002795 Create',
               command=self.on_create).grid(0, 0)
        Spacer(self).grid(0, 1).weight(col=2)
        self.header = Listbox(self,
                              data=['ID', 'Name'],
                              orientation='horizontal').grid(1).span(col=3)

        self.body = Listbox(
            self,
            command=self.on_body,
        ).grid(3).span(col=3).weight(9)

    async def load(self) -> None:
        dominions = (await self.authark_informer.search(
            {"meta": {
                "model": "dominion",
                "domain": []
            }}))['data']
        self.body.setup(data=dominions, fields=['id', 'name'],
                        limit=10).connect()

    async def on_body(self, event: Event) -> None:
        self.dominion = getattr(event.target.parent, 'item', None)
        if self.dominion:
            self.modal = DominionDetailsModal(self,
                                              injector=self.injector,
                                              dominion=self.dominion,
                                              done_command=self.on_modal_done,
                                              proportion={
                                                  'height': 0.67,
                                                  'width': 0.67
                                              }).launch()

    async def on_create(self, event: Event) -> None:
        dominion = {'name': ''}
        self.modal = DominionDetailsModal(self,
                                          injector=self.injector,
                                          dominion=dominion,
                                          done_command=self.on_modal_done,
                                          proportion={
                                              'height': 0.67,
                                              'width': 0.67
                                          }).launch()

    async def on_modal_done(self, event: Event) -> None:
        self.remove(self.modal)
        self.modal = None
        await self.load()
        self.render()
Exemple #2
0
class CredentialsModal(Modal):
    def setup(self, **context) -> 'CredentialsModal':
        self.injector = context['injector']
        self.authark_informer = self.injector['StandardInformer']
        self.management_manager = self.injector['ManagementManager']
        self.user = context['user']
        return super().setup(**context) and self

    def build(self) -> None:
        super().build()
        frame = Frame(self, title='Credentials').title_style(
            Color.WARNING()).weight(4, 2)
        Listbox(frame, data=['ID', 'Type', 'Client', 'Value'],
                orientation='horizontal').grid(1).span(col=3)
        self.body = Listbox(frame).grid(3).span(col=3).weight(9)

    async def load(self) -> None:
        credentials = (await self.authark_informer.search({
            "meta": {
                "model": "credential",
                "domain": [('user_id', '=', self.user['id'])]
            }
        }))['data']
        self.body.setup(data=credentials, fields=[
            'id', 'type', 'client', 'value'], limit=10).connect()
Exemple #3
0
class TenantsModal(Modal):
    def setup(self, **context) -> 'TenantsModal':
        self.tenant_supplier = context['injector']['TenantInformer']
        return super().setup(**context) and self

    def build(self) -> None:
        super().build()
        self.header = Listbox(self,
                              data=['ID', 'Name'],
                              orientation='horizontal')
        self.body = Listbox(self, command=self.on_body).grid(1).weight(4)

    async def load(self) -> None:
        tenants = (await self.tenant_supplier.search_tenants(
            {"meta": {
                "domain": []
            }}))['data']
        self.body.setup(data=tenants, fields=['id', 'name']).connect()

    async def on_body(self, event: Event) -> None:
        item = event.target.parent.item
        await self.done(item)
Exemple #4
0
class DominionsModal(Modal):
    def setup(self, **context) -> 'DominionsModal':
        self.authark_informer = context['injector']['StandardInformer']
        return super().setup(**context) and self

    def build(self) -> None:
        super().build()
        self.header = Listbox(self, data=['ID', 'Name'],
                              orientation='horizontal')
        self.body = Listbox(self, command=self.on_body).grid(1).weight(4)

    async def load(self) -> None:
        dominions = (await self.authark_informer.search({
            "meta": {
                "model": "dominion",
                "domain": []
            }
        }))['data']
        self.body.setup(data=dominions, fields=['id', 'name']).connect()

    async def on_body(self, event: Event) -> None:
        item = event.target.parent.item
        await self.done(item)
Exemple #5
0
class RoleSelectionModal(Modal):
    def setup(self, **context) -> 'RoleSelectionModal':
        self.injector = context['injector']
        self.authark_informer = self.injector['StandardInformer']
        return super().setup(**context) and self

    def build(self) -> None:
        Listbox(self, data=['ID', 'Name', 'Dominion'],
                orientation='horizontal').grid(0)
        self.body = Listbox(self, command=self.on_body).grid(1).weight(9)

    async def load(self) -> None:
        roles = (await self.authark_informer.search({
            "meta": {
                "model": "role",
                "domain": []
            }
            }))['data']
        dominions_map = {
            dominion['id']: dominion for dominion
            in (await self.authark_informer.search({
                "meta": {
                    "model": "dominion",
                    "domain": [('id', 'in', [
                    role['dominion_id'] for role in roles])]
                }
            }))['data']}
        for role in roles:
            role['dominion_name'] = dominions_map[role['dominion_id']]['name']

        self.body.setup(data=roles,
                        fields=['id', 'name', 'dominion_name']).connect()

    async def on_body(self, event: Event) -> None:
        role = getattr(event.target.parent, 'item', None)
        if role:
            await self.done({'result': 'roles', 'role': role})
Exemple #6
0
class RestrictionsModal(Modal):
    def setup(self, **context) -> 'RestrictionsModal':
        self.injector = context['injector']
        self.authark_informer = self.injector['StandardInformer']
        self.security_manager = self.injector['SecurityManager']
        self.policy = context['policy']
        self.restriction = None
        return super().setup(**context) and self

    def build(self) -> None:
        super().build()
        self.modal = None
        frame = Frame(
            self, title=f'Restrictions for resource: {self.policy["resource"]}'
        ).title_style(Color.WARNING()).weight(4, 2)

        Button(frame, content='\U00002795 Create',
               command=self.on_create).grid(0, 0)
        Button(frame, content='\U00002716 Cancel',
               command=self.on_cancel).style(Color.WARNING()).grid(0, 1)

        Listbox(frame, data=['Sequence', 'Name', 'Target', 'Domain'],
                orientation='horizontal').grid(1).span(col=3)
        self.body = Listbox(frame, command=self.on_body
                            ).grid(3).span(col=3).weight(9)

    async def on_modal_done(self, event: Event) -> None:
        self.remove(self.modal)
        self.modal = None
        await self.load()
        self.render()

    async def load(self) -> None:
        roles = (await self.authark_informer.search({
            "meta": {
                "model": "restriction",
                "domain": [('policy_id', '=', self.policy['id'])]
            }
            }))['data']
        self.body.setup(data=roles, fields=[
            'sequence', 'name', 'target', 'domain'], limit=10).connect()

    async def on_body(self, event: Event) -> None:
        self.restriction = getattr(event.target.parent, 'item', None)
        if self.restriction:
            self.modal = RestrictionDetailsModal(
                self, injector=self.injector, restriction=self.restriction,
                done_command=self.on_modal_done,
                proportion={'height': 0.85, 'width': 0.90}).launch()

    async def on_create(self, event: Event) -> None:
        restriction = {
            'id': '', 'policy_id': self.policy['id'], 'sequence': 0,
            'name': '', 'target': self.policy['resource'], 'domain': ''}
        self.modal = RestrictionDetailsModal(
            self, injector=self.injector, restriction=restriction,
            done_command=self.on_modal_done,
            proportion={'height': 0.85, 'width': 0.90}).launch()

    async def on_cancel(self, event: Event) -> None:
        await self.done({'result': 'cancelled'})
Exemple #7
0
class PoliciesModal(Modal):
    def setup(self, **context) -> 'PoliciesModal':
        self.injector = context['injector']
        self.authark_informer = self.injector['StandardInformer']
        self.security_manager = self.injector['SecurityManager']
        self.role = context['role']
        self.policy = None
        return super().setup(**context) and self

    def build(self) -> None:
        super().build()
        self.modal = None
        frame = Frame(
            self, title=f'Policies for role: {self.role["name"]}').title_style(
                Color.DANGER()).weight(4, 2)

        Button(frame, content='\U00002795 Create',
               command=self.on_create).grid(0, 0)
        Button(frame, content='\U00002716 Cancel',
               command=self.on_cancel).style(Color.WARNING()).grid(0, 1)
        Listbox(frame,
                data=['Resource', 'Privilege', 'Active'],
                orientation='horizontal').grid(1).span(col=3)

        self.body = Listbox(frame,
                            command=self.on_body).grid(3).span(col=3).weight(9)

    async def on_modal_done(self, event: Event) -> None:
        self.remove(self.modal)
        self.modal = None
        if event.details['result'] == 'restrictions':
            self.modal = RestrictionsModal(
                self,
                injector=self.injector,
                policy=self.policy,
                proportion={
                    'height': 0.90,
                    'width': 0.95
                },
                done_command=self.on_modal_done).launch()
        else:
            await self.load()
        self.render()

    async def load(self) -> None:
        roles = (await self.authark_informer.search({
            "meta": {
                "model": "policy",
                "domain": [('role_id', '=', self.role['id'])]
            }
        }))['data']
        self.body.setup(data=roles,
                        fields=['resource', 'privilege', 'active'],
                        limit=10).connect()

    async def on_body(self, event: Event) -> None:
        self.policy = getattr(event.target.parent, 'item', None)
        if self.policy:
            self.modal = PolicyDetailsModal(self,
                                            injector=self.injector,
                                            policy=self.policy,
                                            done_command=self.on_modal_done,
                                            proportion={
                                                'height': 0.85,
                                                'width': 0.90
                                            }).launch()

    async def on_create(self, event: Event) -> None:
        policy = {
            'id': '',
            'resource': '',
            'active': False,
            'privilege': '',
            'role_id': self.role['id']
        }
        self.modal = PolicyDetailsModal(self,
                                        injector=self.injector,
                                        policy=policy,
                                        done_command=self.on_modal_done,
                                        proportion={
                                            'height': 0.85,
                                            'width': 0.90
                                        }).launch()

    async def on_cancel(self, event: Event) -> None:
        await self.done({'result': 'cancelled'})
Exemple #8
0
class RolesScreen(Frame):
    def setup(self, **context) -> 'RolesScreen':
        self.injector = context['injector']
        self.authark_informer = self.injector['StandardInformer']
        self.management_manager = self.injector['ManagementManager']
        self.dominion: Dict = {}
        self.role = None
        return super().setup(**context) and self

    def build(self) -> None:
        super().build()
        self.modal = None
        self.title = 'Roles'

        Button(self, content='\U00002795 Create',
               command=self.on_create).grid(0, 0)
        Button(self, content='Dominion',
               command=self.on_dominion).style(Color.SUCCESS()).grid(0, 1)
        self.dominion_label = Label(
            self, content=f'{self.dominion.get("name")}').grid(0, 2)
        Listbox(self, data=['Name', 'Description'],
                orientation='horizontal').grid(1).span(col=3)

        self.body = Listbox(
            self, command=self.on_body).grid(2).span(col=3).weight(9)

    async def on_modal_done(self, event: Event) -> None:
        self.remove(self.modal)
        self.modal = None
        if event.details['result'] == 'policies':
            self.modal = PoliciesModal(
                self, injector=self.injector,
                role=self.role,
                proportion={'height': 0.90, 'width': 0.95},
                done_command=self.on_modal_done).launch()
        elif event.details['result'] == 'users':
            self.modal = UsersSelectionModal(
                self, injector=self.injector,
                role=self.role,
                proportion={'height': 0.95, 'width': 0.95},
                done_command=self.on_modal_done).launch()
        else:
            await self.load()
        self.render()

    async def load(self) -> None:
        self.dominion = self.dominion or next(iter(
            (await self.authark_informer.search({
                "meta": {
                    "model": "dominion",
                    "domain": []
                }
            }))['data']), {'id': 'None'})
        roles = (await self.authark_informer.search({
            "meta": {
                "model": "role",
                "domain": [('dominion_id', '=', self.dominion.get('id'))]
            }
            }))['data']
        self.body.setup(
            data=roles,
            fields=['name', 'description'], limit=20).connect()
        self.dominion_label.setup(
            content=f'{self.dominion.get("name")}').render()

    async def on_body(self, event: Event) -> None:
        self.role = getattr(event.target.parent, 'item', None)
        if self.role:
            self.modal = RoleDetailsModal(
                self, injector=self.injector, role=self.role,
                done_command=self.on_modal_done,
                proportion={'height': 0.67, 'width': 0.80}).launch()

    async def on_dominion(self, event: Event) -> None:
        self.modal = DominionsModal(
            self, injector=self.injector,
            done_command=self.on_dominion_switch,
            proportion={'height': 0.60, 'width': 0.80}
        ).launch()

    async def on_dominion_switch(self, event: Event) -> None:
        self.dominion = event.details
        self.connect()

    async def on_create(self, event: Event) -> None:
        role = {'id': '', 'name': '', 'dominion_id': self.dominion.get('id'),
                'description': ''}
        self.modal = RoleDetailsModal(
            self, injector=self.injector, role=role,
            done_command=self.on_modal_done,
            proportion={'height': 0.70, 'width': 0.70}).launch()

    async def on_cancel(self, event: Event) -> None:
        await self.done({'result': 'cancelled'})
Exemple #9
0
class UsersSelectionModal(Modal):
    def setup(self, **context) -> 'RoleDetailsModal':
        self.injector = context['injector']
        self.authark_informer = self.injector['StandardInformer']
        self.management_manager = self.injector['ManagementManager']
        self.role = context['role']
        self.focused: Dict = {}
        self.available_domain: List = []
        self.chosen_domain: List = []
        return super().setup(**context) and self

    def build(self) -> None:
        super().build()
        self.modal = None

        available_frame = Frame(self, title='Available').weight(
            5, 4).grid(0, 0)
        self.available_search = Entry(
            available_frame, command=self.on_available_search).listen(
                'keydown', self.on_available_search, True).weight(
                    col=2).grid(0, 0)
        self.available_total = Label(
            available_frame, content='Total: 0').grid(0, 1)
        self.available = Listbox(
            available_frame, command=self.on_select).weight(
                9).span(col=2).grid(1)

        switchers = Frame(self).title_style(
            Color.SUCCESS()).style(border=[]).weight(5).grid(0, 1)

        Button(switchers, content='\U000025B6', command=self.on_choose).style(
            Color.SUCCESS(), border=[], template='{}').grid(0)
        Button(switchers, content='\U000025C0', command=self.on_clear).style(
            Color.SUCCESS(), border=[], template='{}').grid(1)
        Button(switchers, content='\U000023E9',
               command=self.on_choose_all).style(
            Color.SUCCESS(), border=[], template='{}').grid(2)
        Button(switchers, content='\U000023EA',
               command=self.on_clear_all).style(
            Color.SUCCESS(), border=[], template='{}').grid(3)

        chosen_frame = Frame(self, title='Chosen').weight(
            5, 4).grid(0, 2)
        self.chosen_search = Entry(chosen_frame).listen(
            'keydown', self.on_chosen_search, True).weight(col=2).grid(0, 0)
        self.chosen_total = Label(
            chosen_frame, content='Total: 0').grid(0, 1)
        self.chosen = Listbox(
            chosen_frame, command=self.on_select).weight(
                9).span(col=2).grid(1)

        actions = Frame(
            self, title='Actions').title_style(
                Color.WARNING()).grid(1).span(col=3)
        Label(actions, content=f'Role: {self.role["name"]}').grid(0, 2)
        Spacer(actions).grid(0, 3).weight(col=1)
        Button(actions, content='Save', command=self.on_save
               ).style(Color.SUCCESS()).grid(0, 4)
        Button(actions, content='Cancel', command=self.on_cancel
               ).style(Color.WARNING()).grid(0, 5)

    async def on_select(self, event: Event) -> None:
        item = getattr(event.target.parent, 'item', None)
        event.target.focus()
        self.focused = item if isinstance(item, dict) else {}

    async def on_available_search(self, event: Event) -> None:
        if event.key == '\n':
            event.stop = True
            text = self.available_search.text.strip()
            self.available.offset = 0
            self.available_domain = [] if not text else [
                '|',  ('name', 'ilike', f'%{text}%'),
                ('email', 'ilike', f'%{text}%')]
            await self.load()
            self.available_search.focus()

    async def on_chosen_search(self, event: Event) -> None:
        if event.key == '\n':
            event.stop = True
            text = self.chosen_search.text.strip()
            self.chosen.offset = 0
            self.chosen_domain = [] if not text else [
                '|',  ('name', 'ilike', f'%{text}%'),
                ('email', 'ilike', f'%{text}%')]
            await self.load()
            self.chosen_search.focus()

    async def load(self) -> None:
        current_user_ids = [ranking['user_id'] for ranking in
                            (await self.authark_informer.search({
                                "meta": {
                                    "model": "ranking",
                                    "domain": [
                                        ('role_id', '=', self.role['id'])]
                                }
                                }))['data']
                            ]
        available_users = (await self.authark_informer.search({
            "meta": {
                "model": "user",
                "domain": [
            '!', ('id', 'in', current_user_ids)] + self.available_domain
            }
        }))['data']
        chosen_users = (await self.authark_informer.search({
            "meta": {
                "model": "user",
                "domain": [
            ('id', 'in', current_user_ids)] + self.chosen_domain
            }
        }))['data']

        self.available.setup(data=available_users,
                             fields=['username', 'email'],
                             limit=20).connect()
        self.chosen.setup(data=chosen_users,
                          fields=['username', 'email'],
                          limit=20).connect()
        self._update_totals()

    async def on_choose(self, event: Event) -> None:
        self._switch(self.focused, self.available, self.chosen)
        self._update_totals()

    async def on_choose_all(self, event: Event) -> None:
        self.chosen.data = list(self.available.data + self.chosen.data)
        self.available.data = []
        self.chosen.connect()
        self.available.connect()
        self._update_totals()

    async def on_clear(self, event: Event) -> None:
        self._switch(self.focused, self.chosen, self.available)
        self._update_totals()

    async def on_clear_all(self, event: Event) -> None:
        self.available.data = list(self.available.data + self.chosen.data)
        self.chosen.data = []
        self.available.connect()
        self.chosen.connect()
        self._update_totals()

    def _update_totals(self) -> None:
        self.available_total.setup(
            content=f'Total: {len(self.available.data)}').render()
        self.chosen_total.setup(
            content=f'Total: {len(self.chosen.data)}').render()

    def _switch(self, item: Optional[Dict[str, Any]],
                source: Listbox, target: Listbox) -> None:
        if item and item in source.data:
            source.data.remove(item)
            source.connect()
        if item and item not in target.data:
            target.data.insert(0, item)
            target.connect()

    async def on_save(self, event: Event) -> None:
        removing_ranking_ids = [
            ranking['id'] for ranking in (await self.authark_informer.search({
                "meta": {
                    "model": "ranking",
                    "domain": [('role_id', '=', self.role['id']),
                            ('user_id', 'in', [user['id'] for user in
                                               self.available.data])]
                    }
                }))['data']
        ]
        await self.management_manager.deassign_role(removing_ranking_ids)
        adding_rankings = [{'role_id': self.role['id'], 'user_id': user['id']}
                           for user in self.chosen.data]
        await self.management_manager.assign_role({
            "meta": {},
            "data": adding_rankings
        })
        await self.done({'result': 'saved'})

    async def on_cancel(self, event: Event) -> None:
        await self.done({'result': 'cancelled'})
Exemple #10
0
class UsersScreen(Frame):
    def setup(self, **context) -> 'UsersScreen':
        self.injector = context['injector']
        self.authark_informer = self.injector['StandardInformer']
        self.user = None
        self.domain: List[Any] = []
        return super().setup(**context) and self

    def build(self) -> None:
        self.modal = None
        self.title = 'Users'
        self.style(Color.SUCCESS())
        Button(self, content='\U00002795 Create',
               command=self.on_create).grid(0, 0)
        Label(self, content='\U0001F50D Search:').grid(0, 1)
        self.search = Entry(self).grid(0, 2).style(
            border=[0]).weight(col=3)
        self.header = Listbox(
            self, data=['ID', 'Name', 'Email'],
            orientation='horizontal').grid(1).span(col=3)
        self.body = Listbox(
            self, command=self.on_body).grid(3).span(col=3).weight(9)
        self.search.listen('keydown', self.on_search, True)

    async def load(self) -> None:
        users = (await self.authark_informer.search({
            "meta": {
                "model": "user",
                "domain": self.domain
            }
        }))['data']
        self.body.setup(
            data=users, fields=['id', 'name', 'email'], limit=20).connect()

    async def on_body(self, event: Event) -> None:
        self.user = getattr(event.target.parent, 'item', None)
        if self.user:
            self.modal = UserDetailsModal(
                self, injector=self.injector, user=self.user,
                done_command=self.on_modal_done,
                proportion={'height': 0.90, 'width': 0.90}).launch()

    async def on_search(self, event: Event) -> None:
        if event.key == '\n':
            event.stop = True
            self.body.offset = 0
            text = self.search.text.strip()
            self.domain = [] if not text else [
                '|',  ('name', 'ilike', f'%{text}%'),
                ('email', 'ilike', f'%{text}%')]
            await self.load()
            self.search.focus()

    async def on_create(self, event: Event) -> None:
        user = {'name': '', 'username': '', 'email': '', 'attributes': {}}
        self.modal = UserDetailsModal(
            self, injector=self.injector, user=user,
            done_command=self.on_modal_done,
            proportion={'height': 0.90, 'width': 0.90}).launch()

    async def on_modal_done(self, event: Event) -> None:
        self.remove(self.modal)
        self.modal = None
        if event.details['result'] == 'roles':
            self.modal = RankingsModal(
                self, injector=self.injector,
                user=self.user,
                done_command=self.on_modal_done).launch()
        elif event.details['result'] == 'credentials':
            self.modal = CredentialsModal(
                self, injector=self.injector,
                user=self.user,
                done_command=self.on_modal_done).launch()
        else:
            await self.load()
        self.render()
        self.body.focus()
Exemple #11
0
class RankingsModal(Modal):
    def setup(self, **context) -> 'RankingsModal':
        self.injector = context['injector']
        self.authark_informer = self.injector['StandardInformer']
        self.management_manager = self.injector['ManagementManager']
        self.user = context['user']
        return super().setup(**context) and self

    def build(self) -> None:
        super().build()
        self.modal = None
        frame = Frame(self, title='Rankings').title_style(
            Color.WARNING()).weight(4, 2)
        Button(frame, content='\U00002795 Assign',
               command=self.on_assign).grid(0, 0)
        Label(frame, content='"Middle click" to Delete').grid(0, 1)
        self.header = Listbox(
            frame, data=['ID', 'Role', 'Dominion'],
            orientation='horizontal').grid(1).span(col=3)

        self.body = Listbox(frame, command=self.on_body).grid(
            3).span(col=3).weight(9)

    async def load(self) -> None:
        rankings = []
        for ranking, [role] in (await self.authark_informer.join({
                "meta": {
                    "model": "ranking",
                    "domain": [('user_id', '=', self.user['id'])],
                    "join": "role",
                    "link": "ranking"
                }
                }))['data']:
            [dominion] = (await self.authark_informer.search({
                "meta": {
                    "model": "dominion",
                    "domain": [('id', '=', role['dominion_id'])]
                }
            }))['data']
            ranking['role_name'] = role['name']
            ranking['dominion_name'] = dominion['name']
            rankings.append(ranking)

        self.body.setup(data=rankings, fields=[
            'id', 'role_name', 'dominion_name'], limit=10).connect()

    async def on_modal_done(self, event: Event) -> None:
        self.remove(self.modal)
        self.modal = None
        if event.details['result'] == 'roles':
            await self.assign_role(event.details['role'])
        else:
            await self.load()
        self.render()

    async def on_assign(self, event: Event) -> None:
        self.modal = RoleSelectionModal(
            self, injector=self.injector,
            done_command=self.on_modal_done,
            proportion={'height': 0.70, 'width': 0.70}).launch()

    async def assign_role(self, role_dict: Dict[str, str]) -> None:
        ranking_dict = {'user_id': self.user['id'], 'role_id': role_dict['id']}
        await self.management_manager.assign_role([ranking_dict])
        self.connect()

    async def on_body(self, event: Event) -> None:
        ranking = getattr(event.target.parent, 'item', None)
        if ranking and event.button == 2:
            event.stop = True
            await self.management_manager.deassign_role([ranking['id']])
            self.connect()