add declared_user_type
closes FOO-2318, FOO-2319, FOO-2320 test plan: * verify that /api/v1/users/self/logins includes the declared_user_type * use PUT /api/v1/users/self/logins/:id to update the declared_user_type; verify it changes Change-Id: I1e43ab6ead5515b113b1949bdda544b2b5c6834f Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/273647 Reviewed-by: Simon Williams <simon@instructure.com> Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> QA-Review: Cody Cutrer <cody@instructure.com> Product-Review: Cody Cutrer <cody@instructure.com>
This commit is contained in:
parent
f65c11a10b
commit
6e04277c3a
|
@ -42,6 +42,7 @@ class PseudonymsController < ApplicationController
|
|||
# @response_field authentication_provider_type The type of the authentication
|
||||
# provider that this login is associated with
|
||||
# @response_field workflow_state The current status of the login
|
||||
# @response_field declared_user_type The declared intention for this user's role
|
||||
#
|
||||
# @example_response
|
||||
# [
|
||||
|
@ -53,7 +54,8 @@ class PseudonymsController < ApplicationController
|
|||
# "user_id": 2,
|
||||
# "authentication_provider_id": 1,
|
||||
# "authentication_provider_type": "facebook",
|
||||
# "workflow_state": "active"
|
||||
# "workflow_state": "active",
|
||||
# "declared_user_type": null,
|
||||
# }
|
||||
# ]
|
||||
def index
|
||||
|
@ -218,6 +220,21 @@ class PseudonymsController < ApplicationController
|
|||
# provider, or the type of the provider (in which case, it will find the
|
||||
# first matching provider).
|
||||
#
|
||||
# @argument login[declared_user_type] [String]
|
||||
# The declared intention of the user type. This can be set, but does
|
||||
# not change any Canvas functionality with respect to their access.
|
||||
# A user can still be a teacher, admin, student, etc. in any particular
|
||||
# context without regard to this setting. This can be used for
|
||||
# administrative purposes for integrations to be able to more easily
|
||||
# identify why the user was created.
|
||||
# Valid values are:
|
||||
# * administrative
|
||||
# * observer
|
||||
# * staff
|
||||
# * student
|
||||
# * student_other
|
||||
# * teacher
|
||||
#
|
||||
# @example_request
|
||||
#
|
||||
# #create a facebook login for user with ID 123
|
||||
|
@ -310,6 +327,21 @@ class PseudonymsController < ApplicationController
|
|||
# @argument login[workflow_state] [String, "active"|"suspended"]
|
||||
# Used to suspend or re-activate a login.
|
||||
#
|
||||
# @argument login[declared_user_type] [String]
|
||||
# The declared intention of the user type. This can be set, but does
|
||||
# not change any Canvas functionality with respect to their access.
|
||||
# A user can still be a teacher, admin, student, etc. in any particular
|
||||
# context without regard to this setting. This can be used for
|
||||
# administrative purposes for integrations to be able to more easily
|
||||
# identify why the user was created.
|
||||
# Valid values are:
|
||||
# * administrative
|
||||
# * observer
|
||||
# * staff
|
||||
# * student
|
||||
# * student_other
|
||||
# * teacher
|
||||
#
|
||||
# @example_request
|
||||
# curl https://<canvas>/api/v1/accounts/:account_id/logins/:login_id \
|
||||
# -H "Authorization: Bearer <ACCESS-TOKEN>" \
|
||||
|
@ -326,6 +358,7 @@ class PseudonymsController < ApplicationController
|
|||
# "integration_id": null,
|
||||
# "authentication_provider_id": null,
|
||||
# "workflow_state": "active",
|
||||
# "declared_user_type": "teacher"
|
||||
# }
|
||||
def update
|
||||
if api_request?
|
||||
|
@ -423,6 +456,7 @@ class PseudonymsController < ApplicationController
|
|||
:authentication_provider_id,
|
||||
:integration_id,
|
||||
:workflow_state,
|
||||
:declared_user_type
|
||||
).blank?
|
||||
render json: nil, status: :bad_request
|
||||
return false
|
||||
|
@ -441,6 +475,10 @@ class PseudonymsController < ApplicationController
|
|||
@pseudonym.authentication_provider = params[:pseudonym][:authentication_provider]
|
||||
end or return false
|
||||
|
||||
has_right_if_requests_change(:declared_user_type, :update) do
|
||||
@pseudonym.declared_user_type = params[:pseudonym][:declared_user_type]
|
||||
end or return false
|
||||
|
||||
has_right_if_requests_change(:sis_user_id, :manage_sis) do
|
||||
# convert "" -> nil for sis_user_id
|
||||
@pseudonym.sis_user_id = params[:pseudonym][:sis_user_id].presence
|
||||
|
|
|
@ -49,6 +49,9 @@ class Pseudonym < ActiveRecord::Base
|
|||
end
|
||||
before_validation :validate_unique_id
|
||||
before_destroy :retire_channels
|
||||
validates :declared_user_type,
|
||||
allow_nil: true,
|
||||
inclusion: { in: %w[administrative observer staff student student_other teacher] }
|
||||
|
||||
before_save :set_password_changed
|
||||
before_validation :infer_defaults, :verify_unique_sis_user_id, :verify_unique_integration_id
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
#
|
||||
# Copyright (C) 2021 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class AddDeclaredUserTypeToPseudonyms < ActiveRecord::Migration[6.0]
|
||||
tag :predeploy
|
||||
|
||||
def change
|
||||
add_column :pseudonyms, :declared_user_type, :string, limit: 255
|
||||
end
|
||||
end
|
|
@ -20,19 +20,22 @@
|
|||
module Api::V1::Pseudonym
|
||||
include Api::V1::Json
|
||||
|
||||
API_PSEUDONYM_JSON_OPTS = [:id,
|
||||
:user_id,
|
||||
:account_id,
|
||||
:unique_id,
|
||||
:sis_user_id,
|
||||
:integration_id,
|
||||
:authentication_provider_id,
|
||||
:created_at,
|
||||
:workflow_state].freeze
|
||||
API_PSEUDONYM_JSON_OPTS = %i[id
|
||||
user_id
|
||||
account_id
|
||||
unique_id
|
||||
sis_user_id
|
||||
integration_id
|
||||
authentication_provider_id
|
||||
created_at
|
||||
workflow_state
|
||||
declared_user_type].freeze
|
||||
|
||||
def pseudonym_json(pseudonym, current_user, session)
|
||||
opts = API_PSEUDONYM_JSON_OPTS
|
||||
opts = opts.reject { |opt| [:sis_user_id, :integration_id].include?(opt) } unless pseudonym.account.grants_any_right?(current_user, :read_sis, :manage_sis)
|
||||
opts = API_PSEUDONYM_JSON_OPTS.dup
|
||||
opts -= %i[sis_user_id integration_id] unless pseudonym.account.grants_any_right?(
|
||||
current_user, :read_sis, :manage_sis
|
||||
)
|
||||
api_json(pseudonym, current_user, session, :only => opts).tap do |result|
|
||||
if pseudonym.authentication_provider
|
||||
result[:authentication_provider_type] = pseudonym.authentication_provider.auth_type
|
||||
|
|
|
@ -167,6 +167,7 @@ describe "AuthenticationAudit API", type: :request do
|
|||
"integration_id" => nil,
|
||||
"authentication_provider_id" => nil,
|
||||
"workflow_state" => "active",
|
||||
"declared_user_type" => nil
|
||||
}]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -49,6 +49,7 @@ describe PseudonymsController, type: :request do
|
|||
'user_id' => p.user_id,
|
||||
'created_at' => p.created_at,
|
||||
'workflow_state' => 'active',
|
||||
'declared_user_type' => nil
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
@ -145,7 +146,8 @@ describe PseudonymsController, type: :request do
|
|||
:login => {
|
||||
:password => 'abcd1234',
|
||||
:sis_user_id => '12345',
|
||||
:unique_id => 'test@example.com'
|
||||
:unique_id => 'test@example.com',
|
||||
:declared_user_type => 'teacher',
|
||||
}
|
||||
})
|
||||
expect(json).to eq({
|
||||
|
@ -158,6 +160,7 @@ describe PseudonymsController, type: :request do
|
|||
'user_id' => @student.id,
|
||||
'created_at' => json['created_at'],
|
||||
'workflow_state' => 'active',
|
||||
'declared_user_type' => 'teacher'
|
||||
})
|
||||
end
|
||||
|
||||
|
@ -259,7 +262,8 @@ describe PseudonymsController, type: :request do
|
|||
:login => {
|
||||
:unique_id => 'student+new@example.com',
|
||||
:password => 'password123',
|
||||
:sis_user_id => 'new-12345'
|
||||
:sis_user_id => 'new-12345',
|
||||
:declared_user_type => 'teacher',
|
||||
}
|
||||
})
|
||||
expect(json).to eq({
|
||||
|
@ -272,6 +276,7 @@ describe PseudonymsController, type: :request do
|
|||
'user_id' => @student.id,
|
||||
'created_at' => @student.pseudonym.created_at.iso8601,
|
||||
'workflow_state' => 'active',
|
||||
'declared_user_type' => 'teacher'
|
||||
})
|
||||
expect(@student.pseudonym.reload.valid_password?('password123')).to be_truthy
|
||||
end
|
||||
|
@ -292,6 +297,11 @@ describe PseudonymsController, type: :request do
|
|||
expect(response.code).to eql '400'
|
||||
end
|
||||
|
||||
it 'ignores invalid declared_user_types' do
|
||||
raw_api_call(:put, @path, @path_options, { login: { declared_user_type: 'ta' } })
|
||||
expect(response.code).to eql '400'
|
||||
end
|
||||
|
||||
it "returns 400 if the unique_id already exists" do
|
||||
raw_api_call(:put, @path, @path_options, {
|
||||
:login => {
|
||||
|
@ -439,6 +449,7 @@ describe PseudonymsController, type: :request do
|
|||
'user_id' => @student.id,
|
||||
'created_at' => pseudonym.created_at.iso8601,
|
||||
'workflow_state' => 'deleted',
|
||||
'declared_user_type' => nil
|
||||
})
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue