2011-02-01 09:57:29 +08:00
#
# Copyright (C) 2011 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/>.
#
module SIS
2011-10-13 07:28:30 +08:00
class UserImporter < BaseImporter
2011-02-01 09:57:29 +08:00
2011-09-07 02:07:54 +08:00
def process ( updates_every , messages )
start = Time . now
importer = Work . new ( @batch_id , @root_account , @logger , updates_every , messages )
User . skip_updating_account_associations do
2011-10-13 07:28:30 +08:00
User . process_as_sis ( @sis_options ) do
Pseudonym . process_as_sis ( @sis_options ) do
2011-10-11 06:31:18 +08:00
yield importer
while importer . any_left_to_process?
importer . process_batch
end
2011-09-22 01:36:45 +08:00
end
2011-02-01 09:57:29 +08:00
end
end
2011-09-07 02:07:54 +08:00
User . update_account_associations ( importer . users_to_add_account_associations , :incremental = > true , :precalculated_associations = > { @root_account . id = > 0 } )
User . update_account_associations ( importer . users_to_update_account_associations )
2013-03-19 23:49:31 +08:00
Pseudonym . where ( :id = > importer . pseudos_to_set_sis_batch_ids ) . update_all ( :sis_batch_id = > @batch_id ) if @batch && ! importer . pseudos_to_set_sis_batch_ids . empty?
2011-09-07 02:07:54 +08:00
@logger . debug ( " Users took #{ Time . now - start } seconds " )
return importer . success_count
2011-02-01 09:57:29 +08:00
end
2011-09-07 02:07:54 +08:00
private
class Work
attr_accessor :success_count , :users_to_set_sis_batch_ids ,
:pseudos_to_set_sis_batch_ids , :users_to_add_account_associations ,
:users_to_update_account_associations
def initialize ( batch_id , root_account , logger , updates_every , messages )
@batch_id = batch_id
@root_account = root_account
@logger = logger
@updates_every = updates_every
@batched_users = [ ]
@messages = messages
@success_count = 0
@users_to_set_sis_batch_ids = [ ]
@pseudos_to_set_sis_batch_ids = [ ]
@users_to_add_account_associations = [ ]
@users_to_update_account_associations = [ ]
end
2011-05-10 05:24:05 +08:00
2011-09-07 02:07:54 +08:00
def add_user ( user_id , login_id , status , first_name , last_name , email = nil , password = nil , ssha_password = nil )
@logger . debug ( " Processing User #{ [ user_id , login_id , status , first_name , last_name , email , password , ssha_password ] . inspect } " )
2011-05-13 03:58:47 +08:00
2011-09-07 02:07:54 +08:00
raise ImportError , " No user_id given for a user " if user_id . blank?
raise ImportError , " No login_id given for user #{ user_id } " if login_id . blank?
raise ImportError , " Improper status for user #{ user_id } " unless status =~ / \ A(active|deleted) /i
2011-05-13 03:58:47 +08:00
2013-01-18 00:22:15 +08:00
@batched_users << [ user_id . to_s , login_id , status , first_name , last_name , email , password , ssha_password ]
2011-09-07 02:07:54 +08:00
process_batch if @batched_users . size > = @updates_every
end
2011-05-04 03:21:18 +08:00
2011-09-07 02:07:54 +08:00
def any_left_to_process?
return @batched_users . size > 0
end
def process_batch
return unless any_left_to_process?
transaction_timeout = Setting . get ( 'sis_transaction_seconds' , '1' ) . to_i . seconds
User . transaction do
tx_end_time = Time . now + transaction_timeout
user_row = nil
2011-09-27 07:19:39 +08:00
while ! @batched_users . empty? && tx_end_time > Time . now
user_row = @batched_users . shift
2011-09-07 02:07:54 +08:00
@logger . debug ( " Processing User #{ user_row . inspect } " )
user_id , login_id , status , first_name , last_name , email , password , ssha_password = user_row
2013-01-18 00:22:15 +08:00
pseudo = @root_account . pseudonyms . find_by_sis_user_id ( user_id . to_s )
2012-01-11 04:58:59 +08:00
pseudo_by_login = @root_account . pseudonyms . active . by_unique_id ( login_id ) . first
2011-09-07 02:07:54 +08:00
pseudo || = pseudo_by_login
2012-01-11 04:58:59 +08:00
pseudo || = @root_account . pseudonyms . active . by_unique_id ( email ) . first if email . present?
2011-09-07 02:07:54 +08:00
if pseudo
if pseudo . sis_user_id . present? && pseudo . sis_user_id != user_id
@messages << " user #{ pseudo . sis_user_id } has already claimed #{ user_id } 's requested login information, skipping "
next
end
if ! pseudo_by_login . nil? && pseudo . unique_id != login_id
@messages << " user #{ pseudo_by_login . sis_user_id } has already claimed #{ user_id } 's requested login information, skipping "
next
end
user = pseudo . user
2011-10-27 02:55:27 +08:00
user . name = " #{ first_name } #{ last_name } " unless user . stuck_sis_fields . include? ( :name )
2011-10-27 05:09:09 +08:00
unless user . stuck_sis_fields . include? ( :sortable_name )
user . sortable_name = last_name . present? && first_name . present? ? " #{ last_name } , #{ first_name } " : " #{ first_name } #{ last_name } "
end
2011-09-07 02:07:54 +08:00
else
user = User . new
2011-10-27 02:55:27 +08:00
user . name = " #{ first_name } #{ last_name } "
2011-10-27 05:09:09 +08:00
user . sortable_name = last_name . present? && first_name . present? ? " #{ last_name } , #{ first_name } " : " #{ first_name } #{ last_name } "
2011-09-07 02:07:54 +08:00
end
2011-10-29 07:40:37 +08:00
# we just leave all users registered now
# since we've deleted users though, we need to do this to be
# backwards compatible with the data
user . workflow_state = 'registered'
should_add_account_associations = false
should_update_account_associations = false
status_is_active = ! ( status =~ / \ Adeleted /i )
if ! status_is_active && ! user . new_record?
# if this user is deleted, we're just going to make sure the user isn't enrolled in anything in this root account and
# delete the pseudonym.
2013-03-19 23:49:31 +08:00
if 0 < user . enrollments . where ( " root_account_id=? AND workflow_state<>? " , @root_account , 'deleted' ) . update_all ( :workflow_state = > 'deleted' )
2011-10-29 07:40:37 +08:00
should_update_account_associations = true
end
2011-09-07 02:07:54 +08:00
end
2011-05-04 03:21:18 +08:00
2011-09-07 02:07:54 +08:00
pseudo || = Pseudonym . new
2011-10-11 06:31:18 +08:00
pseudo . unique_id = login_id unless pseudo . stuck_sis_fields . include? ( :unique_id )
2011-09-07 02:07:54 +08:00
pseudo . sis_user_id = user_id
pseudo . account = @root_account
2011-10-29 07:40:37 +08:00
pseudo . workflow_state = status_is_active ? 'active' : 'deleted'
if pseudo . new_record? && status_is_active
should_add_account_associations = true
elsif pseudo . workflow_state_changed?
if status_is_active
should_add_account_associations = true
else
should_update_account_associations = true
end
end
2011-09-07 02:07:54 +08:00
# if a password is provided, use it only if this is a new user, or the user hasn't changed the password in canvas *AND* the incoming password has changed
# otherwise the persistence_token will change even though we're setting to the same password, logging the user out
if ! password . blank? && ( pseudo . new_record? || pseudo . password_auto_generated && ! pseudo . valid_password? ( password ) )
pseudo . password = password
pseudo . password_confirmation = password
pseudo . password_auto_generated = true
end
pseudo . sis_ssha = ssha_password if ! ssha_password . blank?
pseudo . reset_persistence_token if pseudo . sis_ssha_changed? && pseudo . password_auto_generated
2012-11-17 14:49:00 +08:00
user_touched = false
2011-09-07 02:07:54 +08:00
begin
User . transaction ( :requires_new = > true ) do
if user . changed?
2012-11-17 14:49:00 +08:00
user_touched = true
2013-03-05 08:00:01 +08:00
raise ImportError , user . errors . first . join ( " " ) if ! user . save_without_broadcasting && user . errors . size > 0
2011-09-07 02:07:54 +08:00
elsif @batch_id
@users_to_set_sis_batch_ids << user . id
2011-05-13 03:58:47 +08:00
end
2011-09-07 02:07:54 +08:00
pseudo . user_id = user . id
if pseudo . changed?
pseudo . sis_batch_id = @batch_id if @batch_id
2013-03-05 08:00:01 +08:00
raise ImportError , pseudo . errors . first . join ( " " ) if ! pseudo . save_without_broadcasting && pseudo . errors . size > 0
2011-09-07 02:07:54 +08:00
end
end
rescue = > e
@messages << " Failed saving user. Internal error: #{ e } "
next
end
2011-02-01 09:57:29 +08:00
2011-10-29 07:40:37 +08:00
@users_to_add_account_associations << user . id if should_add_account_associations
@users_to_update_account_associations << user . id if should_update_account_associations
2011-09-07 02:07:54 +08:00
if email . present?
refactor user creation/invitations closes #5833
fixes #5573, #5572, #5753
* communication channels are now only unique within a single user
* UserList changes
* Always resolve pseudonym#unique_ids
* Support looking up by SMS CCs
* Option to either require e-mails match an existing CC,
or e-mails that don't match a Pseudonym will always be
returned unattached (relying on better merging behavior
to not have a gazillion accounts created)
* Method to return users, creating new ones (*without* a
Pseudonym) if necessary. (can't create with a pseudonym,
since Pseudonym#unique_id is still unique, I can't have
multiple outstanding users with the same unique_id)
* EnrollmentsFromUserList is mostly gutted, now using UserList's
functionality directy.
* Use UserList for adding account admins, removing the now
unused Account#add_admin => User#find_by_email/User#assert_by_email
codepath
* Update UsersController#create to not worry about duplicate
communication channels
* Remove AccountsController#add_user, and just use
UsersController#create
* Change SIS::UserImporter to send out a merge opportunity
e-mail if a conflicting CC is found (but still create the CC)
* In /profile, don't worry about conflicting CCs (the CC confirmation
process will now allow merging)
* Remove CommunicationChannelsController#try_merge and #merge
* For the non-simple case of CoursesController#enrollment_invitation
redirect to /register (CommunicationsChannelController#confirm)
* Remove CoursesController#transfer_enrollment
* Move PseudonymsController#registration_confirmation to
CommunicationChannelsController#confirm (have to be able to
register an account without a Pseudonym yet)
* Fold the old direct confirm functionality in, if there are
no available merge opportunities
* Allow merging the new account with the currently logged in user
* Allow changing the Pseudonym#unique_id when registering a new
account (since there might be conflicts)
* Display a list of merge opportunities based on conflicting
communication channels
* Provide link(s) to log in as the other user,
redirecting back to the registration page after login is
complete (to complete the merge as the current user)
* Remove several assert_* methods that are no longer needed
* Update PseudonymSessionsController a bit to deal with the new
way of dealing with conflicting CCs (especially CCs from LDAP),
and to redirect back to the registration/confirmation page when
attempting to do a merge
* Expose the open_registration setting; use it to control if
inviting users to a course is able to create new users
Change-Id: If2f38818a71af656854d3bf8431ddbf5dcb84691
Reviewed-on: https://gerrit.instructure.com/6149
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
2011-10-13 04:30:48 +08:00
# find all CCs for this user, and active conflicting CCs for all users
# unless we're deleting this user, then only find CCs for this user
2011-12-31 07:10:04 +08:00
if status_is_active
2013-03-19 23:49:31 +08:00
ccs = CommunicationChannel . where ( " workflow_state='active' OR user_id=? " , user )
2011-12-31 07:10:04 +08:00
else
ccs = user . communication_channels
end
ccs = ccs . email . by_path ( email ) . all
refactor user creation/invitations closes #5833
fixes #5573, #5572, #5753
* communication channels are now only unique within a single user
* UserList changes
* Always resolve pseudonym#unique_ids
* Support looking up by SMS CCs
* Option to either require e-mails match an existing CC,
or e-mails that don't match a Pseudonym will always be
returned unattached (relying on better merging behavior
to not have a gazillion accounts created)
* Method to return users, creating new ones (*without* a
Pseudonym) if necessary. (can't create with a pseudonym,
since Pseudonym#unique_id is still unique, I can't have
multiple outstanding users with the same unique_id)
* EnrollmentsFromUserList is mostly gutted, now using UserList's
functionality directy.
* Use UserList for adding account admins, removing the now
unused Account#add_admin => User#find_by_email/User#assert_by_email
codepath
* Update UsersController#create to not worry about duplicate
communication channels
* Remove AccountsController#add_user, and just use
UsersController#create
* Change SIS::UserImporter to send out a merge opportunity
e-mail if a conflicting CC is found (but still create the CC)
* In /profile, don't worry about conflicting CCs (the CC confirmation
process will now allow merging)
* Remove CommunicationChannelsController#try_merge and #merge
* For the non-simple case of CoursesController#enrollment_invitation
redirect to /register (CommunicationsChannelController#confirm)
* Remove CoursesController#transfer_enrollment
* Move PseudonymsController#registration_confirmation to
CommunicationChannelsController#confirm (have to be able to
register an account without a Pseudonym yet)
* Fold the old direct confirm functionality in, if there are
no available merge opportunities
* Allow merging the new account with the currently logged in user
* Allow changing the Pseudonym#unique_id when registering a new
account (since there might be conflicts)
* Display a list of merge opportunities based on conflicting
communication channels
* Provide link(s) to log in as the other user,
redirecting back to the registration page after login is
complete (to complete the merge as the current user)
* Remove several assert_* methods that are no longer needed
* Update PseudonymSessionsController a bit to deal with the new
way of dealing with conflicting CCs (especially CCs from LDAP),
and to redirect back to the registration/confirmation page when
attempting to do a merge
* Expose the open_registration setting; use it to control if
inviting users to a course is able to create new users
Change-Id: If2f38818a71af656854d3bf8431ddbf5dcb84691
Reviewed-on: https://gerrit.instructure.com/6149
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
2011-10-13 04:30:48 +08:00
2012-01-04 07:40:03 +08:00
# sis_cc could be set from the previous user, if we're not on a transaction boundary,
# and the previous user had an sis communication channel, and this user doesn't have one
# then it would have "stolen" to sis_cc from the previous user
sis_cc = nil
refactor user creation/invitations closes #5833
fixes #5573, #5572, #5753
* communication channels are now only unique within a single user
* UserList changes
* Always resolve pseudonym#unique_ids
* Support looking up by SMS CCs
* Option to either require e-mails match an existing CC,
or e-mails that don't match a Pseudonym will always be
returned unattached (relying on better merging behavior
to not have a gazillion accounts created)
* Method to return users, creating new ones (*without* a
Pseudonym) if necessary. (can't create with a pseudonym,
since Pseudonym#unique_id is still unique, I can't have
multiple outstanding users with the same unique_id)
* EnrollmentsFromUserList is mostly gutted, now using UserList's
functionality directy.
* Use UserList for adding account admins, removing the now
unused Account#add_admin => User#find_by_email/User#assert_by_email
codepath
* Update UsersController#create to not worry about duplicate
communication channels
* Remove AccountsController#add_user, and just use
UsersController#create
* Change SIS::UserImporter to send out a merge opportunity
e-mail if a conflicting CC is found (but still create the CC)
* In /profile, don't worry about conflicting CCs (the CC confirmation
process will now allow merging)
* Remove CommunicationChannelsController#try_merge and #merge
* For the non-simple case of CoursesController#enrollment_invitation
redirect to /register (CommunicationsChannelController#confirm)
* Remove CoursesController#transfer_enrollment
* Move PseudonymsController#registration_confirmation to
CommunicationChannelsController#confirm (have to be able to
register an account without a Pseudonym yet)
* Fold the old direct confirm functionality in, if there are
no available merge opportunities
* Allow merging the new account with the currently logged in user
* Allow changing the Pseudonym#unique_id when registering a new
account (since there might be conflicts)
* Display a list of merge opportunities based on conflicting
communication channels
* Provide link(s) to log in as the other user,
redirecting back to the registration page after login is
complete (to complete the merge as the current user)
* Remove several assert_* methods that are no longer needed
* Update PseudonymSessionsController a bit to deal with the new
way of dealing with conflicting CCs (especially CCs from LDAP),
and to redirect back to the registration/confirmation page when
attempting to do a merge
* Expose the open_registration setting; use it to control if
inviting users to a course is able to create new users
Change-Id: If2f38818a71af656854d3bf8431ddbf5dcb84691
Reviewed-on: https://gerrit.instructure.com/6149
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
2011-10-13 04:30:48 +08:00
sis_cc = ccs . find { | cc | cc . id == pseudo . sis_communication_channel_id } if pseudo . sis_communication_channel_id
# Have to explicitly load the old sis communication channel, in case it changed (should only happen if user_id got messed up)
sis_cc || = pseudo . sis_communication_channel
2012-05-05 00:31:23 +08:00
# search for active/unconfirmed channels first, so we don't try to resurrect a conflicting cc
other_cc = ccs . find { | cc | cc . user_id == user . id && cc . id != sis_cc . try ( :id ) && ( cc . active? || cc . unconfirmed? ) }
other_cc || = ccs . find { | cc | cc . user_id == user . id && cc . id != sis_cc . try ( :id ) }
refactor user creation/invitations closes #5833
fixes #5573, #5572, #5753
* communication channels are now only unique within a single user
* UserList changes
* Always resolve pseudonym#unique_ids
* Support looking up by SMS CCs
* Option to either require e-mails match an existing CC,
or e-mails that don't match a Pseudonym will always be
returned unattached (relying on better merging behavior
to not have a gazillion accounts created)
* Method to return users, creating new ones (*without* a
Pseudonym) if necessary. (can't create with a pseudonym,
since Pseudonym#unique_id is still unique, I can't have
multiple outstanding users with the same unique_id)
* EnrollmentsFromUserList is mostly gutted, now using UserList's
functionality directy.
* Use UserList for adding account admins, removing the now
unused Account#add_admin => User#find_by_email/User#assert_by_email
codepath
* Update UsersController#create to not worry about duplicate
communication channels
* Remove AccountsController#add_user, and just use
UsersController#create
* Change SIS::UserImporter to send out a merge opportunity
e-mail if a conflicting CC is found (but still create the CC)
* In /profile, don't worry about conflicting CCs (the CC confirmation
process will now allow merging)
* Remove CommunicationChannelsController#try_merge and #merge
* For the non-simple case of CoursesController#enrollment_invitation
redirect to /register (CommunicationsChannelController#confirm)
* Remove CoursesController#transfer_enrollment
* Move PseudonymsController#registration_confirmation to
CommunicationChannelsController#confirm (have to be able to
register an account without a Pseudonym yet)
* Fold the old direct confirm functionality in, if there are
no available merge opportunities
* Allow merging the new account with the currently logged in user
* Allow changing the Pseudonym#unique_id when registering a new
account (since there might be conflicts)
* Display a list of merge opportunities based on conflicting
communication channels
* Provide link(s) to log in as the other user,
redirecting back to the registration page after login is
complete (to complete the merge as the current user)
* Remove several assert_* methods that are no longer needed
* Update PseudonymSessionsController a bit to deal with the new
way of dealing with conflicting CCs (especially CCs from LDAP),
and to redirect back to the registration/confirmation page when
attempting to do a merge
* Expose the open_registration setting; use it to control if
inviting users to a course is able to create new users
Change-Id: If2f38818a71af656854d3bf8431ddbf5dcb84691
Reviewed-on: https://gerrit.instructure.com/6149
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
2011-10-13 04:30:48 +08:00
# Handle the case where the SIS CC changes to match an already existing CC
if sis_cc && other_cc
sis_cc . destroy
sis_cc = nil
end
cc = sis_cc || other_cc || CommunicationChannel . new
cc . user_id = user . id
cc . pseudonym_id = pseudo . id
cc . path = email
2011-10-29 07:40:37 +08:00
cc . workflow_state = status_is_active ? 'active' : 'retired'
refactor user creation/invitations closes #5833
fixes #5573, #5572, #5753
* communication channels are now only unique within a single user
* UserList changes
* Always resolve pseudonym#unique_ids
* Support looking up by SMS CCs
* Option to either require e-mails match an existing CC,
or e-mails that don't match a Pseudonym will always be
returned unattached (relying on better merging behavior
to not have a gazillion accounts created)
* Method to return users, creating new ones (*without* a
Pseudonym) if necessary. (can't create with a pseudonym,
since Pseudonym#unique_id is still unique, I can't have
multiple outstanding users with the same unique_id)
* EnrollmentsFromUserList is mostly gutted, now using UserList's
functionality directy.
* Use UserList for adding account admins, removing the now
unused Account#add_admin => User#find_by_email/User#assert_by_email
codepath
* Update UsersController#create to not worry about duplicate
communication channels
* Remove AccountsController#add_user, and just use
UsersController#create
* Change SIS::UserImporter to send out a merge opportunity
e-mail if a conflicting CC is found (but still create the CC)
* In /profile, don't worry about conflicting CCs (the CC confirmation
process will now allow merging)
* Remove CommunicationChannelsController#try_merge and #merge
* For the non-simple case of CoursesController#enrollment_invitation
redirect to /register (CommunicationsChannelController#confirm)
* Remove CoursesController#transfer_enrollment
* Move PseudonymsController#registration_confirmation to
CommunicationChannelsController#confirm (have to be able to
register an account without a Pseudonym yet)
* Fold the old direct confirm functionality in, if there are
no available merge opportunities
* Allow merging the new account with the currently logged in user
* Allow changing the Pseudonym#unique_id when registering a new
account (since there might be conflicts)
* Display a list of merge opportunities based on conflicting
communication channels
* Provide link(s) to log in as the other user,
redirecting back to the registration page after login is
complete (to complete the merge as the current user)
* Remove several assert_* methods that are no longer needed
* Update PseudonymSessionsController a bit to deal with the new
way of dealing with conflicting CCs (especially CCs from LDAP),
and to redirect back to the registration/confirmation page when
attempting to do a merge
* Expose the open_registration setting; use it to control if
inviting users to a course is able to create new users
Change-Id: If2f38818a71af656854d3bf8431ddbf5dcb84691
Reviewed-on: https://gerrit.instructure.com/6149
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
2011-10-13 04:30:48 +08:00
newly_active = cc . path_changed? || ( cc . active? && cc . workflow_state_changed? )
2012-11-17 14:49:00 +08:00
if cc . changed?
2013-03-05 08:00:01 +08:00
if cc . valid?
cc . save_without_broadcasting
else
msg = " An email did not pass validation "
msg += " ( " + " #{ email } , error: "
msg += cc . errors . full_messages . join ( " , " ) + " ) "
raise ImportError , msg
end
2012-11-17 14:49:00 +08:00
user . touch unless user_touched
end
refactor user creation/invitations closes #5833
fixes #5573, #5572, #5753
* communication channels are now only unique within a single user
* UserList changes
* Always resolve pseudonym#unique_ids
* Support looking up by SMS CCs
* Option to either require e-mails match an existing CC,
or e-mails that don't match a Pseudonym will always be
returned unattached (relying on better merging behavior
to not have a gazillion accounts created)
* Method to return users, creating new ones (*without* a
Pseudonym) if necessary. (can't create with a pseudonym,
since Pseudonym#unique_id is still unique, I can't have
multiple outstanding users with the same unique_id)
* EnrollmentsFromUserList is mostly gutted, now using UserList's
functionality directy.
* Use UserList for adding account admins, removing the now
unused Account#add_admin => User#find_by_email/User#assert_by_email
codepath
* Update UsersController#create to not worry about duplicate
communication channels
* Remove AccountsController#add_user, and just use
UsersController#create
* Change SIS::UserImporter to send out a merge opportunity
e-mail if a conflicting CC is found (but still create the CC)
* In /profile, don't worry about conflicting CCs (the CC confirmation
process will now allow merging)
* Remove CommunicationChannelsController#try_merge and #merge
* For the non-simple case of CoursesController#enrollment_invitation
redirect to /register (CommunicationsChannelController#confirm)
* Remove CoursesController#transfer_enrollment
* Move PseudonymsController#registration_confirmation to
CommunicationChannelsController#confirm (have to be able to
register an account without a Pseudonym yet)
* Fold the old direct confirm functionality in, if there are
no available merge opportunities
* Allow merging the new account with the currently logged in user
* Allow changing the Pseudonym#unique_id when registering a new
account (since there might be conflicts)
* Display a list of merge opportunities based on conflicting
communication channels
* Provide link(s) to log in as the other user,
redirecting back to the registration page after login is
complete (to complete the merge as the current user)
* Remove several assert_* methods that are no longer needed
* Update PseudonymSessionsController a bit to deal with the new
way of dealing with conflicting CCs (especially CCs from LDAP),
and to redirect back to the registration/confirmation page when
attempting to do a merge
* Expose the open_registration setting; use it to control if
inviting users to a course is able to create new users
Change-Id: If2f38818a71af656854d3bf8431ddbf5dcb84691
Reviewed-on: https://gerrit.instructure.com/6149
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
2011-10-13 04:30:48 +08:00
pseudo . sis_communication_channel_id = pseudo . communication_channel_id = cc . id
if newly_active
2012-02-18 04:09:56 +08:00
other_ccs = ccs . reject { | other_cc | other_cc . user_id == user . id || other_cc . user . nil? || other_cc . user . pseudonyms . active . count == 0 ||
2013-03-19 23:49:31 +08:00
! other_cc . user . pseudonyms . active . where ( " account_id=? AND sis_user_id IS NOT NULL " , @root_account ) . empty? }
refactor user creation/invitations closes #5833
fixes #5573, #5572, #5753
* communication channels are now only unique within a single user
* UserList changes
* Always resolve pseudonym#unique_ids
* Support looking up by SMS CCs
* Option to either require e-mails match an existing CC,
or e-mails that don't match a Pseudonym will always be
returned unattached (relying on better merging behavior
to not have a gazillion accounts created)
* Method to return users, creating new ones (*without* a
Pseudonym) if necessary. (can't create with a pseudonym,
since Pseudonym#unique_id is still unique, I can't have
multiple outstanding users with the same unique_id)
* EnrollmentsFromUserList is mostly gutted, now using UserList's
functionality directy.
* Use UserList for adding account admins, removing the now
unused Account#add_admin => User#find_by_email/User#assert_by_email
codepath
* Update UsersController#create to not worry about duplicate
communication channels
* Remove AccountsController#add_user, and just use
UsersController#create
* Change SIS::UserImporter to send out a merge opportunity
e-mail if a conflicting CC is found (but still create the CC)
* In /profile, don't worry about conflicting CCs (the CC confirmation
process will now allow merging)
* Remove CommunicationChannelsController#try_merge and #merge
* For the non-simple case of CoursesController#enrollment_invitation
redirect to /register (CommunicationsChannelController#confirm)
* Remove CoursesController#transfer_enrollment
* Move PseudonymsController#registration_confirmation to
CommunicationChannelsController#confirm (have to be able to
register an account without a Pseudonym yet)
* Fold the old direct confirm functionality in, if there are
no available merge opportunities
* Allow merging the new account with the currently logged in user
* Allow changing the Pseudonym#unique_id when registering a new
account (since there might be conflicts)
* Display a list of merge opportunities based on conflicting
communication channels
* Provide link(s) to log in as the other user,
redirecting back to the registration page after login is
complete (to complete the merge as the current user)
* Remove several assert_* methods that are no longer needed
* Update PseudonymSessionsController a bit to deal with the new
way of dealing with conflicting CCs (especially CCs from LDAP),
and to redirect back to the registration/confirmation page when
attempting to do a merge
* Expose the open_registration setting; use it to control if
inviting users to a course is able to create new users
Change-Id: If2f38818a71af656854d3bf8431ddbf5dcb84691
Reviewed-on: https://gerrit.instructure.com/6149
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
2011-10-13 04:30:48 +08:00
unless other_ccs . empty?
cc . send_merge_notification!
2011-05-13 03:58:47 +08:00
end
2011-09-07 02:07:54 +08:00
end
end
2011-02-01 09:57:29 +08:00
2011-09-07 02:07:54 +08:00
if pseudo . changed?
pseudo . sis_batch_id = @batch_id if @batch_id
2013-03-05 08:00:01 +08:00
if pseudo . valid?
pseudo . save_without_broadcasting
@success_count += 1
else
msg = " A user did not pass validation "
msg += " ( " + " user: #{ user_id } , error: "
msg += pseudo . errors . full_messages . join ( " , " ) + " ) "
raise ImportError , msg
end
2011-09-07 02:07:54 +08:00
elsif @batch_id && pseudo . sis_batch_id != @batch_id
@pseudos_to_set_sis_batch_ids << pseudo . id
2013-03-05 08:00:01 +08:00
@success_count += 1
2011-04-30 04:03:25 +08:00
end
2011-09-07 02:07:54 +08:00
2011-04-29 04:52:57 +08:00
end
2011-02-01 09:57:29 +08:00
end
end
end
end
2011-04-29 04:52:57 +08:00
end