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

Harvest: Facilitate trigger launching and two factor authentification with TriggerLauncher #415

Merged

Conversation

gregorylegarec
Copy link
Contributor

@gregorylegarec gregorylegarec commented May 1, 2019

This PR prepares the code for and add the TriggerLauncher component.

Using render props, it allows to easily launch a trigger and handle all steps of a konnector job lifecycle.

To launch a konnector job with a button:

render(){
  // trigger has already been fetched
  const { trigger } = this.props
  return (
    <TriggerLauncher trigger={trigger}>
      {({launch, running}) => (
        <Button
          onClick={launch}
          disabled={running}
        />
      )}
    </TriggerLauncher>

TriggerLauncher relies internally on a KonnectorJob object. KonnectorJob is an object which handles a konnector job lifecycle from launch to success or error. It use MicroEE mixins to emit events.

// trigger has already been fetched
const konnectorJob = new KonnectorJob(trigger)
konnectorJob
  .on('success', handleSuccess)
  .on('twoFARequest', handleTwoFARequest)
konnectorJob.launch()

KonnectorJob for now relies internally on existing classes KonnectorJobWatcher and KonnectorAccountWatcher, they should both be merged directly into KonnectorJob. But as they are also used in TriggerManager to handle 2FA, we prefer to not introduce regressions in this PR and keep this refactoring for a next PR. In this future PR TriggerManager will lose all logic related to 2FA, which it should not handle.

Tests for TriggerManager and KonnectorJob are coming in a future PR as well.

@gregorylegarec gregorylegarec requested a review from CPatchane as a code owner May 1, 2019 11:13
@gregorylegarec gregorylegarec self-assigned this May 1, 2019
@gregorylegarec gregorylegarec added the ✨ Enhancement New feature or request label May 1, 2019
@gregorylegarec gregorylegarec force-pushed the feat/harvest/TriggerLauncher branch 3 times, most recently from db0cb38 to 0a67664 Compare May 1, 2019 23:13
Copy link
Contributor

@CPatchane CPatchane left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good but we need much more tests for those new components/models


export default withMutations(accountsMutations, triggersMutations)(
TriggerLauncher
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have a test for this new component? At least a snapshot will be a good beginning than nothing

client: PropTypes.object
}

export default translate()(withMutations(accountsMutations)(TwoFAModal))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least a snapshot would be great to avoid regressions when merging the two TwoFA components in the future


MicroEE.mixin(KonnectorJob)

export default KonnectorJob
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have a test for this model, since it will be the main used model, we have to have to start some tests here

gregorylegarec and others added 11 commits May 6, 2019 12:12
In KonnectorJobWatcher, login success is no longer a success,
to not block regular success to be triggered.
KonnectorJob is a model which encapsulate existing
KonnectorJobWatcher and KonnectorAccountWatcher,
aiming to merge them into it in a near future.

For now we prefer to not introduce regressions
into TriggerManager, event if it will also
need a refactoring to use directly KonnectorJob.

KonnectorJob manages trigger, account and job
logic already existing into TriggerManager,
which is not the place they belong to.
For now it is just a copy of TwoFAForm, to avoid
introducing regression into TriggerManager.

Both TwoFAForm and TwoFAModal will need to be
merged.
@CPatchane CPatchane force-pushed the feat/harvest/TriggerLauncher branch from 24906ec to db6c561 Compare May 6, 2019 10:13
@CPatchane CPatchane force-pushed the feat/harvest/TriggerLauncher branch from d1a005d to 48fd910 Compare May 6, 2019 11:16
Copy link
Contributor

@ptbrowne ptbrowne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quelques observations et retours non bloquants. Je suis un peu en questionnement quand au stockage du state du trigger dans le composant plutôt que dans l'objet KonnectorJob.


render() {
const { showTwoFAModal, status } = this.state
const { account, children, konnector, submitting } = this.props
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: When using boolean variable, I tend to put has/is in front. isSubmitting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. As submitting is also used in TriggerManager, I suggest to keep it now for consistence and rename all props at the same time. I made an issue: #431.

Copy link
Contributor Author

@gregorylegarec gregorylegarec May 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CPatchane account and konnector are data which can be retrieved with trigger infos. As konnectorJob is already fetching the related account, I suggest to also fetch the related konnector in it.

Then we pass the whole konnectorJob to TwoFAModal or we get account and konnector from it.

We should try to limit the number of props which can be deduced with other ones now, otherwise we will soon have a new Cozy-Home into Harvest. TriggerLauncher just expect a trigger as prop. For now it also take submitting but we will make it disappear in the future.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See fee5d47

<div>
{children({
launch: this.launch,
running: ![ERRORED, IDLE, SUCCESS].includes(status) || submitting
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I assume the triger does not have a status == running ? It seems a bit brittle because if we had another status, we will have running to true whereas the new status can be scheduled or something else

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How I see it: If we introduce another status we should know it and add it in our model, which strengthen your suggestion to rely totally on konnectorJob to know get information about job status.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handled directly in KonnectorJob now

dismissAction={this.handleTwoFAModalDismiss}
handleSubmitTwoFACode={this.handle2FACode}
submitting={status === RUNNING_TWOFA}
retryAsked={status === TWO_FA_MISMATCH}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering if it would no be simpler for the TwoFaForm to get the job and listen by itself on it. Here we are adding external props to control the TwoFAForm whereas if it had the job it could listen to it by itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was asking myself the same kind of question during development. What made me choose this solutions was to avoid passing a complex object like a KonnectorJob as prop. But I am still not sure this was a good solution.

How I see it if we pass the konnectorJob to TwoFAModal:

  • TriggerLauncher must still listen to twoFARequest event to show 2FA modal
  • TwoFAModal only listen to twoFAMismatch event

Do you agree ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now the TriggerLauncher just use KonnectorJob from props with fee5d47

.on('success', this.handleSuccess)
.on('twoFARequest', this.handleTwoFARequest)
.on('twoFAMismatch', this.handleTwoFAMismatch)
this.konnectorJob.launch()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Observations:

  • In launch we are assigning this.konnectorJob, this means that TriggerLauncher has an internal state and it is not cleaned up on success or error. Do we need to save an internal variable ? Could we simplify and only use a closure ?
  • The component is responsible to remember the status of the konnector in its internal state. I wonder if it would no be simpler to have this status in the konnectorJob and rely on it for the render.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems clever. The konnectorJob is saved as an interanl variable to have access to konnectorJob.sendTwoFACode method to pass it to TwoFAModal.

Keeping the status in konnectorJob could also spare us all the handle{KonnectorJobEvent} methods here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree about the status but we still need the internal variable for the sendTwoFACode prop passed to the form, I don't see another simpler way to handle it :/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See fee5d47

@gregorylegarec
Copy link
Contributor Author

@ptbrowne Thanks for your feedback 👍

@CPatchane CPatchane force-pushed the feat/harvest/TriggerLauncher branch from fee5d47 to addbecd Compare May 7, 2019 11:58
CPatchane added 2 commits May 7, 2019 14:20
Temporary duplicate TwoFAForm into TwoFAModal to avoid regressions
at term, TriggerManager will use TwoFAModal
@gregorylegarec gregorylegarec merged commit 4b0ffe0 into cozy:master May 7, 2019
@gregorylegarec
Copy link
Contributor Author

Thanks @CPatchane 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ Enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants