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

Draft: Telemetry for v2 routes #202

Merged
merged 18 commits into from
Jan 10, 2023
Merged

Draft: Telemetry for v2 routes #202

merged 18 commits into from
Jan 10, 2023

Conversation

vmatsiiako
Copy link
Collaborator

No description provided.

type: rawSecret.type,
user: new Types.ObjectId(req.user._id)
}

sanitizedSecretesToCreate.push(safeUpdateFields)
})

const [bulkCreateError, newlyCreatedSecrets] = await to(Secret.insertMany(sanitizedSecretesToCreate).then())
const [bulkCreateError, secrets] = await to(Secret.insertMany(sanitizedSecretesToCreate).then())
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a Typo? Isn't the correct form is "sanitizedSecretsToCreate"

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think it might be, but this controller is not user anymore. We will deprecate it soon, but for now the correct version is in secretsContoller.ts

userAgent: req.headers?.['user-agent']
}
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This PostHog boilerplate takes a lot of space and not easy to change in bulk in the future. Is it possible to seperate to function and use that function?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hmmm interesting! How would you do it? Personally I'd say it's already pretty concise, though it does take a lot of space

Copy link
Contributor

Choose a reason for hiding this comment

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

What about we create a function to get distinctId, channel, userAgent from req and context variable which extends the default. Something like this;

type PostHogEventData = {
    event: string
    distinctId: string
    properties: Record<any,any> & {
        channel?: "web"|"cli"
        userAgent?: string
    }
}

function capturePostHogEvent(eventName: string, req: Request, context: Partial<PostHogEventData>){
    if(!postHogClient) return;

    const postHogData = Object.assign({
        event: eventName,
        distinctId: req.user.email,
        properties: {
            channel: req.headers?.['user-agent']?.toLowerCase().includes('mozilla') ? 'web' : 'cli',
            userAgent: req.headers?.['user-agent']
        }
    }, context)

    postHogClient.capture(postHogData);
}

...

capturePostHogEvent('secrets_added', req, {
    properties: {
        numberOfSecrets: 1,
        workspaceId,
        environment
    }
})

Copy link
Collaborator

Choose a reason for hiding this comment

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

Agree with this!

I think we can add this as an extension to /services/PostHogClient in the backend. We can convert it to a class and have some useful methods on there like this one to capture events.

In the interest of time and un-blocking some people, we're going to merge this PR and add in this change in a separate PR. Feel free to submit a new PR with this modularization after the merge!

Copy link
Contributor

@Zamion101 Zamion101 left a comment

Choose a reason for hiding this comment

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

There needs some changes to this PR and associated commits. There are some parts that we can optimize and some parts that we can seperate logics to their own functions for the purpose of easier to manage in the future. I would like to get your opininons on my reviews.

secretIdsToDelete.forEach(secretIdToDelete => {
if (secretsUserCanDeleteSet.has(secretIdToDelete)) {
const deleteOperation = { deleteOne: { filter: { _id: new Types.ObjectId(secretIdToDelete) } } }
deleteOperationsToPerform.push(deleteOperation)
numSecretsDeleted++;
} else {
throw RouteValidationError({ message: "You cannot delete secrets that you do not have access to" })
Copy link
Contributor

Choose a reason for hiding this comment

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

Won't this piece of code stop the process of deleting other secrets? Like if I want to delete 10 secrets in bulk but second secret in array throws this error, won't be the other remaining secrets not deleted? There is no redundancy for errors as well. Transactions and Bulk operations should follow Atomicity from ACID while working on databases.

Error Message should point to which of the secret(s) user do not have access to.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, as mentioned above, I think this controller is about to be deprecated

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yup this controller will be deprecated soon pretty much after the merge as we transition to the new endpoints in v2/secrets.

secretIds: secrets.map((n: any) => n._id)
});

readAction && await EELogService.createLog({
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this code be simplified and take advantage of Promises?

await EELogService.createActionSecret({
        name: ACTION_READ_SECRETS,
        userId: req.user._id.toString(),
        workspaceId: workspaceId as string,
        secretIds: secrets.map((n: any) => n._id)
    })
    .then((readAction)=>{
        EELogService.createLog({
             userId: req.user._id.toString(),
             workspaceId: workspaceId as string,
             actions: [readAction],
             channel,
             ipAddress: req.ip
        });
    })
    .then(()=>{return res.status(200).json({secrets})})

or just be entirely async without await, it will speed up response time because response is not dependent to Audit Logs success status.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah yea we can do without await then because you're right response is not dependent on the audit log success status — Let's submit that in the next PR

secretCommentCiphertext,
secretCommentIV,
secretCommentTag
} = secret;
Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer to just use secret.xyz in required fields rather then deconstructing to seperate variables like here. It's just makes code hard to read because of the variables that used once and never again below code.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sounds good I'll make this adjustment after!

router.post(
'/',
body('workspaceId').exists().isString().trim(),
body('environment').exists().isString().trim().isIn(['dev', 'staging', 'prod', 'test']),
Copy link
Contributor

Choose a reason for hiding this comment

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

So what about custom envrionment names?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think we don't have customer environment names yet. But agree, when we implement that we should change that

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah Akhil will add these right after.

throw new Error('secrets array must contain objects that conform to the Secret interface');
}
}
} else if (typeof value === 'object') {
Copy link
Contributor

Choose a reason for hiding this comment

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

I have seen this check a lot in this PR. If we're gonna use this check over and over again we need to make it seperate function and use that function here. It's really not easy to manage in this scale.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sounds good. I'll throw this check into a helper function 👌


router.delete(
'/',
[
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this correct? The check is inside of Array but the Array is not deconstructed. Should the correct form be ...[check('secretIds')]

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah I believe it's correct. I've tested it with and without correct secretIds

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh actually hmm maybe it would also work without the array..

Copy link
Collaborator

Choose a reason for hiding this comment

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

Alrighty fixed.

@dangtony98 dangtony98 closed this Jan 10, 2023
@dangtony98 dangtony98 reopened this Jan 10, 2023
@dangtony98 dangtony98 marked this pull request as ready for review January 10, 2023 08:26
@dangtony98 dangtony98 merged commit cbfd35e into main Jan 10, 2023
@dangtony98 dangtony98 deleted the ph-telemetry branch January 10, 2023 08:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants