fixes#10690
previously, notifications only considered user locale settings
when translating; they now consider the context as well.
test plan:
* create a course with a spanish or russian locale;
* enroll an english user in the course;
* verify that the enrollment email is sent in the course
locale and not the user locale.
Change-Id: Ib942f35dff770ec02aa4e39880a5234e318f26a9
Reviewed-on: https://gerrit.instructure.com/14103
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Jon Jensen <jon@instructure.com>
test plan:
* have a site admin user in shard 1
* add that user by their login id as an admin to an account in
shard 2 (in the UI)
* it should work
* repeat for enrolling in a course
Change-Id: I403f0f853056d4ea1dd9628c70e882fdc3cfd8bf
Reviewed-on: https://gerrit.instructure.com/14090
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
disabling canvas auth also force-disables open registration, and
makes LDAP auth act like full delegated auth (CAS or SAML)
test plan:
* configure LDAP, CAS, or SAML. MAKE SURE YOU CAN LOG IN.
* go to account settings, and disable "Canvas Authentication"
* open registration should no longer show up on account settings
page (after saving)
* ensure you can no longer log in with your Canvas credentials, but
you can with LDAP, CAS, or SAML credentials.
* remove LDAP, CAS, or SAML from the account
* "Canvas Authentication" should no longer show up on the account
settings page, open registration should
* your Canvas credentials should start working again
* add LDAP, CAS, or SAML back
* "Canvas Authentication" should be back on in account settings
Change-Id: Ic7475623e5139bb545a87d8e5b1014dabaf4e854
Reviewed-on: https://gerrit.instructure.com/12850
Reviewed-by: Jeremy Stanley <jeremy@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
test plan:
* enable optional MFA, and check the following:
* normal log in should not be affected
* you can enroll in MFA from your profile page
* you can re-enroll in MFA from your profile page
* you can disable MFA from your profile page
* MFA can be reset by an admin on your user page
* when enrolled, you are asked for verification code after
username/password when logging in
* you can't access any other part of the site directly until
until entering your verification code
* enable required MFA, and check the following
* when not enrolled in MFA, and you log in, you are forced to
enroll
* you cannot disable MFA from your profile page
* you can re-enroll in MFA from your profile page
* an admin (other than himself) can reset MFA from the user page
* for enrolling in MFA
* use Google Authenticator and scan the QR code; you should have
30-seconds or so of extra leeway to enter your code
* having no SMS communication channels on your profile, the
enrollment page should just have a form to add a new phone
* having one or more SMS communication channels on your profile,
the enrollment page should list them, or allow you to create
a new one (and switch back)
* having more than one SMS communication channel on your profile,
the enrollment page should remember which one you have selected
after you click "send"
* an unconfirmed SMS channel should go to confirmed when it's used
to enroll in MFA
* you should not be able to go directly to /login/otp to enroll
if you used "Remember me" token to log in
* MFA login flow
* if configured with SMS, it should send you an SMS after you
put in your username/password; you should have about 5 minutes
of leeway to put it in
* if you don't check "remember computer" checkbox, you should have
to enter a verification code each time you log in
* if you do check it, you shouldn't have to enter your code
anymore (for three days). it also shouldn't SMS you a
verification code each time you log in
* setting MFA to required for admins should make it required for
admins, optional for other users
* with MFA enabled, directly go to /login/otp after entering
username/password but before entering a verification code; it
should send you back to the main login page
* if you enrolled via SMS, you should not be able to remove that
SMS from your profile
* there should not be a reset MFA link on a user page if they
haven't enrolled
* test a login or required enrollment sequence with CAS and/or SAML
Change-Id: I692de7405bf7ca023183e717930ee940ccf0d5e6
Reviewed-on: https://gerrit.instructure.com/12700
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Brian Palmer <brianp@instructure.com>
since we have already "validated" the email (by virtue of them receiving
it and clicking on a link), we don't need to validate it here. fixes an
issue where users with non-email pseudonyms could not get past this page
also tweak form so that pseudonym can be specified if it needs to be set
(for example, the email was already taken by another user)
test plan:
1. as an admin create a new user with a login other than their email
address
2. check the user's /messages URL to see the email that was sent to the
user
3. copy and paste the URL that was sent in the email and navigate to it
4. the registration page should allow you to proceed and the label should
say "Login"
Change-Id: I563b53b16b950bd7f6dafc456349db74fd97b294
Reviewed-on: https://gerrit.instructure.com/12569
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Zach Pendleton <zachp@instructure.com>
gets rid of the old green modal style. adds a new modal style (light gray)
and a login style (dark gray). a few form tweaks.
test plan:
1. confirm the login page works and looks correct
2. confirm the unauthorized page (e.g. /courses/1 when not logged in)
works and looks correct
3. confirm the confirm registration page works and looks correct
4. confirm the course self-enrollment page works and looks correct
5. confirm the oauth2 confirm page works and looks correct
Change-Id: Ib9197693ec7b45349f25d69b9931bbae4c7ee831
Reviewed-on: https://gerrit.instructure.com/12246
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Ryan Shaw <ryan@instructure.com>
fixes#7676
test plan:
* get a site admin password wrong 11 times in a row from the same
computer
* it should error with "too many login attempts" for the next 5
minutes
Change-Id: I7e63e3ecf76f1a7a638d8a43110e787ed08af795
Reviewed-on: https://gerrit.instructure.com/11828
Reviewed-by: Jeremy Stanley <jeremy@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
test plan:
1. sign up as a teacher
2. sign up as a student with a course code
1. confirm that you are auto-logged in as soon as you submit valid info
in the form
3. sign up as a student without a course code
4. sign up as an observer
1. confirm that you are auto-enrolled in the child's courses
5. test the log in form
Change-Id: I581de48095e85ca869b9ded101fe143ffadb9c9a
Reviewed-on: https://gerrit.instructure.com/11111
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Jon Jensen <jon@instructure.com>
moved some code into the model for easier reuse (e.g. observer
co-enrollmenent needs to be able to auth as the observed user)
test plan:
1. run PseudonymSessionController specs
2. they should pass
Change-Id: If6cafc99235f270909d2dd17d1912b1a51bb11bc
Reviewed-on: https://gerrit.instructure.com/11079
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
* add the foreigner gem so plugins can begin adding foreign keys
immediately
* add an extension to do less locking when creating foreign keys
on postgres 9.1+
* fix a few pieces of code that either don't properly clean up
foreign dependencies, or create objects in the wrong order
to maintain referential integrity
* change the specs to truncate all tables in a single command
for postgres (to avoid referential integrity errors; also
slightly faster)
test plan:
* no user visible functionality should change
Change-Id: I185e478b99fbe598d408912053c34a064aa9c461
Reviewed-on: https://gerrit.instructure.com/10580
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Brian Palmer <brianp@instructure.com>
test plan:
* create a user in a non-default account
* the user should no longer be able to log in at the default account
Change-Id: Ibf2ca15e6ae4d1da71b23648332862520be4358a
Reviewed-on: https://gerrit.instructure.com/8746
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Brian Palmer <brianp@instructure.com>
test plan:
* create a new pseudonym without a password in script/console
* after saving, pseudonym.password should return a value, and
it should not start with "tmp-pw-"
Change-Id: Idb49ada75d0212fd068e09fbf4e77d837b25e9c4
Reviewed-on: https://gerrit.instructure.com/9778
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Brian Palmer <brianp@instructure.com>
If an LDAP server times out, log the time of failure to the
AccountAuthorizationConfig, and don't try to connect again until some
time passes.
test plan:
* set up an account that uses LDAP, point it to localhost port 6767
* run `nc -l 6767` or some other command to listen on that port, but
not ever respond
* attempt to log in on that account, the first log in should hang for
5 seconds. subsequent logins should skip even trying to talk to
ldap, until 1 minute passes.
* change the account authorization config, verify that it tries the
LDAP server again immediately
Change-Id: Iea5d7c27f72341d16ae370a0f6ad4ec90fb96b74
Reviewed-on: https://gerrit.instructure.com/9116
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
Reviewed-by: Zach Wily <zach@instructure.com>
admin can now create user with no sis_user_id without receiving
an error about the sis id already existing.
also includes a migration to set all empty string sis_user_ids to
NULL.
test plan:
* enable sis imports on an account;
* as an admin in that account, create a new user, leaving the
sis id blank;
* create a second new user, also with a blank sis id;
* verify that the second user is creating without any errors.
test plan:
Change-Id: Ia247c58e0070a4b02ecc584c18ed20bb5c05dcd3
Reviewed-on: https://gerrit.instructure.com/8665
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
fixes#7147
test plan:
* enable open registration
* invite a new user to a course
* that user should not show up in the account's user list
* finish registering the user
* the user should now show up in the account's user list
Change-Id: I60790c213671a7c16a52082602725a2468ad2dc4
Reviewed-on: https://gerrit.instructure.com/8502
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
refs #6883
Use it when checking if a pseudonym is valid for authentication, but
not for if we need to create a new pseudonym for an account. This
means that you can authenticate via an implicit trust relationship,
but when you are invited to something, it will still try and create
a pseudonym for you in that account.
test plan:
* run existing specs (no behavior is changed without a plugin
to define trust relationships)
Change-Id: Ieb200da27351c185e640e9c50ae1a6054e502c63
Reviewed-on: https://gerrit.instructure.com/8076
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
this is already true, just make sure it stays that way
test plan: n/a
Change-Id: Ia7340e8de57b18da509d51580b5827c7069af80a
Reviewed-on: https://gerrit.instructure.com/7166
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: JT Olds <jt@instructure.com>
so that it's case insensitive
also fix some latent CommunicationChannel.find_or_initialize_by_path
discovered by specs for this
test plan:
* run the specs
* use forgot password with a username that differs in case
* self-register a new user multiple times (without confirming)
with e-mail addresses that differ in case
Change-Id: I476325f591c997fc8d50d5f38480177f732f07a7
Reviewed-on: https://gerrit.instructure.com/7724
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Brian Palmer <brianp@instructure.com>
test plan:
* create a user via SIS import with an e-mail address
* add a different e-mail address to the user
* re-import the user via SIS, and set their e-mail address
to the second e-mail you added, but with a different case
* the user should have a single e-mail address, the one set
in the second SIS import
Change-Id: Iab6b16e0b37cfb8caac3faa453be570b99621a9e
Reviewed-on: https://gerrit.instructure.com/7784
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Brian Palmer <brianp@instructure.com>
Reviewed-by: Zach Pendleton <zachp@instructure.com>
test plan:
* disable open registration in all accounts you use
* create users with the same login in multiple accounts, and invite
user to a course in one of the accounts; it should find the user
from the account the course is in
* create users in the same login in multiple accounts, and invite
user to a course in an account that does not have that login; it
should not find any users (can't resolve the conflict)
* if you have a plugin the changes the definition of a trusted
account, try to add user from one account to an account that does
not trust the first; it should not find any users
Change-Id: I5e5283e8f41bb0aea00ae3a48e4dc87a7e811978
Reviewed-on: https://gerrit.instructure.com/7258
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Bracken Mosbacker <bracken@instructure.com>
that's only true for Instructure, and not for hosted or open source
installations
test plan: n/a
Change-Id: I63c3c163fba410da758c4b0fe132332c0460abbc
Reviewed-on: https://gerrit.instructure.com/7009
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: JT Olds <jt@instructure.com>
closes#6382
Previously, the "stay logged in" cookie just used the authlogic default
implementation, which is the pseudonym persistence_token. This is a
problem, because that persistence_token only ever changes when the
pseudonym password changes, so it's the same everywhere; so if that
cookie is stolen, it's valid for a very long time.
This switches us to one-time-use tokens that expire as soon as the token
logs the user in once. Each user agent also gets a different
one-time-use token.
Change-Id: I4f20cd7759fd74590e82ed55797552e342243d49
testplan:
* Check that no token is set at all when "stay logged in" isn't
selected.
* Check "stay logged in", and verify:
* That you don't have to login again after restarting your browser,
but your _normandy_session got reset.
* That if you save and try to replay using the same
pseudonym_credentials, they don't work the second time.
* That a second browser will get a different pseudonym_credentials
value, and using one token doesn't affect the other.
* That once the token is used, a new one is generated and set in
your cookies. Verify this new token works as well.
* That logging out removes the pseudonym_credentials cookie in your
browser. And also that manually restoring this cookie still
doesn't log you in, since it was removed server-side as well.
* Change your password, and verify that the existing "stay logged in"
tokens no longer work.
* Delete your pseudonym, and verify the same.
Reviewed-on: https://gerrit.instructure.com/7093
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
Reviewed-by: Zach Wily <zach@instructure.com>
testplan: delete all logins for an account from a user, and check
their associations
Change-Id: I13939947e38525d4fe821cc991f622f5e117804c
Reviewed-on: https://gerrit.instructure.com/7001
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Brian Palmer <brianp@instructure.com>
refs #6199, #6177
makes it easier for a plugin to modify the logic. also removed dummy
method in Account that is never hooked into.
Change-Id: I87e2cad5172f6dece4448d61dc4681a94c44cecb
testplan: login
Reviewed-on: https://gerrit.instructure.com/6982
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Brian Palmer <brianp@instructure.com>
also fix searching all accounts to do so case insensitively
Change-Id: I3199f5ecd80d07e685c09c31bdffc96ef0f5371e
Reviewed-on: https://gerrit.instructure.com/6592
Reviewed-by: Zach Wily <zach@instructure.com>
Tested-by: Hudson <hudson@instructure.com>
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>
update_all's update hash doesn't have any magic performed on bare Time
objects; it assumes any Time object it's given is already in UTC. using
a TimeWithZone object (regardless of timezone), which Fixnum#ago and
friends happen to return, is still fine.
Change-Id: I297b2a3211b896b5225ebcfaaee3c1eb56e55fb6
Reviewed-on: https://gerrit.instructure.com/5351
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Jon Jensen <jon@instructure.com>
Adds the ability for admins to configure a second LDAP server that will be
queried after the primary, assuming the user could not be found on the
primary. This is a slight refactor towards a more flexible authorization
configs model. Changes include:
* changed the authorization relationship on Account to has_many
* for backwards compat with all the code that assumes one config, added
a convenience method to Account
* refactored the auth config editing screen to send multiple configs at a
time
* modified the pseudonym to iterate over all the auth configs (when using
ldap), stopping at the first one that succeeds
Change-Id: I6bae474f542e8c7046f07d4ab2c27e7d6f64a1ce
Reviewed-on: https://gerrit.instructure.com/4108
Reviewed-by: Brian Palmer <brianp@instructure.com>
Tested-by: Hudson <hudson@instructure.com>
refs #4487
This consolidates our ErrorReport class with our ErrorLogging mechanism,
it's all in ErrorReport now and you call ErrorReport.log_error or
ErrorReport.log_exception to both create an ErrorReport object, and call
the hooks similar to what ErrorLogging did so that plugins for other
error handling mechanisms can be injected.
ErrorReport has a category field now, similar to how ErrorLogging used
to take a type. the /error_reports UI can filter by category.
The plugin interface was designed with Hoptoad integration in mind, but
it should be pretty general.
Change-Id: I59f7a0d44cf4b6215ad13ff92d30e1d1af607b74
Reviewed-on: https://gerrit.instructure.com/3577
Reviewed-by: Brian Palmer <brianp@instructure.com>
Tested-by: Hudson <hudson@instructure.com>
proactively found and fixed varchar(255)'s where we relied on mysql's
silent truncation. added validations for places where we want to
enforce these limits
made it so you can reuse titles/urls of deleted wiki pages, and added
validations to ensure sane urls and prevent orphaned pages
Change-Id: I15bcc0c7a751efba1a0f7548e9989ad2ea1792bf
Reviewed-on: https://gerrit.instructure.com/2935
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Brian Palmer <brianp@instructure.com>