2014-05-04 10 views
10

Attualmente sto creando una struttura in cui ho dipendenti che appartengono a un'azienda. All'interno di questa azienda devo essere in grado di creare diversi gruppi. Classifica se vuoi. Potresti assegnare meno permessi per abbassare i ranghi e più permessi ai ranghi più alti.Gruppi per oggetto utilizzando le autorizzazioni oggetto Django e django-guardian

Desidero ottenere autorizzazioni a livello di oggetto e ho notato che il progetto django-guardian mi ha fornito esattamente ciò di cui avevo bisogno. Funziona con gli oggetti utente e di gruppo nativi, quindi sto cercando di trovare un modo per implementare l'oggetto gruppo nativo in un oggetto aziendale.

I problemi che affronto sono quel nome in gruppo è unico. Quindi se 2 aziende aggiungono lo stesso gruppo, si verificheranno degli errori.

Ho trovato un'implementazione che funziona in un certo modo ma mi sembra abbastanza "hacky". Nella mia azienda ho dichiarato una variabile gruppo che fa riferimento a Gruppo:

class Company(models.Model): 
    ... 
    groups = models.ManyToManyField(Group, through='CompanyRole') 

CompanyRole ospita fondamentalmente il nome del gruppo e un riferimento a società e del gruppo

class CompanyRole(models.Model): 
    group = models.ForeignKey(Group) 
    company = models.ForeignKey(Company) 
    real_name = models.CharField(max_length=60, verbose_name=_('Real name')) 

    objects = CompanyGroupManager() 

ho creato un manager personalizzato con un metodo conveniente per aggiungere un nuovo 'gruppo aziendale'

class CompanyGroupManager(models.Manager): 
    def create_group(self, company, group_name): 
     un_group_name = str(company.id) + '#' + group_name 
     group = Group.objects.create(name=un_group_name) 
     company_group = self.model(
      real_name=group_name, 
      company=company, 
      group=group 
     ) 

     company_group.save(using=self._db) 
     return company_group 

Ecco la parte in cui non mi sento davvero a mio agio. Per modificare il problema con il nome univoco nel modello di gruppo, ho utilizzato una combinazione dell'ID aziendale, un segno cancelletto e il nome effettivo del gruppo per evitare interferenze.

Ora la mia domanda è: ci sono metodi migliori nel mio scenario, mi manca qualcosa o è un buon modo per realizzare ciò di cui ho bisogno?

+0

Puoi usare permessi personalizzati cablati nel tuo modello aziendale invece di gruppi? – Fiver

+0

Fondamentalmente voglio che voglio fare è. In un'azienda, dovresti essere in grado di creare reparti che puoi concedere autorizzazioni globali e autorizzazioni agli oggetti. Supponiamo che tu abbia un dipartimento chiamato programmatori junior, voglio essere in grado di dare loro permessi completi su determinati progetti, ma globalmente concedere loro pochissime autorizzazioni ad altri progetti che vengono creati. È possibile ora ma la mia soluzione sembra piuttosto hacky. Cosa intendi con permessi personalizzati cablati? –

+1

Ciao Jeffrey, voglio dire usare l'attributo Meta 'permessi 'per definire le tue autorizzazioni che puoi controllare. Hai menzionato diversi altri modelli non presenti nel codice, nei progetti e nei reparti pubblicati, quindi sono un po 'incerto sulla struttura del tuo modello. Ma, penso di vedere quello che vuoi realizzare. Aggiungerò una risposta con una configurazione che ho usato in passato. Puoi fornire un elenco di esempio delle autorizzazioni/ruoli che desideri avere per gli utenti? – Fiver

risposta

2

Purtroppo non c'è modo di ottenere intorno al requisito unico, è perché questo campo viene utilizzato come ID: https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.Field.unique

Le opzioni disponibili sono le seguenti:

1) Mocking il modello.

In pratica, è sufficiente creare un nuovo modello di gruppo che non ha il requisito univoco. Il rovescio della medaglia è che avresti bisogno di usarlo ovunque, quindi se questo richiede l'aggiornamento di app di terze parti, potrebbe non valerne la pena.

2) rendere il nome unico. (Come hai fatto tu)

Assicurati di documentare bene la tua convenzione, in modo che tutti i futuri programmatori sappiano cosa stanno guardando. Qualcosa come "nome azienda" # "nome gruppo" potrebbe avere un senso più intuitivo di un ID . Se l'hash può apparire in entrambi, quindi usare un delimitatore più sicuro ("__" è un modo relativamente comune per connettere concetti correlati in django, potrei fare questo).

Si consiglia di aggiungere quanto segue per facilitare l'accesso al nome.

def get_name(self): 
    # Explain how you get the group name from your uniqueified name 
    return self.name.split('#')[1] 

Group.add_to_class('get_name', get_name) 

Quando si accede il nome del vostro gruppo nella vostra applicazione, basta fare:

my_group.get_name() 

si potrebbe anche voler mettere il generare il nome uniqueified in una versione override del save().Questo ti darebbe una divisione più bella tra il modello e la vista ...

+0

Questo è esattamente quello che ho fatto anch'io. :) Tuttavia, lo svantaggio che ho scoperto su questo approccio è il seguente: Ad esempio, hai un modello: MyModel. Con permessi: view_mymodel, change_mymodel, add_mymodel, delete_mymodel. Per visualizzare, modificare ed eliminare permissioni, le aggiungi ad un oggetto e controlla l'autorizzazione (user.has_perm ('view_mymodel', obj)). Ma per aggiungere non puoi e userai user.has_perm ('add_mymodel'). Cosa succede se l'utente per un'organizzazione è in un gruppo con le autorizzazioni di aggiunta e nell'altra organizzazione l'utente è in un gruppo senza? – gabn88