Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add beforeLogin trigger with support for auth providers #5445

Merged
merged 5 commits into from Apr 23, 2019

Conversation

@omairvaiyani
Copy link
Contributor

commented Mar 23, 2019

This has been attempted before a couple of times but never seen to completion. I used some of the ideas by @carlosapgomes in his now closed PR, however most of the work was too out of sync with the current state of the library.

Currently:
User sign ups can be validated, rejected and side-effects issued in beforeSave on Parse.User. There is no similar functionality for user logins.

Use cases:

  • Blocking an account from logging in (for example, if they are banned).
  • Recording a login event for analytics.
  • Notifying user by email if a login occurred at an unusual IP address.

Motivation / Bias:
We have a multi-tenanted platform wherein each client has their own subdomain. They share the same database and so, theoretically users from subdomain-a can legally login to subdomain-b. This new trigger allows us to check the request headers against the user to verify if the login is appropriate.

Example usage:

// In cloud code
Parse.Cloud.beforeLogin(async request => { 
  const { object: user }  = request;
  if(user.get('isBanned')) {
   throw new Error('Sorry, you are a naughty boy.')
  }
});

// On the client
await Parse.User.logIn('naughty', 'pass123'); // rejected with "Sorry, you are a naughty boy."

Considerations:
This trigger behaves in a similar manner to other triggers:

  • It sends a TriggerRequest that contains object, headers, ip, installationId, etc
  • Like afterSave on Parse.User, it will not save mutations to the user unless explicitly saved.
  • It will return a Parse.Error if an exception is thrown
  • It waits for any promises to resolve

The trigger has some unique behaviours not seen in other triggers:

  • It does not accept a className or Parse.Object constructor as the first argument; it is only meant for Parse.User
  • It does not set the user on the request object - technically, the user has not yet been provided a session until after beforeLogin is successfully completed

Some specific behaviours with regards to signup/login:

  • It does not run on sign up
  • It does run on username/pass AND authProvider logins
  • It will not run if the login credentials are incorrect

Please let me know if there are side-effects that I have not accounted for in the added unit tests.

@omairvaiyani omairvaiyani referenced this pull request Mar 23, 2019

Closed

beforeLogin Hook #4524

@codecov

This comment has been minimized.

Copy link

commented Mar 23, 2019

Codecov Report

Merging #5445 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #5445      +/-   ##
==========================================
+ Coverage   93.93%   93.94%   +<.01%     
==========================================
  Files         123      123              
  Lines        9024     9035      +11     
==========================================
+ Hits         8477     8488      +11     
  Misses        547      547
Impacted Files Coverage Δ
src/triggers.js 94.49% <ø> (ø) ⬆️
src/Routers/UsersRouter.js 93.5% <100%> (+0.04%) ⬆️
src/cloud-code/Parse.Cloud.js 97.43% <100%> (+0.21%) ⬆️
src/RestWrite.js 93.52% <100%> (+0.08%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d64a23b...f7ab0a9. Read the comment docs.

@acinader

This comment has been minimized.

Copy link
Member

commented Apr 21, 2019

@stage88 or @georgesjamous would either of you be willing to look at this pull request and give feedback on:

  1. would this be an appropriate feature to add
  2. does the code look like it is doing what it is supposed to
  3. is it well covered
  4. what documentation would need to be written or changed?
@stage88
Copy link
Contributor

left a comment

Looks good!

Would it be worth guarding against maintainers accidentally adding beforeLogin to classes other then _User?

See function validateClassNameForTriggers in https://github.com/parse-community/parse-server/blob/master/src/triggers.js.

Also see this test: 'should validate triggers correctly'.

@omairvaiyani

This comment has been minimized.

Copy link
Contributor Author

commented Apr 23, 2019

Thanks for taking a look @stage88

I've added the assertions as you suggested with one caveat. The test case 'should validate triggers correctly' would (prior to the latest commits) not throw given that the beforeLogin function was automatically setting the className to _User. I've now adjusted the code for better consistency.

@stage88

This comment has been minimized.

Copy link
Contributor

commented Apr 23, 2019

Great effort 👏, thanks @omairvaiyani.

@georgesjamous this looks good to me.

CC @acinader

@@ -41,6 +42,11 @@ function validateClassNameForTriggers(className, type) {
// TODO: Allow proper documented way of using nested increment ops
throw 'Only afterSave is allowed on _PushStatus';
}
if (type === Types.beforeLogin && className !== '_User') {
// TODO: check if upstream code will handle `Error` instance rather

This comment has been minimized.

Copy link
@acinader

@acinader acinader merged commit a1e1cef into parse-community:master Apr 23, 2019

2 checks passed

Danger All good
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details

@omairvaiyani omairvaiyani deleted the omairvaiyani:before-login-trigger branch Apr 23, 2019

@TomWFox TomWFox referenced this pull request Apr 24, 2019

Merged

Add documentation for beforeLogin trigger #617

1 of 1 task complete
@TomWFox

This comment has been minimized.

Copy link
Member

commented Apr 24, 2019

@omairvaiyani I've started a draft PR for the documentation of this features in #617 on the docs repo. It would be great if you could take a look.

@omairvaiyani

This comment has been minimized.

Copy link
Contributor Author

commented Apr 24, 2019

@TomWFox that was quick! I've added some suggestions but nothing major.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.