2012-09-27 55 views
0

我目前的工作在Grails的一個解決方案,我已經安裝了以下安全插件:Spring Security UI Grails僅爲管理員搜索/創建/編輯用戶?

  • Spring Security的核心
  • Spring Security的UI

我基本上都會有如下的解決方案安全結構:

  • 超級用戶
  • 廣告分鐘(對於不同的業務領域)
  • 用戶(在不同的業務領域內)

所以基本上我爲了讓各個業務領域管理員管理他們自己的地區安裝了Spring Security的用戶界面,他們應該能夠要使用用戶界面以允許他們僅搜索自己區域的用戶,在他們自己的區域創建用戶並僅在他們自己的區域編輯用戶。然而,春季安全界面讓那些有權訪問的人可以做任何事情。

我已經爲彈簧安全域模型添加了一個額外的字段,它是「區域」,所以我一直在想當管理員搜索用戶時,他們只會看到用戶與他們在同一區域,當他們創建用戶他們只能爲自己的區域這樣做,他們只能在自己的區域編輯用戶。

以下是春季安全用戶界面用於搜索用戶的一些代碼,我可以修改此代碼以僅返回與當前登錄的管理員位於同一區域的用戶嗎?或者,還有更好的方法?

def userSearch = { 

    boolean useOffset = params.containsKey('offset') 
    setIfMissing 'max', 10, 100 
    setIfMissing 'offset', 0 

    def hql = new StringBuilder('FROM ').append(lookupUserClassName()).append(' u WHERE 1=1 ') 
    def queryParams = [:] 

    def userLookup = SpringSecurityUtils.securityConfig.userLookup 
    String usernameFieldName = userLookup.usernamePropertyName 

    for (name in [username: usernameFieldName]) { 
     if (params[name.key]) { 
      hql.append " AND LOWER(u.${name.value}) LIKE :${name.key}" 
      queryParams[name.key] = params[name.key].toLowerCase() + '%' 
     } 
    } 

    String enabledPropertyName = userLookup.enabledPropertyName 
    String accountExpiredPropertyName = userLookup.accountExpiredPropertyName 
    String accountLockedPropertyName = userLookup.accountLockedPropertyName 
    String passwordExpiredPropertyName = userLookup.passwordExpiredPropertyName 

    for (name in [enabled: enabledPropertyName, 
        accountExpired: accountExpiredPropertyName, 
        accountLocked: accountLockedPropertyName, 
        passwordExpired: passwordExpiredPropertyName]) { 
     Integer value = params.int(name.key) 
     if (value) { 
      hql.append " AND u.${name.value}=:${name.key}" 
      queryParams[name.key] = value == 1 
     } 
    } 

    int totalCount = lookupUserClass().executeQuery("SELECT COUNT(DISTINCT u) $hql", queryParams)[0] 

    Integer max = params.int('max') 
    Integer offset = params.int('offset') 

    String orderBy = '' 
    if (params.sort) { 
     orderBy = " ORDER BY u.$params.sort ${params.order ?: 'ASC'}" 
    } 

    def results = lookupUserClass().executeQuery(
      "SELECT DISTINCT u $hql $orderBy", 
      queryParams, [max: max, offset: offset]) 
    def model = [results: results, totalCount: totalCount, searched: true] 

    // add query params to model for paging 
    for (name in ['username', 'enabled', 'accountExpired', 'accountLocked', 
        'passwordExpired', 'sort', 'order']) { 
     model[name] = params[name] 
    } 

    render view: 'search', model: model 
} 

編輯....

我認爲它可能是與下面的代碼:

def results = lookupUserClass().executeQuery(
      "SELECT DISTINCT u $hql $orderBy", 
      queryParams, [max: max, offset: offset]) 

我想我只需要使它看起來爲改變這一聲明當前登錄的用戶「區域」等於與用戶相同的區域的用戶列表。任何人都可以請幫助我嗎?

EDIT 2 .....

我現在看着這一點,並已經能夠獲得用戶的地區,現在ALLS我需要做的就是修改查詢到數據庫中查找用戶與管理員搜索具有相同的區域。我已經試過,沒有運氣以下,可有人請幫助我這個,因爲我知道這一定是簡單的只是不能似乎那裏:-S

 def user = springSecurityService.currentUser 
     def userArea = user.area 

     def hql = new StringBuilder('FROM ').append(lookupUserClassName()).append(' u WHERE 1=1 AND u.area = userArea') 

編輯3 .......

感謝我的問題這麼多一半就解決了笑,現在只是阿賈克斯片:

我曾嘗試下面的代碼,以修改搜索爲Ajax功能只返回結果,其中的片區用戶是一樣的當前登錄的用戶:

String username = params.term 
      String usernameFieldName = SpringSecurityUtils.securityConfig.userLookup.usernamePropertyName 
      def user = springSecurityService.currentUser 

      setIfMissing 'max', 10, 100 

      def results = lookupUserClass().executeQuery(
        "SELECT DISTINCT u.$usernameFieldName " + 
        "FROM ${lookupUserClassName()} u " + 
        "WHERE LOWER(u.$usernameFieldName) LIKE :name AND LOWER(u.area) = :area " + 
        "ORDER BY u.$usernameFieldName", 
        [name: "${username.toLowerCase()}%"], 
        [area: "user.area"], 
        [max: params.max]) 

還試圖改變PARAM如下:

[area: user.area] 
+0

任何人都可以請幫我這個我只是需要一種方法來找出區(這存在着如春的安全域模型的字符串)當前記錄哪些用戶是然後修改該MYSQL命令以僅查找同一區域的用戶? – user723858

回答

1

該控制器建立一個HQL查詢,所以你不能只是說「WHERE u.area = userArea」,你需要使用一個命名參數,並把該值在queryParams地圖

def user = springSecurityService.currentUser 

    def hql = new StringBuilder('FROM ').append(lookupUserClassName()).append(
     ' u WHERE u.area = :userArea ') 
    def queryParams = [userArea:user.area] 

對於問題(阿賈克斯位),我懷疑的第二部分你需要的LOWER轉換,你也需要把你所有的查詢參數到一個地圖(第二個地圖參數僅做分頁設置):

def results = lookupUserClass().executeQuery(
    "SELECT DISTINCT u.$usernameFieldName " + 
    "FROM ${lookupUserClassName()} u " + 
    "WHERE LOWER(u.$usernameFieldName) LIKE :name AND u.area = :area " + 
    "ORDER BY u.$usernameFieldName", 
    [name: "${username.toLowerCase()}%", area:user.area], 
    [max: params.max]) 

如果你確實想area檢查以案例 - unsense然後離開它作爲LOWER(u.area) = :area但你也需要轉換你的值再對小寫測試:

[name: "${username.toLowerCase()}%", area:user.area.toLowerCase()], 
+0

非常感謝你,似乎已經解決了我的問題的第一部分:-)現在我只需修改Ajax元素以基於相同的參數進行更新。詳情請參閱我的文章中的編輯,我非常感謝幫助:-) – user723858

+0

@ user723858看到我最新的編輯。 –

+0

你是一個拯救生命的人:-) – user723858

相關問題