2016-06-11 3 views
0

Users이 있고 각 사용자가 Projects을 만들 수 있다고 가정합니다.Pundit 범위 지정 사용 빈 결과

Show 내 rails 컨트롤러의 동작을 관리자 또는 프로젝트 소유자 만이 Show 작업을 수행 할 수 있도록 제한하려고합니다.

제가 직면 한 문제는 아마도 Pundit에서 Scopes를 사용하는 방법에 대한 오해입니다.

Show 조치는 다음과 같습니다

def show 
    project = policy_scope(Project).find_by({id: project_params[:id]}) 

    if project 
     render json: project 
    else 
     render json: { error: "Not found" }, status: :not_found 
    end 
    end 

내 학자 범위 클래스는 다음과 같습니다 : 내 레일 테스트에서

class Scope < Scope 

    def resolve 
     if @user.admin? 
     scope.all 
     else 
     # obviously, if non-matching user id, an ActiveRelation of 
     # empty array would be returned and subsequent find_by(...) 
     # would fail causing my controller's 'else' to execute 
     # returning 404 instead of 403 
     scope.where(user_id: @user.id) 
     end 
    end 
    end 

, 내가 받아야하는 비 프로젝트 소유자를 주장하는 것을 시도하고있다 a 403 금지됨 :

test "show project should return forbidden if non admin viewing other user's project" do 
    # "rex" here is not the owner of the project 
    get project_path(@project.id), headers: @rex_authorization_header 
    assert_response :forbidden 
end 

내 테스트에 실패했습니다. 오류가 나타납니다 :

Failure: 
ProjectsControllerTest#test_show_project_should_return_forbidden_if_non_admin_viewing_other_user's_project [/Users/zhang/App_Projects/LanceKit/Rails_Project/LanceKit/test/controllers/projects_controller_test.rb:40]: 
Expected response to be a <403: forbidden>, but was a <404: Not Found>. 
Expected: 403 
    Actual: 404 

나는 올바르게 Pundit을 사용하고있는 것 같지 않습니다.

동작에 policy_scope(Project)...을 사용하는 대신 Pundit의 authorize project을 사용해야합니까?

scope.where(...)은 잘못된 사용자 ID를 감지하고 결과를 반환하지 않고 '이 리소스를 볼 수있는 권한이 없습니다.'라는 오류를 반환 할 것으로 예상했습니다.

+0

또한이 Stackoverflow 게시물을 찾았습니다 : http://stackoverflow.com/questions/21172620/why-are-scope-oriented-actions-particularly-index-actions-treated-differen Rob의 대답은 범위를 사용하여 제안하는 것 같습니다. 색인/표시 작업. – Zhang

답변

1

나의 테스트 결과가 나에게 나타내는 바에서 show에 대한 범위를 사용하면 은 (는)입니다.

Pundit 범위는 데이터 집합을 필터링하여 조건과 일치하는 데이터 집합 만 반환한다는 의미이며, current_user가 리소스 소유자인지 여부는 확인하지 않습니다. Pundit 범위가 403 Forbidden 오류를 발생시키지 않습니다.

즉, show 작업에서만 범위 지정을 사용하면 you are not authorized to view this project because it belongs to a different user 대신에 this project with id 3 does not exist in the database과 같은 의미 버그가 발생합니다.

자신을 위해 요약 :

  • 사용 policy_scopeshow에 대한 index 행동
  • 사용 authorize, create, update, delete
  • 사용 authorizepolicy_scope에 대한 당신이 소유자를 자원하지 않는 경우 및 시도

    와 같은 펑키 복수 리소스 경로에 액세스하려면

    get "/user/1/projects" => "Project.index"

    사용자가 프로젝트를 볼 수있는 "프로젝트 관리자"또는 "공동 작업자"인지 여부를 확인하려는 경우에 대비하십시오.이 경우 elsif 절을 사용하여 범위 코드를 수정해야 할 수 있습니다. 이 다음 따라서 예상 (403) 금지 내 테스트는 기대하고있다 오류 및 내 테스트를 제기

    def show 
        project = Project.find_by({id: project_params[:id]}) 
    
        authorize project 
    
        if project 
         render json: project 
        else 
         render json: { error: "Not found" }, status: :not_found 
        end 
        end 
    

    : 내 위의 질문과 관련

, 내 show 행동 안에 authorize를 사용하여 내 프로젝트를 수정 통과합니다.

+0

특정 레코드를 요청하는 프로그램에 액세스 할 때 이에 동의합니다. Pundit 범위는 인덱스 (또는 다른 수집 방법)에서만 의미가 있습니다. – ardochhigh