class Log(models.Model): ADD = 1 EDIT = 2 DELETE = 3 OPERATION_CHOICES = [[ADD, u'Cadastro'], [EDIT, u'Edição'], [DELETE, u'Exclusão']] content_type = models.ForeignKey(ContentType, verbose_name=u'Objeto', filter=True) operation = models.IntegerField(verbose_name=u'Operação', choices=OPERATION_CHOICES, filter=True) user = models.ForeignKey('admin.User', filter=True) date = models.DateTimeField(verbose_name=u'Data/Hora', auto_now=True, filter=True) object_id = models.IntegerField(verbose_name=u'Identificador', search=True) object_description = models.CharField(verbose_name=u'Descrição do Objeto') content = models.TextField(verbose_name=u'Conteúdo', null=True) fieldsets = ( (u'Dados Gerais', {'fields': ( ('content_type', 'operation'), ('user', 'date'), ('object_id', 'object_description'), 'get_tags')}), (u'Índices', {'relations': ('logindex_set',)}), ) objects = models.Manager() class Meta: verbose_name = u'Log' verbose_name_plural = u'Logs' icon = 'fa-history' list_per_page = 25 def __unicode__(self): return 'Log #%s' % self.pk def can_add(self): return False def can_edit(self): return False def can_delete(self): return False def get_action_description(self): return (u'adicionou', u'editou', u'removeu')[self.operation - 1] def get_style(self): return ('success', 'info', 'danger')[self.operation - 1] def get_icon(self): return ('plus', 'pencil', 'trash-o')[self.operation - 1] @meta(u'Tags', formatter='log_tags') def get_tags(self): return json.loads(self.content) def create_indexes(self, instance): for log_index in get_metadata(instance.__class__, 'logging', (), iterable=True): index_object = getattr2(instance, log_index) if index_object: index_content_type = ContentType.objects.get_for_model(index_object.__class__) LogIndex.objects.create(log=self, content_type=index_content_type, object_id=index_object.pk)
class Log(models.Model): ADD = 1 EDIT = 2 DELETE = 3 OPERATION_CHOICES = [[ADD, _('Add')], [EDIT, _('Edit')], [DELETE, _('Delete')]] content_type = models.ForeignKey(ContentType, verbose_name=_('Content Type'), filter=True) operation = models.IntegerField(verbose_name=_('Operation'), choices=OPERATION_CHOICES, filter=True) user = models.ForeignKey('admin.User', filter=True, verbose_name=_('User')) date = models.DateTimeField(verbose_name=_('Date/Time'), auto_now=True, filter=True) object_id = models.IntegerField(verbose_name=_('Identifier'), search=True) object_description = models.CharField(verbose_name=_('Object Description')) content = models.TextField(verbose_name=_('Content'), null=True) fieldsets = ( (_('General Data'), {'fields': ( ('content_type', 'operation'), ('user', 'date'), ('object_id', 'object_description'), 'get_tags')}), (_('Indexes'), {'relations': ('logindex_set',)}), ) objects = models.Manager() class Meta: verbose_name = _('Log') verbose_name_plural = _('Logs') icon = 'fa-history' list_per_page = 25 def __str__(self): return 'Log #{}'.format(self.pk) def can_add(self): return False def can_edit(self): return False def can_delete(self): return False def get_action_description(self): return (_('added'), _('edited'), _('deleted'))[self.operation - 1] def get_style(self): return ('success', 'info', 'danger')[self.operation - 1] def get_icon(self): return ('plus', 'pencil', 'trash-o')[self.operation - 1] @meta('Tags') def get_tags(self): return json.loads(self.content) def create_indexes(self, instance): for log_index in get_metadata(instance.__class__, 'logging', (), iterable=True): index_object = getattr2(instance, log_index) if index_object: index_content_type = ContentType.objects.get_for_model(index_object.__class__) LogIndex.objects.create(log=self, content_type=index_content_type, object_id=index_object.pk)
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
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)
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
class Log(models.Model): ADD = 1 EDIT = 2 DELETE = 3 OPERATION_CHOICES = [[ADD, _('Add')], [EDIT, _('Edit')], [DELETE, _('Delete')]] content_type = models.ForeignKey(ContentType, verbose_name=_('Content Type'), filter=True) operation = models.IntegerField(verbose_name=_('Operation'), choices=OPERATION_CHOICES, filter=True) user = models.ForeignKey('admin.User', filter=True, verbose_name=_('User')) date = models.DateTimeField(verbose_name=_('Date/Time'), auto_now=True, filter=True) object_id = models.IntegerField(verbose_name=_('Identifier'), search=True) object_description = models.CharField(verbose_name=_('Object Description')) content = models.TextField(verbose_name=_('Content'), null=True, search=True) fieldsets = ( (_('General Data'), {'fields': ( ('content_type', 'operation'), ('user', 'date'), ('object_id', 'object_description'), 'get_tags')}), (_('Indexes'), {'relations': ('logindex_set',), 'condition': 'has_index'}), ) objects = models.Manager() class Meta: verbose_name = _('Log') verbose_name_plural = _('Logs') icon = 'fa-history' list_per_page = 25 list_display = 'content_type', 'object_id', 'operation', 'user', 'date', 'get_tags' order_by = '-date' def __str__(self): return 'Log #{}'.format(self.pk) def can_add(self): return False def can_edit(self): return False def can_delete(self): return False def has_index(self): return self.logindex_set.exists() def get_action_description(self): return (_('added'), _('edited'), _('deleted'))[self.operation - 1] def get_style(self): return ('success', 'info', 'danger')[self.operation - 1] def get_icon(self): return ('plus', 'pencil', 'trash-o')[self.operation - 1] @meta('Alterações') def get_tags(self): data = [] for attr, old, new in json.loads(self.content): data.append('{} : {} >> {}'.format(attr, old, new)) for log_index in self.logindex_set.all(): date = datetime.datetime( log_index.log.date.year, log_index.log.date.month, log_index.log.date.day, log_index.log.date.hour, log_index.log.date.minute, log_index.log.date.second ) qs = Log.objects.filter( content_type=log_index.content_type, user=log_index.log.user, date__startswith=date, object_id=log_index.object_id ) for log in qs: for attr, old, new in json.loads(log.content): data.append('{} : {} >> {}'.format(attr, old, new)) return ' | '.join(data) def create_indexes(self, instance): for log_index in get_metadata(instance.__class__, 'logging', (), iterable=True): index_object = getattr2(instance, log_index) if index_object: index_content_type = ContentType.objects.get_for_model(index_object.__class__) LogIndex.objects.create(log=self, content_type=index_content_type, object_id=index_object.pk)
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)
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
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)