Skip to content

Commit

Permalink
Add more specs when the verified personal information is missing
Browse files Browse the repository at this point in the history
Allow testing if the profile GraphQL API is not returning the
personal verified information and add specs testing these cases.
  • Loading branch information
ahukkanen committed Dec 8, 2023
1 parent ea08a53 commit cfe83d5
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,33 @@ module HelsinkiProfile
module Test
module GdprGraphql
class AuthorizedField < GraphQL::Schema::Field
def initialize(*args, required_permission: nil, **kwargs, &block)
@required_permission = required_permission
# Pass on the default args:
super(*args, **kwargs, &block)
end

def to_graphql
field_defn = super # Returns a GraphQL::Field
field_defn.metadata[:required_permission] = @required_permission
field_defn
end

def authorized?(obj, args, ctx)
super && ctx[:current_profile].present?
return false unless super
return false if ctx[:current_profile].blank?
return false unless permission_satisfied?(ctx)

true
end

private

def permission_satisfied?(ctx)
return true if @required_permission.blank?
return false if ctx[:permissions].blank?

ctx[:permissions][@required_permission]
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/decidim/helsinki_profile/test/gdpr_graphql/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def self.unauthorized_object(error)

def self.error_to_code(error)
case error
when GraphQL::UnauthorizedFieldError
when GraphQL::UnauthorizedFieldError, GraphQL::UnauthorizedError
"PERMISSION_DENIED_ERROR"
else
"GENERAL_ERROR"
Expand Down
20 changes: 19 additions & 1 deletion lib/decidim/helsinki_profile/test/gdpr_graphql/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def request(req)
end

def execute(query, variables: {}, operation_name: nil, current_profile: nil)
context = { current_profile: current_profile }
context = { current_profile: current_profile, permissions: permissions }

Schema.execute(query, variables: variables, operation_name: operation_name, context: context)
end
Expand All @@ -44,6 +44,14 @@ def authenticate(authorization)
nil
end

def reset_permissions
@permissions = default_permissions
end

def set_permission(key, value)
permissions[key] = value
end

def reset_profiles
@profiles = {}
end
Expand All @@ -62,6 +70,16 @@ def profile(uuid)

private

def permissions
@permissions ||= default_permissions

@permissions
end

def default_permissions
{ verified_information: true }
end

def oidc
@oidc ||= Decidim::HelsinkiProfile::Oidc::Connector.new(:auth)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ module GdprGraphql
class ProfileNode < Decidim::Api::Types::BaseObject
graphql_name "ProfileNode"

field_class AuthorizedField

field :id, GraphQL::Types::ID, null: false
field :first_name, GraphQL::Types::String, null: false
field :last_name, GraphQL::Types::String, null: false
field :nickname, GraphQL::Types::String, null: false
field :language, GraphQL::Types::String, null: true
field :primary_email, EmailNode, null: true
field :primary_address, AddressNode, null: true
field :verified_personal_information, VerifiedPersonalInformationNode, null: true
field :verified_personal_information, VerifiedPersonalInformationNode, null: true, required_permission: :verified_information
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
let(:oauth_raw_info) { base_oauth_raw_info }
let(:base_oauth_raw_info) do
{
sub: oauth_uid,
name: "Marja Mirja Mainio",
given_name: "Marja",
family_name: "Mainio",
Expand Down Expand Up @@ -167,6 +168,26 @@
it "returns true for valid authentication data" do
expect(subject.validate!).to be(true)
end

context "when user identifier is blank" do
let(:oauth_uid) { nil }

it "raises a validation error" do
expect { subject.validate! }.to raise_error(
Decidim::HelsinkiProfile::Authentication::ValidationError
)
end
end

context "when the sub field is not available at the OAuth raw info" do
let(:oauth_raw_info) { base_oauth_raw_info.merge(sub: nil) }

it "raises a validation error" do
expect { subject.validate! }.to raise_error(
Decidim::HelsinkiProfile::Authentication::ValidationError
)
end
end
end

describe "#identify_user!" do
Expand Down Expand Up @@ -263,6 +284,37 @@
)
end

context "when the profile API does not return verified user information" do
let(:oauth_raw_info) do
{
name: "Marja Mirja Mainio",
given_name: "Marja",
family_name: "Mainio"
}
end

before do
gdpr_api.set_permission(:verified_information, false)
end

it "authorizes the user with limited information" do
auth = subject.authorize_user!(user)

expect(Decidim::Authorization.count).to eq(1)
expect(Decidim::Authorization.last.id).to eq(auth.id)
expect(auth.metadata).to eq(
"service" => ["suomi_fi"],
"name" => oauth_raw_info[:name],
"first_name" => oauth_raw_info[:given_name],
"given_name" => oauth_raw_info[:given_name],
"last_name" => oauth_raw_info[:family_name],
"ad_groups" => nil,
"permanent_address" => false
)
expect(auth.pseudonymized_pin).to be_nil
end
end

context "when an authorization already exists" do
let!(:authorization) do
Decidim::Authorization.create!(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,47 @@
gdpr_api.register_profile(profile)
end

it "runs the GDPR query" do
it "runs the GraphQL query" do
expect(response.code).to eq("200")
expect(response_data).to eq(
"myProfile" => { "id" => profile[:id], "firstName" => profile[:first_name] }
)
expect(response_errors).to be_nil
end

context "with verifiedPersonalInformation" do
let(:query) { "myProfile { verifiedPersonalInformation { firstName } }" }

it "runs the GraphQL query" do
expect(response.code).to eq("200")
expect(response_data).to eq(
"myProfile" => { "verifiedPersonalInformation" => { "firstName" => profile[:first_name] } }
)
expect(response_errors).to be_nil
end

context "when access is not permitted" do
before do
gdpr_api.set_permission(:verified_information, false)
end

it "returns an error" do
expect(response.code).to eq("200")
expect(response_data).to eq(
"myProfile" => { "verifiedPersonalInformation" => nil }
)
expect(response_errors).to eq(
[
{
"message" => "You do not have permission to perform this action.",
"locations" => [{ "line" => 1, "column" => 15 }],
"path" => %w(myProfile verifiedPersonalInformation),
"extensions" => { "code" => "PERMISSION_DENIED_ERROR" }
}
]
)
end
end
end

context "when the auth token is incorrect" do
Expand Down
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
auth_server = Decidim::HelsinkiProfile::Test::OidcServer.get(:auth)
gdpr_api = Decidim::HelsinkiProfile::Test::GdprGraphql::Server.instance

gdpr_api.reset_permissions
gdpr_api.reset_profiles

# Endpoints that are common for OICD servers
Expand Down

0 comments on commit cfe83d5

Please sign in to comment.