2016-11-24 26 views
0

假設我有三種環回模式:閱讀器,書本和備註。 。Reader是用戶的一個實例,可以登錄的關係是這樣的:環回中的訪問控制包括過濾器

  • 閱讀器有許多書籍
  • 閱讀器有許多注意事項
  • 書有許多注意事項
  • 注屬於讀者
  • 筆記本屬於書

我想實現的是查詢所有已登錄閱讀器的書籍,並填寫屬於本書的註釋和讀者。

API調用看起來就像是:

/api/reader/me/books?filter[include]=notes 

但不管它們是否屬於讀者這個返回所有屬於書的筆記。我可以在api調用中添加另一個過濾器,但我需要在服務器端過濾Notes,以便讀者無法訪問其他讀者的筆記。

我試圖添加此訪問控制Book模型:

{ 
    "principalType": "ROLE", 
    "principalId": "$owner", 
    "permission": "ALLOW", 
    "property": "__get__notes" 
} 

和該ACL注意模型

[ 
    { 
     "principalType": "ROLE", 
     "principalId": "$everyone", 
     "permission": "DENY" 
    }, { 
     "principalType": "ROLE", 
     "principalId": "$owner", 
     "permission": "ALLOW", 
     "property": "*" 
    } 
] 

它非常適合這樣的

/api/reader/me/books/<bookId>/notes 
電話

但不適用於包含過濾器的第一次調用。我應該怎麼做才能讓讀者的筆記充滿書本?

任何幫助非常感謝。

+0

我有一個類似的問題,我需要限制或允許基於每個實例的訪問,而不是SL中使用的每個模型基礎。不幸的是,我沒有找到一個合適的方式來做到這一點,並不得不實施我自己的授權層。然而,你可以做的一件事是在afterRemote鉤子上進行一個簡單的過濾,這樣你可以進行某種減法操作,只返回那些你可以訪問的實例。在我的情況下,這是不可能的,因爲我需要用戶A的實例可以被用戶B訪問。但這不是你的情況,所以它可能工作。 – Acapulco

+0

你可以在這裏閱讀文檔 - https://loopback.io/doc/en/lb2/Remote-hooks.html - 這不是直截了當,可能不是很有效,雖然 – Acapulco

回答

0

要實現這一點,您必須創建一個遠程方法。您必須在應用程序級別應用過濾器。

假設用戶的細節是存放在User模型

module.exports = function(Reader){ 

    var async = require('async'); 
    Reader.fetchBooks = function(userId, callback){ 
     var app = this.app; 
     var updatedReaderList = []; 
     Reader.find({ 
      where: {userId: userId }, 
      include: {relation: "books"} 
     }, function(err, readerList){ 
      if(err){ 
       return callback(err); 
      } 
      if(readerList){ 
       if(readerList.length){ 
        var series = []; 
        readerList.forEach(function(reader){ 
         var readerObj = reader.toJSON(); 
         updatedReaderList.push(readerObj); 
         if(readerObj.books){ 
          readerObj.books.forEach(function(book){ 
           series.push(function(callback){ 
           fetchNotes(app, book, readerObj.id, callback); 
           }); 
          } 
         } 
        }); 

        //Now save the data in series.. 
        async.series(series, function(err){ 
         if(err){ 
          callback(err); 
         }else{ 

          //Now send the callback 
          callback(null, updatedReaderList); 
         } 
        }); 

       }else{ 
        callback(null, []) 
       } 
      }else{ 
       callback(null, []) 
      } 
     }); 


    }; 

    var fetchNotes = function(app, book, readerId, callback){ 
     var Note = app.models.Note; 
     //Fetch only those note whose reader id belongs to current reader and book belongs to same one. 
     Note.find({ 
      where: { 
      readerId: readerId, 
      bookId: book.id 
      } 
     }, function(err, noteList){ 
      if(err){ 
      return callback(err); 
      }else{ 
      if(noteList){ 
       book.notes = noteList; 
      } 
      } 
     }); 
    }; 
} 

現在,您可以限制其他所有方法,簡單地允許這種遠程方法。

{ 
    "principalType": "ROLE", 
    "principalId": "$owner", 
    "permission": "ALLOW", 
    "property": "fetchBooks" 
} 

注意:您可以使用promise來刪除回調地獄。