Ejemplo n.º 1
0
class Settings(models.Model):
    class Meta:
        verbose_name = 'Configuração'
        verbose_name_plural = 'Configurações'

    fieldsets = (
        ('Configuração Geral', {
            'fields': (('initials', 'name'), ('logo', 'logo_pdf'),
                       ('icon', 'background'))
        }),
        ('Social', {
            'fields': (('twitter', 'facebook'), ('google', 'pinterest'),
                       ('linkedin', 'rss'))
        }),
        ('Direitos Autorais', {
            'fields': ('company', ('phone_1', 'phone_2'), 'address', 'email')
        }),
        ('Aparência', {
            'fields': ('default_color', )
        }),
        ('Servidor', {
            'fields': (('server_address', 'system_email_address'), )
        }),
        ('Versão', {
            'fields': ('version', )
        }),
    )

    # Application
    initials = models.CharField('Nome', default='Django+')
    name = models.CharField('Descrição', default='Django Plus')
    logo = models.ImageField('Logotipo',
                             upload_to='config',
                             null=True,
                             blank=True,
                             default='')
    logo_pdf = models.ImageField('Logotipo para PDF',
                                 upload_to='config',
                                 help_text='Imagem sem fundo transparente',
                                 null=True,
                                 blank=True,
                                 default='')
    icon = models.ImageField('Ícone',
                             upload_to='config',
                             null=True,
                             blank=True)
    background = models.ImageField('Background',
                                   upload_to='config',
                                   default='',
                                   blank=True)

    # Social params
    twitter = models.CharField('Twitter', null=True, blank=True)
    facebook = models.CharField('Facebook', null=True, blank=True)
    google = models.CharField('Google', null=True, blank=True)
    pinterest = models.CharField('pinterest', null=True, blank=True)
    linkedin = models.CharField('Linkedin', null=True, blank=True)
    rss = models.CharField('RSS', null=True, blank=True)

    # Company
    company = models.CharField('Empresa', null=True, blank=True)
    address = models.TextField('Endereço', null=True, blank=True)
    phone_1 = models.PhoneField('Telefone Principal', null=True, blank=True)
    phone_2 = models.PhoneField('Telefone Secundário', null=True, blank=True)
    email = models.CharField('E-mail', null=True, blank=True)

    # Server configuration
    version = models.CharField('Versão do Sistema', exclude=True)
    server_address = models.CharField('Endereço de Acesso',
                                      default='http://*****:*****@djangoplus.net')

    @staticmethod
    def default():
        from djangoplus.cache import loader
        if not loader.settings_instance:
            loader.settings_instance = Settings.objects.first()
        if not loader.settings_instance:
            settings = Settings()
            settings.initials = 'Sistema'
            settings.name = 'Sistema de gerenciamento online, responsivo e multiplataforma'
            settings.twitter = 'https://twitter.com/'
            settings.facebook = 'https://www.facebook.com/'
            settings.google = 'https://plus.google.com/'
            settings.pinterest = 'https://www.pinterest.com/'
            settings.linkedin = 'https://www.linkedin.com/'
            settings.rss = 'https://www.rss.com/'
            settings.company = ''
            settings.address = ''
            settings.phone_1 = ''
            settings.phone_2 = ''
            settings.email = ''
            settings.version = '1.0'
            settings.save()
            loader.settings_instance = settings
        return loader.settings_instance

    def save(self, *args, **kwargs):
        from djangoplus.cache import loader
        super(Settings, self).save(*args, **kwargs)
        loader.settings_instance = self
Ejemplo n.º 2
0
class User(AbstractBaseUser, PermissionsMixin):
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    name = models.CharField('Nome', max_length=30, blank=True, search=True)
    username = models.CharField('Login',
                                max_length=30,
                                unique=True,
                                search=True)
    email = models.CharField('E-mail', max_length=75, blank=True, default='')
    active = models.BooleanField(verbose_name='Ativo?',
                                 default=True,
                                 filter=True)
    photo = models.ImageField(upload_to='profiles',
                              null=True,
                              blank=True,
                              default='/static/images/user.png',
                              verbose_name='Foto',
                              exclude=True)

    permission_mapping = models.JsonField(
        verbose_name='Mapeamento de Permissão', exclude=True, display=False)
    objects = UserManager()

    fieldsets = (
        ('Identificação', {
            'fields': (('name', 'email'), ),
            'image': 'photo'
        }),
        ('Acesso', {
            'fields': (('username', 'is_superuser'), ('active', ))
        }),
        ('Funções', {
            'relations': ('role_set', )
        }),
        ('Mapeamento de Permissão', {
            'fields': ('permission_mapping', )
        }),
    )

    class Meta():
        verbose_name = 'Usuário'
        verbose_name_plural = 'Usuários'
        list_display = 'photo', 'username', 'name', 'groups'
        add_form = 'UserForm'
        can_admin = 'Gerenciador de Usuários'
        icon = 'fa-users'
        # list_template = 'image_cards.html'

    def __init__(self, *args, **kwargs):
        super(User, self).__init__(*args, **kwargs)

    def save(self, *args, **kwargs):
        if not self.password:
            if settings.DEBUG or 'test' in sys.argv:
                password = settings.DEFAULT_PASSWORD
            else:
                password = uuid.uuid4().get_hex()
            self.set_password(password)
        super(User, self).save(*args, **kwargs)

    def __str__(self):
        return self.name or self.username

    @action('Alterar Senha', input='ChangePasswordForm', inline=True)
    def change_password(self, new_password, confirm_password):
        self.set_password(new_password)
        self.save()

    @action('Enviar Convite de Acesso',
            inline=True,
            condition='email',
            category=None)
    def send_access_invitation(self):
        project_name = Settings.default().initials
        subject = 'Acesso ao Sistema - "{}"'.format(project_name)
        message = '''Você está cadastro no sistema <b>{}</b>.
            Para (re)definir sua senha de acesso, clique no botão abaixo.
        '''.format(project_name)
        actions = [('Acessar agora!',
                    '/admin/password/{}/{}/'.format(self.pk,
                                                    encrypt(self.password)))]
        send_mail(subject, message, self.email, actions=actions)

    def units(self, group_name=None):
        qs = self.role_set.all()
        if group_name:
            qs = qs.filter(group__name=group_name)
        return qs.values_list('units', flat=True)

    def in_group(self, *group_names):
        return self.role_set.filter(group__name__in=group_names).exists()

    def in_other_group(self, group_name):
        return self.is_superuser or self.role_set.exclude(
            group__name=group_name).exists()

    def get_permission_mapping(self, model, obj=None):
        from djangoplus.cache import loader
        permission_mapping_key = obj and '{}:{}'.format(
            model.__name__,
            type(obj).__name__) or model.__name__
        if not settings.DEBUG and permission_mapping_key in self.permission_mapping:
            return self.permission_mapping[permission_mapping_key]

        organization_lookups = []
        unit_lookups = []
        role_lookups = dict()
        lookups = dict(list_lookups=[], edit_lookups=[], delete_lookups=[])

        for lookup in get_metadata(model, 'list_lookups', (), iterable=True):
            field = get_field(model, lookup)
            if hasattr(
                    field.remote_field.model, 'organization_ptr') or hasattr(
                        field.remote_field.model, 'unit_ptr'):
                if hasattr(field.remote_field.model, 'organization_ptr'):
                    organization_lookups.append(lookup)
                if hasattr(field.remote_field.model, 'unit_ptr'):
                    unit_lookups.append(lookup)
            else:
                role_username = get_metadata(field.remote_field.model,
                                             'role_username')
                if role_username:
                    role_lookups[get_metadata(
                        field.remote_field.model,
                        'verbose_name')] = '{}__{}'.format(
                            lookup, role_username)
                for subclass in field.remote_field.model.__subclasses__():
                    role_username = get_metadata(subclass, 'role_username')
                    if role_username:
                        role_lookups[get_metadata(
                            subclass, 'verbose_name')] = '{}__{}__{}'.format(
                                lookup, subclass.__name__.lower(),
                                role_username)

        if hasattr(model,
                   'organization_ptr') and 'id' not in organization_lookups:
            organization_lookups.append('id')

        if hasattr(model, 'unit_ptr') and 'id' not in unit_lookups:
            unit_lookups.append('id')

        if get_metadata(model, 'role_username') and 'id' not in role_lookups:
            role_lookups[get_metadata(model, 'verbose_name')] = get_metadata(
                model, 'role_username')

        for field in get_metadata(model, 'fields'):
            if field.remote_field and field.remote_field.model:
                if field.remote_field.model in loader.role_models:
                    role_lookups[get_metadata(
                        field.remote_field.model,
                        'verbose_name')] = '{}__{}'.format(
                            field.name, loader.role_models[
                                field.remote_field.model]['username_field'])
                if field.remote_field.model in loader.abstract_role_models:
                    for to in loader.abstract_role_models[
                            field.remote_field.model]:
                        role_lookups[get_metadata(
                            to, 'verbose_name')] = '{}__{}__{}'.format(
                                field.name, to.__name__.lower(),
                                loader.role_models[to])
                if hasattr(field.remote_field.model,
                           'unit_ptr_id') and field.name not in unit_lookups:
                    unit_lookups.append(field.name)
                if hasattr(field.remote_field.model, 'organization_ptr_id'
                           ) and field.name not in organization_lookups:
                    organization_lookups.append(field.name)

        for organization_lookup in organization_lookups:
            if loader.unit_model:
                for field in get_metadata(loader.organization_model, 'fields'):
                    if field.remote_field and hasattr(field.remote_field.model,
                                                      'unit_ptr'):
                        if organization_lookup == 'id':
                            unit_lookup = field.name
                        else:
                            unit_lookup = '{}__{}'.format(
                                organization_lookup, field.name)
                        if unit_lookup not in unit_lookups and not hasattr(
                                model, 'unit_ptr'):
                            unit_lookups.append(unit_lookup)
                        break

        for unit_lookup in unit_lookups:
            if loader.organization_model:
                for field in get_metadata(loader.unit_model, 'fields'):
                    if field.remote_field and hasattr(field.remote_field.model,
                                                      'organization_ptr'):
                        if unit_lookup == 'id':
                            organization_lookup = field.name
                        else:
                            organization_lookup = '{}__{}'.format(
                                unit_lookup, field.name)
                        if organization_lookup not in organization_lookups and not hasattr(
                                model, 'organization_ptr'):
                            organization_lookups.append(organization_lookup)

        groups = dict()
        unit_organization_lookup = 'scope__organization'
        unit_organization_field_name = Unit.get_organization_field_name()
        if loader.unit_model and unit_organization_field_name:
            unit_organization_lookup = 'scope__unit__{}__{}'.format(
                loader.unit_model.__name__.lower(),
                unit_organization_field_name)
        scope_queryset = self.role_set.filter(active=True).values_list(
            'group__name', 'scope__organization', 'scope__unit',
            unit_organization_lookup)
        for group_name, organization_id, unit_id, unit_organization_id in scope_queryset:
            if group_name not in groups:
                groups[group_name] = dict(username_lookups=[],
                                          organization_ids=[],
                                          unit_ids=[])
            if group_name in role_lookups:
                groups[group_name]['username_lookups'].append(
                    role_lookups[group_name])
            if organization_id:
                groups[group_name]['organization_ids'].append(organization_id)
            if unit_id:
                groups[group_name]['unit_ids'].append(unit_id)
                if unit_organization_id:
                    groups[group_name]['organization_ids'].append(
                        unit_organization_id)

        if model in loader.permissions_by_scope:
            can_view_globally = can_edit_globally = can_delete_globally = False
            for group_name in groups:

                username_lookups = groups[group_name]['username_lookups']
                unit_ids = list(set(groups[group_name]['unit_ids']))
                organization_ids = list(
                    set(groups[group_name]['organization_ids']))

                can_view = can_view_by_role = can_view_by_unit = can_view_by_organization = False

                if obj:

                    if type(obj) in loader.permissions_by_scope:
                        can_view = group_name in loader.permissions_by_scope[
                            type(obj)].get('add', [])
                        can_view_by_unit = group_name in loader.permissions_by_scope[
                            type(obj)].get('add_by_unit', [])
                        can_view_by_organization = group_name in loader.permissions_by_scope[
                            type(obj)].get('add_by_organization', [])

                if (can_view or can_view_by_role or can_view_by_unit
                        or can_view_by_organization) is False:
                    can_view = group_name in loader.permissions_by_scope[
                        model].get('view', [])
                    can_view_by_role = group_name in loader.permissions_by_scope[
                        model].get('view_by_role', [])
                    can_view_by_unit = group_name in loader.permissions_by_scope[
                        model].get('view_by_unit', [])
                    can_view_by_organization = group_name in loader.permissions_by_scope[
                        model].get('view_by_organization', [])

                if can_view:
                    can_view_globally = True
                else:
                    if can_view_by_role:
                        for username_lookup in username_lookups:
                            lookups['list_lookups'].append(
                                (username_lookup, (self.username, )))
                    if can_view_by_unit:
                        if unit_ids:
                            for unit_lookup in unit_lookups:
                                lookups['list_lookups'].append(
                                    ('{}'.format(unit_lookup), unit_ids))
                    if can_view_by_organization:
                        if organization_ids:
                            for organization_lookup in organization_lookups:
                                lookups['list_lookups'].append(
                                    ('{}'.format(organization_lookup),
                                     organization_ids))

                can_edit = group_name in loader.permissions_by_scope[
                    model].get('edit', [])
                can_edit_by_role = group_name in loader.permissions_by_scope[
                    model].get('edit_by_role', [])
                can_edit_by_unit = group_name in loader.permissions_by_scope[
                    model].get('edit_by_unit', [])
                can_edit_by_organization = group_name in loader.permissions_by_scope[
                    model].get('edit_by_organization', [])

                if can_edit:
                    can_edit_globally = True
                else:
                    if can_edit_by_role:
                        for username_lookup in username_lookups:
                            lookups['edit_lookups'].append(
                                (username_lookup, (self.username, )))
                    if can_edit_by_unit and unit_ids:
                        for unit_lookup in unit_lookups:
                            lookups['edit_lookups'].append(
                                (unit_lookup, unit_ids))
                    if can_edit_by_organization and organization_ids:
                        for organization_lookup in organization_lookups:
                            lookups['edit_lookups'].append(
                                (organization_lookup, organization_ids))

                can_delete = group_name in loader.permissions_by_scope[
                    model].get('delete', [])
                can_delete_by_role = group_name in loader.permissions_by_scope[
                    model].get('delete_by_role', [])
                can_delete_by_unit = group_name in loader.permissions_by_scope[
                    model].get('delete_by_unit', [])
                can_delete_by_organization = group_name in loader.permissions_by_scope[
                    model].get('delete_by_organization', [])

                if can_delete:
                    can_delete_globally = True
                else:
                    if can_delete_by_role:
                        for username_lookup in username_lookups:
                            lookups['delete_lookups'].append(
                                (username_lookup, (self.username, )))
                    if can_delete_by_unit and unit_ids:
                        for unit_lookup in unit_lookups:
                            lookups['delete_lookups'].append(
                                (unit_lookup, unit_ids))
                    if can_delete_by_organization and organization_ids:
                        for organization_lookup in organization_lookups:
                            lookups['delete_lookups'].append(
                                (organization_lookup, organization_ids))

                for actions_dict in (loader.actions, loader.class_actions):
                    for category in actions_dict.get(model, ()):
                        for key in list(actions_dict[model][category].keys()):
                            execute_lookups = []
                            view_name = actions_dict[model][category][key][
                                'view_name']
                            can_execute = group_name in loader.permissions_by_scope[
                                model].get('{}'.format(view_name), [])
                            can_execute_by_role = group_name in loader.permissions_by_scope[
                                model].get('{}_by_role'.format(view_name), [])
                            can_execute_by_unit = group_name in loader.permissions_by_scope[
                                model].get('{}_by_unit'.format(view_name), [])
                            can_execute_by_organization = group_name in loader.permissions_by_scope[
                                model].get(
                                    '{}_by_organization'.format(view_name), [])
                            if can_execute:
                                execute_lookups = None
                            else:
                                if can_execute_by_role:
                                    for username_lookup in username_lookups:
                                        execute_lookups.append(
                                            (username_lookup,
                                             (self.username, )))
                                if can_execute_by_unit and unit_ids:
                                    for unit_lookup in unit_lookups:
                                        execute_lookups.append(
                                            (unit_lookup, unit_ids))
                                if can_execute_by_organization and organization_ids:
                                    for organization_lookup in organization_lookups:
                                        execute_lookups.append(
                                            (organization_lookup,
                                             organization_ids))
                            if execute_lookups:
                                if view_name not in lookups:
                                    lookups[view_name] = []
                                lookups[view_name] += execute_lookups

            if can_view_globally:
                lookups['list_lookups'] = []
            if can_edit_globally:
                lookups['edit_lookups'] = []
            if can_delete_globally:
                lookups['delete_lookups'] = []

        for codename in ('view', 'list'):
            if model in loader.permissions_by_scope:
                if loader.permissions_by_scope[model].get(
                        '{}_by_unit'.format(codename)) and not unit_lookups:
                    raise Exception(
                        'A "lookup" meta-attribute must point to a Unit model in {}'
                        .format(model))
                if loader.permissions_by_scope[model].get(
                        '{}_by_organization'.format(codename)) and (
                            not organization_lookups and not unit_lookups):
                    raise Exception(
                        'A "lookup" meta-attribute must point to a Unit or Organization model in {}'
                        .format(model))
                if loader.permissions_by_scope[model].get(
                        '{}_by_role'.format(codename)) and not role_lookups:
                    raise Exception(
                        'A "lookup" meta-attribute must point to a role model in {}'
                        .format(model))

        self.permission_mapping[permission_mapping_key] = lookups
        self.save()

        return self.permission_mapping[permission_mapping_key]

    # gieve a set of group or permission names, this method returns the groups the user belongs to
    def find_groups(self, perm_or_group, exclude=None):
        qs = self.groups.all()
        if perm_or_group:
            permissions = []
            groups = []
            for item in perm_or_group:
                if '.' in item:
                    permissions.append(item.split('.')[1])
                else:
                    groups.append(item)
            if permissions:
                qs = qs.filter(permissions__codename__in=permissions)
            if groups:
                qs = qs.filter(name__in=groups)

        if exclude:
            qs = qs.exclude(name=exclude)
        return qs

    def email_user(self, subject, message, from_email=None, **kwargs):
        send_mail(subject, message, from_email, [self.email], **kwargs)

    def check_role_groups(self):
        for group in self.groups.all():
            self.groups.remove(group)
        for group in self.role_set.filter(active=True).values_list(
                'group', flat=True).distinct():
            self.groups.add(group)
Ejemplo n.º 3
0
class Settings(models.Model):

    class Meta:
        verbose_name = _('Settings')
        verbose_name_plural = _('Settings')

    fieldsets = (
        (_('General Data'), {'fields': (('initials', 'name'), ('logo', 'logo_pdf'), ('icon', 'background'))}),
        (_('Social Data'), {'fields': (('twitter', 'facebook'), ('google', 'pinterest'), ('linkedin', 'rss'))}),
        (_('Copyright'), {'fields': ('company', ('phone_1', 'phone_2'), 'address', 'email')}),
        (_('Look and Feel'), {'fields': ('default_color',)}),
        (_('Server'), {'fields': (('server_address', 'system_email_address'),)}),
        (_('Version'), {'fields': ('version',)}),
    )

    # Application
    initials = models.CharField(_('Name'), default='Django+')
    name = models.CharField(_('Description'), default='Django Plus')
    logo = models.ImageField(_('Logo'), upload_to='config', null=True, blank=True, default='')
    logo_pdf = models.ImageField(_('PDF Logo'), upload_to='config', help_text=_('No-background image'),
                                 null=True, blank=True, default='')
    icon = models.ImageField(_('Icon'), upload_to='config', null=True, blank=True)
    background = models.ImageField('Background', upload_to='config', default='', blank=True)

    # Social params
    twitter = models.CharField('Twitter', null=True, blank=True)
    facebook = models.CharField('Facebook', null=True, blank=True)
    google = models.CharField('Google', null=True, blank=True)
    pinterest = models.CharField('Pinterest', null=True, blank=True)
    linkedin = models.CharField('Linkedin', null=True, blank=True)
    rss = models.CharField('RSS', null=True, blank=True)

    # Company
    company = models.CharField(_('Company Name'), null=True, blank=True)
    address = models.TextField(_('Address'), null=True, blank=True)
    phone_1 = models.PhoneField(_('Primary Phome'), null=True, blank=True)
    phone_2 = models.PhoneField(_('Secondary Phone'), null=True, blank=True)
    email = models.CharField(_('Email'), null=True, blank=True)

    # Server configuration
    version = models.CharField(_('System Version'), exclude=True)
    server_address = models.CharField(_('Server URL'), default='http://*****:*****@djangoplus.net')

    @staticmethod
    def default():
        from djangoplus.cache import CACHE
        if not CACHE['SETTINGS_INSTANCE']:
            CACHE['SETTINGS_INSTANCE'] = Settings.objects.first()
        if not CACHE['SETTINGS_INSTANCE']:
            s = Settings()
            s.initials = _('System')
            s.name = _('Online, responsive e multiplatform system')
            s.twitter = 'https://twitter.com/'
            s.facebook = 'https://www.facebook.com/'
            s.google = 'https://plus.google.com/'
            s.pinterest = 'https://www.pinterest.com/'
            s.linkedin = 'https://www.linkedin.com/'
            s.rss = 'https://www.rss.com/'
            s.company = ''
            s.address = ''
            s.phone_1 = ''
            s.phone_2 = ''
            s.email = ''
            s.version = '1.0'
            s.save()
            CACHE['SETTINGS_INSTANCE'] = s
        return CACHE['SETTINGS_INSTANCE']

    def save(self, *args, **kwargs):
        from djangoplus.cache import CACHE
        super(Settings, self).save(*args, **kwargs)
        CACHE['SETTINGS_INSTANCE'] = self
Ejemplo n.º 4
0
class User(AbstractBaseUser, PermissionsMixin):
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    name = models.CharField(_('Name'), max_length=100, blank=True, search=True)
    username = models.CharField(_('Username'), max_length=30, unique=True, search=True)
    email = models.CharField(_('E-mail'), max_length=75, blank=True, default='')
    active = models.BooleanField(verbose_name=_('Active'), default=True, filter=True)
    photo = models.ImageField(upload_to='profiles', null=True, blank=True,
                              default='/static/images/user.png', verbose_name=_('Photo'), exclude=True)

    token = models.CharField(verbose_name='Token', null=True, exclude=True)

    permission_mapping = models.JsonField(verbose_name=_('Permissions Mapping'), exclude=True, display=False)
    scope = models.ForeignKey(Scope, verbose_name='Scope', null=True, exclude=True, blank=True)
    objects = UserManager()

    fieldsets = (
        (_('Identification'), {'fields': (('name', 'email'),), 'image': 'photo'}),
        (_('Access'), {'fields': (('username', 'is_superuser'), ('active',))}),
        (_('Roles'), {'relations': ('role_set',)}),
        (_('Permissions Mapping'), {'fields': ('permission_mapping',)}),
    )

    class Meta:
        verbose_name = _('User')
        verbose_name_plural = _('Users')
        list_display = 'photo', 'username', 'name', 'email', 'groups'
        add_form = 'UserForm'
        can_admin = _('User Manager')
        icon = 'fa-users'
        expose = True
        # list_template = 'image_cards.html'

    def __init__(self, *args, **kwargs):
        super(User, self).__init__(*args, **kwargs)

    def save(self, *args, **kwargs):
        if not self.token:
            self.token = binascii.hexlify(os.urandom(20)).decode()
        if not self.password:
            if settings.DEBUG or 'test' in sys.argv or True:
                password = settings.DEFAULT_PASSWORD
            else:
                password = uuid.uuid4().hex
            self.set_password(password)
        super(User, self).save(*args, **kwargs)
        if self.is_superuser:
            group = Group.objects.get_or_create(name=_('Superuser'))[0]
            self.groups.add(group)
        group = Group.objects.get_or_create(name=_('User'))[0]
        self.groups.add(group)

    def __str__(self):
        return self.name or self.username

    @action(_('Change Password'), input='ChangePasswordForm', inline=True)
    def change_password(self, new_password, confirm_password):
        self.set_password(new_password)
        self.save()

    @action(_('Send Access Invitation'), inline=True, condition='email', category=None)
    def send_access_invitation(self):
        self.send_access_invitation_for_group(None)

    def send_reset_password_notification(self):
        project_name = Settings.default().initials
        subject = '{} - "{}"'.format(_('Reset Password'), project_name)
        message = _('Click on the button bellow to (re)define your password.')
        actions = [(_('Reset Password!'), '/admin/password/{}/{}/'.format(self.pk, signing.dumps(self.password)))]
        send_mail(subject, message, self.email, actions=actions)

    def send_access_invitation_for_group(self, group):
        project_name = Settings.default().initials
        subject = '{} - "{}"'.format(_('System Access'), project_name)
        if group:
            extra = _('''If you are already a user, click on the button "Access now!" to authenticate.
                Otherwise, click on the button "Define password!" to provide your access password.''')
            message = '''{} <b>{}</b> {} <b>{}</b>.
                {}
            '''.format(_('You were registered in the system.'), project_name, _(' as '), group, extra)
            actions = [
                (_('Access now!'), '/admin/'),
                (_('Define password!'), '/admin/password/{}/{}/'.format(self.pk, signing.dumps(self.password)))
            ]
        else:
            extra = _('Click on the button bellow to (re)define your password.')
            message = '''{} <b>{}</b>.
                {}.
            '''.format(_('You were registered in the system'), project_name, extra)
            actions = [(_('Access now!'), '/admin/password/{}/{}/'.format(self.pk, signing.dumps(self.password)))]
        send_mail(subject, message, self.email, actions=actions)

    def units(self, group_name=None):
        qs = self.role_set.all()
        if group_name:
            qs = qs.filter(group__name=group_name)
        return qs.values_list('scope', flat=True)

    def in_group(self, *group_names):
        return self.role_set.filter(group__name__in=group_names).exists()

    def in_other_group(self, group_name):
        return self.is_superuser or self.role_set.exclude(group__name=group_name).exists()

    def get_appliable_scopes(self):
        scopes = []
        for scope in Scope.objects.filter(pk__in=self.role_set.values_list('scope', flat=True)):
            if scope not in scopes:
                scopes.append(scope)
                if scope.is_organization():
                    for unit in scope.organization.get_units():
                        scopes.append(unit)
        return scopes

    def apply_current_scope(self, queryset):
        if self.scope:
            filters = []
            organization_lookups, unit_lookups, role_lookups = self.get_lookups(queryset.model)
            if self.scope.is_organization():
                lookups = organization_lookups
            else:
                lookups = unit_lookups
            for lookup in lookups:
                filters.append(Q(**{lookup: self.scope.pk}))
            if filters:
                queryset = queryset.filter(reduce(operator.__and__, filters))
        return queryset

    def get_lookups(self, model):
        from djangoplus.cache import CACHE

        organization_lookups = []
        unit_lookups = []
        role_lookups = dict()

        for lookup in get_metadata(model, 'list_lookups', (), iterable=True):
            field = get_field(model, lookup)
            if hasattr(field.remote_field.model, 'organization_ptr') or hasattr(field.remote_field.model, 'unit_ptr'):
                if hasattr(field.remote_field.model, 'organization_ptr'):
                    organization_lookups.append(lookup)
                if hasattr(field.remote_field.model, 'unit_ptr'):
                    unit_lookups.append(lookup)
            else:
                role_username = get_metadata(field.remote_field.model, 'role_username')
                if role_username:
                    role_lookups[get_metadata(field.remote_field.model, 'verbose_name')] = '{}__{}'.format(
                        lookup, role_username)
                for subclass in field.remote_field.model.__subclasses__():
                    role_username = get_metadata(subclass, 'role_username')
                    if role_username:
                        role_lookups[get_metadata(subclass, 'verbose_name')] = '{}__{}__{}'.format(
                            lookup, subclass.__name__.lower(), role_username)

        if hasattr(model, 'organization_ptr') and 'id' not in organization_lookups:
            organization_lookups.append('id')

        if hasattr(model, 'unit_ptr') and 'id' not in unit_lookups:
            unit_lookups.append('id')

        if get_metadata(model, 'role_username') and 'id' not in role_lookups:
            role_lookups[get_metadata(model, 'verbose_name')] = get_metadata(model, 'role_username')

        for field in get_metadata(model, 'fields') + get_metadata(model, 'many_to_many'):
            if field.remote_field and field.remote_field.model:
                if field.remote_field.model in CACHE['ROLE_MODELS']:
                    role_lookups[get_metadata(field.remote_field.model, 'verbose_name')] = '{}__{}'.format(field.name, CACHE['ROLE_MODELS'][field.remote_field.model]['username_field'])
                if field.remote_field.model in CACHE['ABSTRACT_ROLE_MODELS']:
                    for to in CACHE['ABSTRACT_ROLE_MODELS'][field.remote_field.model]:
                        role_lookups[get_metadata(to, 'verbose_name')] = '{}__{}__{}'.format(
                            field.name, to.__name__.lower(), CACHE['ROLE_MODELS'][to])
                if hasattr(field.remote_field.model, 'unit_ptr_id') and field.name not in unit_lookups:
                    unit_lookups.append(field.name)
                if hasattr(field.remote_field.model, 'organization_ptr_id') and field.name not in organization_lookups:
                    organization_lookups.append(field.name)

        for organization_lookup in organization_lookups:
            if CACHE['UNIT_MODEL']:
                for field in get_metadata(CACHE['ORGANIZATION_MODEL'], 'fields'):
                    if field.remote_field and hasattr(field.remote_field.model, 'unit_ptr'):
                        if organization_lookup == 'id':
                            unit_lookup = field.name
                        else:
                            unit_lookup = '{}__{}'.format(organization_lookup, field.name)
                        if unit_lookup not in unit_lookups and not hasattr(model, 'unit_ptr'):
                            unit_lookups.append(unit_lookup)
                        break

        for unit_lookup in unit_lookups:
            if CACHE['ORGANIZATION_MODEL']:
                for field in get_metadata(CACHE['UNIT_MODEL'], 'fields'):
                    if field.remote_field and hasattr(field.remote_field.model, 'organization_ptr'):
                        if unit_lookup == 'id':
                            organization_lookup = field.name
                        else:
                            organization_lookup = '{}__{}'.format(unit_lookup, field.name)
                        if organization_lookup not in organization_lookups and not hasattr(model, 'organization_ptr'):
                            organization_lookups.append(organization_lookup)

        return organization_lookups, unit_lookups, role_lookups

    def get_permission_mapping(self, model, obj=None):
        from djangoplus.cache import CACHE
        permission_mapping_key = obj and '{}:{}'.format(model.__name__, type(obj).__name__) or model.__name__
        if permission_mapping_key in self.permission_mapping:
            return self.permission_mapping[permission_mapping_key]

        organization_lookups, unit_lookups, role_lookups = self.get_lookups(model)
        lookups = dict(list_lookups=[], edit_lookups=[], delete_lookups=[])

        groups = dict()
        unit_organization_lookup = 'scope__organization'
        unit_organization_field_name = Unit.get_organization_field_name()
        if CACHE['UNIT_MODEL'] and unit_organization_field_name:
            unit_organization_lookup = 'scope__unit__{}__{}'.format(
                CACHE['UNIT_MODEL'].__name__.lower(), unit_organization_field_name
            )
        scope_queryset = self.role_set.filter(
            active=True).values_list('group__name', 'scope__organization', 'scope__unit', unit_organization_lookup)
        for group_name, organization_id, unit_id, unit_organization_id in scope_queryset:

            if group_name not in groups:
                groups[group_name] = dict(username_lookups=[], organization_ids=[], unit_ids=[])
            if group_name in role_lookups:
                groups[group_name]['username_lookups'].append(role_lookups[group_name])
            if organization_id:
                groups[group_name]['organization_ids'].append(organization_id)
            if unit_id:
                groups[group_name]['unit_ids'].append(unit_id)
                if unit_organization_id:
                    groups[group_name]['organization_ids'].append(unit_organization_id)

        if model in CACHE['PERMISSIONS_BY_SCOPE']:
            can_view_globally = can_edit_globally = can_delete_globally = False
            for group_name in groups:

                username_lookups = groups[group_name]['username_lookups']
                unit_ids = list(set(groups[group_name]['unit_ids']))
                organization_ids = list(set(groups[group_name]['organization_ids']))

                can_view = can_view_by_role = can_view_by_unit = can_view_by_organization = False

                if obj:

                    if type(obj) in CACHE['PERMISSIONS_BY_SCOPE']:
                        can_view = group_name in CACHE['PERMISSIONS_BY_SCOPE'][type(obj)].get('add', [])
                        can_view_by_unit = group_name in CACHE['PERMISSIONS_BY_SCOPE'][type(obj)].get('add_by_unit', [])
                        can_view_by_organization = group_name in CACHE['PERMISSIONS_BY_SCOPE'][type(obj)].get(
                            'add_by_organization', [])

                if (can_view or can_view_by_role or can_view_by_unit or can_view_by_organization) is False:
                    can_view = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get('view', [])
                    can_view_by_role = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get('view_by_role', [])
                    can_view_by_unit = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get('view_by_unit', [])
                    can_view_by_organization = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get(
                        'view_by_organization', [])

                if can_view:
                    can_view_globally = True
                else:
                    if can_view_by_role:
                        for username_lookup in username_lookups:
                            lookups['list_lookups'].append((username_lookup, (self.username,)))
                    if can_view_by_unit:
                        if unit_ids:
                            for unit_lookup in unit_lookups:
                                lookups['list_lookups'].append(('{}'.format(unit_lookup), unit_ids))
                    if can_view_by_organization:
                        if organization_ids:
                            for organization_lookup in organization_lookups:
                                lookups['list_lookups'].append(('{}'.format(organization_lookup), organization_ids))

                can_edit = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get('edit', [])
                can_edit_by_role = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get('edit_by_role', [])
                can_edit_by_unit = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get('edit_by_unit', [])
                can_edit_by_organization = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get(
                    'edit_by_organization', [])

                if can_edit:
                    can_edit_globally = True
                else:
                    if can_edit_by_role:
                        for username_lookup in username_lookups:
                            lookups['edit_lookups'].append((username_lookup, (self.username,)))
                    if can_edit_by_unit and unit_ids:
                        for unit_lookup in unit_lookups:
                            lookups['edit_lookups'].append((unit_lookup, unit_ids))
                    if can_edit_by_organization and organization_ids:
                        for organization_lookup in organization_lookups:
                            lookups['edit_lookups'].append((organization_lookup, organization_ids))

                can_delete = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get('delete', [])
                can_delete_by_role = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get('delete_by_role', [])
                can_delete_by_unit = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get('delete_by_unit', [])
                can_delete_by_organization = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get(
                    'delete_by_organization', [])

                if can_delete:
                    can_delete_globally = True
                else:
                    if can_delete_by_role:
                        for username_lookup in username_lookups:
                            lookups['delete_lookups'].append((username_lookup, (self.username,)))
                    if can_delete_by_unit and unit_ids:
                        for unit_lookup in unit_lookups:
                            lookups['delete_lookups'].append((unit_lookup, unit_ids))
                    if can_delete_by_organization and organization_ids:
                        for organization_lookup in organization_lookups:
                            lookups['delete_lookups'].append((organization_lookup, organization_ids))

                for actions_dict in (CACHE['INSTANCE_ACTIONS'], CACHE['QUERYSET_ACTIONS']):
                    for category in actions_dict.get(model, ()):
                        for key in list(actions_dict[model][category].keys()):
                            execute_lookups = []
                            view_name = actions_dict[model][category][key]['view_name']
                            can_execute = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get('{}'.format(
                                view_name), [])
                            can_execute_by_role = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get(
                                '{}_by_role'.format(view_name), [])
                            can_execute_by_unit = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get(
                                '{}_by_unit'.format(view_name), [])
                            can_execute_by_organization = group_name in CACHE['PERMISSIONS_BY_SCOPE'][model].get(
                                '{}_by_organization'.format(view_name), [])
                            if can_execute:
                                execute_lookups = None
                            else:
                                if can_execute_by_role:
                                    for username_lookup in username_lookups:
                                        execute_lookups.append((username_lookup, (self.username,)))
                                if can_execute_by_unit and unit_ids:
                                    for unit_lookup in unit_lookups:
                                        execute_lookups.append((unit_lookup, unit_ids))
                                if can_execute_by_organization and organization_ids:
                                    for organization_lookup in organization_lookups:
                                        execute_lookups.append((organization_lookup, organization_ids))
                            if execute_lookups:
                                if view_name not in lookups:
                                    lookups[view_name] = []
                                lookups[view_name] += execute_lookups

            if can_view_globally:
                lookups['list_lookups'] = []
            if can_edit_globally:
                lookups['edit_lookups'] = []
            if can_delete_globally:
                lookups['delete_lookups'] = []

        for codename in ('view', 'list'):
            if model in CACHE['PERMISSIONS_BY_SCOPE']:
                if CACHE['PERMISSIONS_BY_SCOPE'][model].get('{}_by_unit'.format(codename)) and not unit_lookups:
                    raise Exception('A "lookup" meta-attribute must point to a Unit model in {}'.format(model))
                if CACHE['PERMISSIONS_BY_SCOPE'][model].get('{}_by_organization'.format(codename)) and (
                        not organization_lookups and not unit_lookups):
                    raise Exception('A "lookup" meta-attribute must point to a Unit or Organization model in {}'.format(
                        model))
                if CACHE['PERMISSIONS_BY_SCOPE'][model].get('{}_by_role'.format(codename)) and not role_lookups:
                    raise Exception('A "lookup" meta-attribute must point to a role model in {}'.format(model))

        self.permission_mapping[permission_mapping_key] = lookups
        self.save()

        return self.permission_mapping[permission_mapping_key]

    # given a set of group or permission names, this method returns the groups the user belongs to
    def find_groups(self, perm_or_group, exclude=None):
        qs = self.groups.all()
        if perm_or_group:
            permissions = []
            groups = []
            for item in perm_or_group:
                if '.' in item:
                    permissions.append(item.split('.')[1])
                else:
                    groups.append(item)
            if permissions:
                qs = qs.filter(permissions__codename__in=permissions)
            if groups:
                qs = qs.filter(name__in=groups)

        if exclude:
            qs = qs.exclude(name=exclude)
        return qs

    def email_user(self, subject, message, from_email=None, **kwargs):
        send_mail(subject, message, from_email, [self.email], **kwargs)

    def check_role_groups(self):
        for group in self.groups.all():
            self.groups.remove(group)
        for group in self.role_set.filter(active=True).values_list('group', flat=True).distinct():
            self.groups.add(group)
Ejemplo n.º 5
0
class Settings(models.Model):

    class Meta:
        verbose_name = u'Configuração'
        verbose_name_plural = u'Configurações'

    fieldsets = (
        (u'Configuração Geral', {'fields': (('initials', 'name'), ('logo', 'logo_pdf'), ('icon', 'background'))}),
        (u'Social', {'fields': (('twitter', 'facebook'), ('google', 'pinterest'), ('linkedin', 'rss'))}),
        (u'Contato', {'fields': (('phone_1', 'phone_2'), 'address', 'email')}),
        (u'Aparência', {'fields': ('default_color',)}),
        (u'Servidor', {'fields': (('server_address', 'system_email_address'),)}),
        (u'Versão', {'fields': ('version',)}),
    )

    # Application
    initials = models.CharField(u'Nome', default=u'Django+')
    name = models.CharField(u'Descrição', default=u'Django Plus')
    logo = models.ImageField(u'Logotipo', upload_to='config', null=True, blank=True, default='')
    logo_pdf = models.ImageField(u'Logotipo para PDF', upload_to='config', help_text=u'Imagem sem fundo transparente',
                                 null=True, blank=True, default='')
    icon = models.ImageField(u'Ícone', upload_to='config', null=True, blank=True)
    background = models.ImageField(u'Background', upload_to='config', default='', blank=True)

    # Social params
    twitter = models.CharField(u'Twitter', null=True, blank=True)
    facebook = models.CharField(u'Facebook', null=True, blank=True)
    google = models.CharField(u'Google', null=True, blank=True)
    pinterest = models.CharField(u'pinterest', null=True, blank=True)
    linkedin = models.CharField(u'Linkedin', null=True, blank=True)
    rss = models.CharField(u'RSS', null=True, blank=True)

    # Contact info
    address = models.TextField(u'Endereço', null=True, blank=True)
    phone_1 = models.PhoneField(u'Telefone Principal', null=True, blank=True)
    phone_2 = models.PhoneField(u'Telefone Secundário', null=True, blank=True)
    email = models.CharField(u'E-mail', null=True, blank=True)

    # Server configuration
    version = models.CharField(u'Versão do Sistema', exclude=True)
    server_address = models.CharField(u'Endereço de Acesso', default=u'http://*****:*****@djangoplus.net')

    @staticmethod
    def default():
        qs = Settings.objects.all()
        if qs.exists():
            return qs[0]
        else:
            settings = Settings()
            settings.initials = u'Sistema'
            settings.name = u'Sistema de gerenciamento online, responsivo e multiplataforma'
            settings.twitter = u'https://twitter.com/'
            settings.facebook = u'https://www.facebook.com/'
            settings.google = u'https://plus.google.com/'
            settings.pinterest = u'https://www.pinterest.com/'
            settings.linkedin = u'https://www.linkedin.com/'
            settings.rss = u'https://www.rss.com/'
            settings.address = u''
            settings.phone_1 = u''
            settings.phone_2 = u''
            settings.email = u''
            settings.version = '1.0'
            settings.save()
            return settings
Ejemplo n.º 6
0
class User(AbstractBaseUser, PermissionsMixin):
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    name = models.CharField(u'Nome', max_length=30, blank=True, search=True)
    username = models.CharField(u'Login', max_length=30, unique=True)
    email = models.CharField(u'E-mail', max_length=75, blank=True, default='')
    active = models.BooleanField(verbose_name=u'Ativo?', default=True, filter=True)
    photo = models.ImageField(upload_to='profiles', null=True, blank=True, default='', verbose_name=u'Foto', exclude=True)

    permission_mapping = models.TextField(verbose_name=u'Mapeamento de Permissão', default='{}', exclude=True, display=False)
    organization = models.ForeignKey(Organization, verbose_name=u'Organização', null=True, blank=True, display=False)
    unit = models.ForeignKey(Unit, verbose_name=u'Unidade', null=True, blank=True, display=False)

    objects = UserManager()

    fieldsets = (
        (u'Identificação', {'fields': (('name', 'email'),)}),
        (u'Acesso', {'fields': (('username', 'is_superuser'), ('active',))}),
        (u'Funções', {'relations': ('role_set',)}),
        (u'Mapeamento de Permissão', {'fields': (('organization', 'unit'), 'permission_mapping')}),
    )

    class Meta():
        verbose_name = u'Usuário'
        verbose_name_plural = u'Usuários'
        list_display = 'username', 'name', 'groups'
        add_form = 'UserForm'
        can_admin = u'Gerenciador de Usuários'
        icon = 'fa-user'

    def save(self, *args, **kwargs):
        super(User, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.name or self.username

    @action('Alterar Senha', input='ChangePasswordForm', inline=True)
    def change_password(self, new_password, confirm_password):
        self.set_password(new_password)
        self.save()

    def units(self, group_name=None):
        qs = self.role_set.all()
        if group_name:
            qs = qs.filter(group__name=group_name)
        return qs.values_list('units', flat=True)

    def in_group(self, *group_names):
        return self.role_set.filter(group__name__in=group_names).exists()

    def in_other_group(self, group_name):
        return self.is_superuser or self.role_set.exclude(group__name=group_name).exists()

    def get_permission_mapping(self, model, obj=None):
        from djangoplus.cache import loader
        import json
        permission_mapping = json.loads(self.permission_mapping or '{}')
        permission_mapping_key = obj and '%s:%s' % (model.__name__, type(obj).__name__) or model.__name__
        if 0 and permission_mapping_key in permission_mapping:
            return permission_mapping[permission_mapping_key]

        organization_lookups = []
        unit_lookups = []
        role_lookups = dict()
        lookups = dict(list_lookups=[], edit_lookups=[], delete_lookups=[])

        for lookup in get_metadata(model, 'list_lookups', (), iterable=True):
            field = get_field(model, lookup)
            if hasattr(field.rel.to, 'organization_ptr') or hasattr(field.rel.to, 'unit_ptr'):
                if hasattr(field.rel.to, 'organization_ptr'):
                    organization_lookups.append(lookup)
                if hasattr(field.rel.to, 'unit_ptr'):
                    unit_lookups.append(lookup)
            else:
                role_username = get_metadata(field.rel.to, 'role_username')
                if role_username:
                    role_lookups[get_metadata(field.rel.to, 'verbose_name')] = '%s__%s' % (lookup, role_username)
                for subclass in field.rel.to.__subclasses__():
                    role_username = get_metadata(subclass, 'role_username')
                    if role_username:
                        role_lookups[get_metadata(subclass, 'verbose_name')] = '%s__%s__%s' % (
                            lookup, subclass.__name__.lower(), role_username)

        if hasattr(model, 'organization_ptr') and 'id' not in organization_lookups:
            organization_lookups.append('id')

        if hasattr(model, 'unit_ptr') and 'id' not in unit_lookups:
            unit_lookups.append('id')

        if get_metadata(model, 'role_username') and 'id' not in role_lookups:
            role_lookups[get_metadata(model, 'verbose_name')] = get_metadata(model, 'role_username')

        for field in get_metadata(model, 'fields'):
            if hasattr(field, 'rel') and field.rel and hasattr(field.rel, 'to') and field.rel.to:
                if field.rel.to in loader.role_models:
                    role_lookups[get_metadata(field.rel.to, 'verbose_name')] = '%s__%s' % (field.name, loader.role_models[field.rel.to]['username_field'])
                if field.rel.to in loader.abstract_role_models:
                    for to in loader.abstract_role_models[field.rel.to]:
                        role_lookups[get_metadata(to, 'verbose_name')] = '%s__%s__%s' % (
                            field.name, to.__name__.lower(), loader.role_models[to])
                if hasattr(field.rel.to, 'unit_ptr_id') and field.name not in unit_lookups:
                    unit_lookups.append(field.name)
                if hasattr(field.rel.to, 'organization_ptr_id') and field.name not in organization_lookups:
                    organization_lookups.append(field.name)

        for organization_lookup in organization_lookups:
            if loader.unit_model:
                if organization_lookup == 'id':
                    unit_lookup = loader.unit_model.__name__.lower()
                else:
                    unit_lookup = '%s__%s' % (organization_lookup, loader.unit_model.__name__.lower())
                if unit_lookup not in unit_lookups and not hasattr(model, 'unit_ptr'):
                    unit_lookups.append(unit_lookup)

        for unit_lookup in unit_lookups:
            if loader.organization_model:
                if unit_lookup == 'id':
                    organization_lookup = loader.organization_model.__name__.lower()
                else:
                    organization_lookup = '%s__%s' % (unit_lookup, loader.organization_model.__name__.lower())
                if organization_lookup not in organization_lookups and not hasattr(model, 'organization_ptr'):
                    organization_lookups.append(organization_lookup)

        groups = dict()
        for group_name, organization_id, unit_id in self.role_set.values_list('group__name', 'organizations', 'units'):
            if group_name not in groups:
                groups[group_name] = dict(username_lookups=[], organization_ids=[], unit_ids=[])
            if group_name in role_lookups:
                groups[group_name]['username_lookups'].append(role_lookups[group_name])
            if organization_id and not self.unit_id and (organization_id == self.organization_id or not self.organization_id):
                groups[group_name]['organization_ids'].append(organization_id)
            if self.unit_id or unit_id:
                groups[group_name]['unit_ids'].append(self.unit_id or unit_id)

        if model in loader.permissions_by_scope:
            for group_name in groups:

                username_lookups = groups[group_name]['username_lookups']
                unit_ids = list(set(groups[group_name]['unit_ids']))
                organization_ids = list(set(groups[group_name]['organization_ids']))

                if obj:

                    can_list = can_list_by_role = can_list_by_unit = can_list_by_organization = False

                    if type(obj) in loader.permissions_by_scope:
                        can_list = group_name in loader.permissions_by_scope[type(obj)].get('add', [])
                        can_list_by_role = group_name in loader.permissions_by_scope[type(obj)].get('add_by_role', [])
                        can_list_by_unit = group_name in loader.permissions_by_scope[type(obj)].get('add_by_unit', [])
                        can_list_by_organization = group_name in loader.permissions_by_scope[type(obj)].get('add_by_organization', [])

                        if (can_list or can_list_by_role or can_list_by_unit or can_list_by_organization) is False:
                            can_list = group_name in loader.permissions_by_scope[type(obj)].get('list', [])
                            can_list_by_role = group_name in loader.permissions_by_scope[type(obj)].get('list_by_role', [])
                            can_list_by_unit = group_name in loader.permissions_by_scope[type(obj)].get('list_by_unit', [])
                            can_list_by_organization = group_name in loader.permissions_by_scope[type(obj)].get('list_by_organization', [])

                    if (can_list or can_list_by_role or can_list_by_unit or can_list_by_organization) is False:
                        can_list = group_name in loader.permissions_by_scope[model].get('list', [])
                        can_list_by_role = group_name in loader.permissions_by_scope[model].get('list_by_role', [])
                        can_list_by_unit = group_name in loader.permissions_by_scope[model].get('list_by_unit', [])
                        can_list_by_organization = group_name in loader.permissions_by_scope[model].get('list_by_organization', [])

                else:
                    can_list = group_name in loader.permissions_by_scope[model].get('list', [])
                    can_list_by_role = group_name in loader.permissions_by_scope[model].get('list_by_role', [])
                    can_list_by_unit = group_name in loader.permissions_by_scope[model].get('list_by_unit', [])
                    can_list_by_organization = group_name in loader.permissions_by_scope[model].get('list_by_organization', [])

                if can_list:
                    lookups['list_lookups'] = []
                else:
                    if can_list_by_role:
                        for username_lookup in username_lookups:
                            lookups['list_lookups'].append((username_lookup, (self.username,)))
                    if can_list_by_unit or self.unit_id:
                        if unit_ids and 0 not in unit_ids:
                            for unit_lookup in unit_lookups:
                                lookups['list_lookups'].append(('%s' % unit_lookup, unit_ids))
                    if can_list_by_organization:
                        if organization_ids and 0 not in organization_ids:
                            for organization_lookup in organization_lookups:
                                lookups['list_lookups'].append(('%s' % organization_lookup, organization_ids))

                can_edit = group_name in loader.permissions_by_scope[model].get('edit', [])
                can_edit_by_role = group_name in loader.permissions_by_scope[model].get('edit_by_role', [])
                can_edit_by_unit = group_name in loader.permissions_by_scope[model].get('edit_by_unit', [])
                can_edit_by_organization = group_name in loader.permissions_by_scope[model].get('edit_by_organization', [])

                if can_edit:
                    lookups['edit_lookups'] = None
                else:
                    if can_edit_by_role:
                        for username_lookup in username_lookups:
                            lookups['edit_lookups'].append((username_lookup, (self.username,)))
                    if can_edit_by_unit and unit_ids:
                        for unit_lookup in unit_lookups:
                            lookups['edit_lookups'].append((unit_lookup, unit_ids))
                    if can_edit_by_organization and organization_ids:
                        for organization_lookup in organization_lookups:
                            lookups['edit_lookups'].append((organization_lookup, organization_ids))

                can_delete = group_name in loader.permissions_by_scope[model].get('delete', [])
                can_delete_by_role = group_name in loader.permissions_by_scope[model].get('delete_by_role', [])
                can_delete_by_unit = group_name in loader.permissions_by_scope[model].get('delete_by_unit', [])
                can_delete_by_organization = group_name in loader.permissions_by_scope[model].get('delete_by_organization', [])

                if can_delete:
                    lookups['delete_lookups'] = None
                else:
                    if can_delete_by_role:
                        for username_lookup in username_lookups:
                            lookups['delete_lookups'].append((username_lookup, (self.username,)))
                    if can_delete_by_unit and unit_ids:
                        for unit_lookup in unit_lookups:
                            lookups['delete_lookups'].append((unit_lookup, unit_ids))
                    if can_delete_by_organization and organization_ids:
                        for organization_lookup in organization_lookups:
                            lookups['delete_lookups'].append((organization_lookup, organization_ids))

                for actions_dict in (loader.actions, loader.class_actions):
                    for category in actions_dict.get(model, ()):
                        for key in actions_dict[model][category].keys():
                            execute_lookups = []
                            view_name = actions_dict[model][category][key]['view_name']
                            can_execute = group_name in loader.permissions_by_scope[model].get('%s' % view_name, [])
                            can_execute_by_role = group_name in loader.permissions_by_scope[model].get('%s_by_role' % view_name, [])
                            can_execute_by_unit = group_name in loader.permissions_by_scope[model].get('%s_by_unit' % view_name, [])
                            can_execute_by_organization = group_name in loader.permissions_by_scope[model].get('%s_by_organization' % view_name, [])
                            if can_execute:
                                execute_lookups = None
                            else:
                                if can_execute_by_role:
                                    for username_lookup in username_lookups:
                                        execute_lookups.append((username_lookup, (self.username,)))
                                if can_execute_by_unit and unit_ids:
                                    for unit_lookup in unit_lookups:
                                        execute_lookups.append((unit_lookup, unit_ids))
                                if can_execute_by_organization and organization_ids:
                                    for organization_lookup in organization_lookups:
                                        execute_lookups.append((organization_lookup, organization_ids))
                            if execute_lookups:
                                if view_name not in lookups:
                                    lookups[view_name] = []
                                lookups[view_name] += execute_lookups

            if loader.permissions_by_scope[model].get('list_by_unit') and not unit_lookups:
                raise Exception('A "lookup" meta-attribute must point to a Unit model in %s' % model)
            if loader.permissions_by_scope[model].get('list_by_organization') and (not organization_lookups and not unit_lookups):
                raise Exception('A "lookup" meta-attribute must point to a Unit or Organization model in %s' % model)
            if loader.permissions_by_scope[model].get('list_by_role') and not role_lookups:
                raise Exception('A "lookup" meta-attribute must point to a role model in %s' % model)

        permission_mapping[permission_mapping_key] = lookups

        self.permission_mapping = json.dumps(permission_mapping)
        self.save()

        return permission_mapping[permission_mapping_key]

    # gieve a set of group or permission names, this method returns the groups the user belongs to
    def find_groups(self, perm_or_group, exclude=None):
        qs = self.groups.all()
        if perm_or_group:
            permissions = []
            groups = []
            for item in perm_or_group:
                if '.' in item:
                    permissions.append(item.split('.')[1])
                else:
                    groups.append(item)
            if permissions:
                qs = qs.filter(permissions__codename__in=permissions)
            if groups:
                qs = qs.filter(name__in=groups)

        if exclude:
            qs = qs.exclude(name=exclude)
        return qs

    def email_user(self, subject, message, from_email=None, **kwargs):
        send_mail(subject, message, from_email, [self.email], **kwargs)