Modo migliore per applicare le autorizzazioni: controller o vincolo?

Ho un plugin che aggiunge un modello, server, con un campo user_id. Voglio che solo il proprietario del server possa eseguire una POST (o forse dovrebbe essere una PUT? L’azione eseguirà un rebuild da riga di comando di un’istanza di Discourse sul loro server; non sono sicuro di quale sia la migliore pratica.)

In config/routes.rb c’è questo:

post “/upgrade/:id” => “servers#queue_upgrade”, constraints: PfaffmanagerConstraint.new

È consigliabile che matches? in pfaffmanager_constraint.rb controlli path_parameters[:action] e applichi i permessi lì, oppure farlo in servers_controller.rb?

Inoltre, penso che dovrei davvero spostare questa rotta sotto namespace :user, quindi forse dopo aver risolto questo problema, la questione si risolverà come parte di quel processo, ma questo funziona quasi, e vorrei passare a far provare questo codice ad altre persone.

La rotta di Rails è questa:
https://github.com/pfaffman/discourse-pfaffmanager/blob/master/config/routes.rb#L12

E il mio controller tenta di applicare i permessi:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/app/controllers/pfaffmanager/servers_controller.rb#L53-L70

Ma il mio spec restituisce un 200 quando un altro utente esegue la post:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/spec/requests/servers_controller_spec.rb#L149-L157

Immagino di dover in qualche modo far sì che Ember presti attenzione a questo?

1 Mi Piace

Non puoi passare un metodo a before_action per verificare la tua condizione?

1 Mi Piace

Credo che le autorizzazioni debbano essere applicate nel controller o nei vincoli. Il modello non sa chi lo sta chiamando, credo.

Grazie mille per averci pensato.

1 Mi Piace

Credo che tu abbia bisogno di un metodo di guardia per verificare se un utente è autorizzato a eseguire una determinata azione. Ad esempio, can_upgrade_server?

Inoltre, una volta fatto ciò, puoi utilizzare il metodo guardian.ensure_can_upgrade_server! che verifica la condizione e solleva un’eccezione, il che, a mio avviso, è esattamente ciò che desideri.

2 Mi Piace

Oh, il metodo Guardian! Sì! Ci darò un’occhiata! Grazie.

2 Mi Piace

L’unico modello che utilizza guardian è il modello user. Sembra che la maggior parte delle operazioni con guardian avvenga nei controller.

Ad esempio, il controller delle categorie utilizza ensure_can_create_category, che credo venga creato magicamente in lib/guardian.rb.

Ma per ora, non sto utilizzando guardian perché ho difficoltà a capire come istanziarlo correttamente. Nel mio controller ho questo:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/app/controllers/pfaffmanager/servers_controller.rb#L54-L75

E qui ci sono gli spec che lo testano:

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/spec/requests/servers_controller_spec.rb#L154-L181