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

Feat/config installer #13

Open
wants to merge 35 commits into
base: main
Choose a base branch
from

Conversation

Keyrxng
Copy link
Member

@Keyrxng Keyrxng commented Nov 9, 2024

Resolves #3
Requires #11 and #12 (reviewing those could be skipped and focus placed just on this PR)

  • Listing all plugins from ubiquity-os-marketplace and grabbing manifests
  • Login with GitHub App: fetch user orgs with app installs.
  • Select org: Select config: Select Plugin
  • Update configuration based on manifest values
  • Save to local and optionally push to GitHub
  • Can build multiple plugins before pushing to GitHub

Still buggy with some plugins I need to inspect the more complex ones and handle their configs better but this shows what it looks like with a plugin with a medium size config. It should be ready to over the next day.

@zugdev Idk if you want to work your magic after this is merged, branch off and PR against dev or into this before that or just review and create a spec for what's needed? What do you think?


We can still build this UI with the ability to read from a query param directly too but it's a cleaner approach housing them all imo.

  • I'm thinking pull the plugin README and display it beside the configuration?
  • breadcrumbs would be good to jump back and re-select plugin, config, org.
  • it's pretty verbose but additional details in the manifest for each prop. In .ts we use JSDoc comments on input props and it fills the IDE. This would be handy af if we had a workflow to parse these and write them to the manifest which could be read on this UI: e.g requiredLabelsToStart without defaults might be confusing to a partner

QA:

plugin-installer-demo.mp4

@Keyrxng
Copy link
Member Author

Keyrxng commented Nov 9, 2024

  1. manifest.name should reflect the repository name so we can match it to the worker/action url
  2. all plugin manifests rendering without error.
  3. redesigning the UI to accommodate the extensive configs should be spec'd
  4. I've achieved the spec as it exists for this task, following some minor tweaks to config prop options this is review ready.

QA with official plugin URL:

demo-sbs.mp4

@zugdev I saw you say that this codebase is your scope, perhaps you want to start reviewing my PRs as I think 0x4007 is busy.

@Keyrxng Keyrxng mentioned this pull request Nov 9, 2024
.cspell.json Outdated Show resolved Hide resolved
.env.example Outdated Show resolved Hide resolved
.eslintrc Outdated Show resolved Hide resolved
.github/CODEOWNERS Outdated Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
@Keyrxng
Copy link
Member Author

Keyrxng commented Nov 11, 2024

I'm going to move on and complete other tasks while reviews are pending

@zugdev
Copy link

zugdev commented Nov 12, 2024

If I sign in with an account that has nothing to show, we should tell that to the user.

image

The auth token is not being cleared on sign out, the only way for me to currently logout is to clear my cookies manually.

Screen.Recording.2024-11-12.001120.mp4

Also we have a scope error that is not allowing it to fetch my orgs correctly, I've pinpointed the issue in my review comments:

image

zugdev

This comment was marked as resolved.

@zugdev
Copy link

zugdev commented Nov 12, 2024

I think you should try catch whatever can fail, that certainly includes HTTP requests. For instance, to get the list of app installations you need an authenticated GitHub app. I couldn't login with my org so I got deadlocked. We should at least show a message in those cases.

@zugdev
Copy link

zugdev commented Nov 12, 2024

Some points for setup:

  1. Your DB auth should be tied to a GitHub App not an OAuth app. The kernel is a GitHub app, the same is required for this because we need permissions that are out of scope for a normal OAuth app.

Ignore what I previously said about auth, already hid my comments, my Supabase is set for OAuth - my bad. However I still believe there should be try catches.

How should I set this up? I don't see a way to do it in Supabase's dashboard. Or did you mean signing in with a GitHub app? If that's the case, I wasn't able to.

static/main.ts Show resolved Hide resolved
public async getGitHubUserOrgs(): Promise<string[]> {
const octokit = await this.getOctokit();
const response = await octokit.request("GET /user/orgs");
Copy link

Choose a reason for hiding this comment

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

This is failing, it seems that the correct endpoint for this request would be "GET /organizations", based on this piece of docs: https://docs.github.com/pt/rest/orgs/orgs?apiVersion=2022-11-28#list-organizations

Copy link
Member Author

Choose a reason for hiding this comment

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

No that's list all organizations I'm calling listForAuthenticatedUser

https://docs.github.com/en/rest/orgs/orgs?apiVersion=2022-11-28#list-organizations-for-the-authenticated-user


I'll use octokit.rest.listForAuthneticated method to clear any confusion

Copy link
Member Author

@Keyrxng Keyrxng Nov 14, 2024

Choose a reason for hiding this comment

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

It's likely failing due to your permissions.

When I was showing you how to run the kernel and plugins I told you to update your kernel app's permissions at it had very very few, I trust you did this yeah?

  1. GitHub App needs permissions set.
  2. Supabase auth needs updated with your GitHub app Client ID and secret.
  3. Update the GH App callback URL to be Supabase.
  4. Login and it should be able to list your orgs bud.

For OAuth app tokens and personal access tokens (classic), this endpoint only lists organizations that your authorization allows you to operate on in some way (e.g., you can list teams with read:org scope, you can publicize your organization membership with user scope, etc.). Therefore, this API requires at least user or read:org scope for OAuth app tokens and personal access tokens (classic). Requests with insufficient scope will receive a 403 Forbidden response.

Copy link

@zugdev zugdev Nov 14, 2024

Choose a reason for hiding this comment

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

  1. Supabase auth needs updated with your GitHub app Client ID and secret.

What do you mean with this, exactly? Is it in a secrets format, or an oauth config perhaps? Where do I set this up?

Copy link

@Keyrxng, this task has been idle for a while. Please provide an update.

@Keyrxng
Copy link
Member Author

Keyrxng commented Nov 14, 2024

So the only changes requested I can implement is to ensure the auth token is popped from local?

I'll also wrap main in a try-catch and capture any errors

@rndquu rndquu self-requested a review November 15, 2024 10:59
Copy link
Member

@rndquu rndquu left a comment

Choose a reason for hiding this comment

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

  1. Getting the authentication.ts:127 GET https://api.github.com/user/orgs 403 (Forbidden) on github auth:
Screenshot 2024-11-15 at 14 20 17

Perhaps we should pass the read:org scope similarly to how it works in work.ubq.fi?

  1. Pls make all CI workflows passing:
    a) For failing build you may hardcode values
    b) For failing empty strings workflow you may refactor the code
    c) For failing knip unused dependencies should be removed
    d) For failing cypress values can be hardcoded
    e) For failing jest either remove the test either fix the octokit related error

@rndquu
Copy link
Member

rndquu commented Nov 15, 2024

@Keyrxng #12 is included in the current PR, correct?

@Keyrxng
Copy link
Member Author

Keyrxng commented Nov 15, 2024

#12 is included in the current PR, correct?

Yeah that's right, using the methods but the approach has changed.

Perhaps we should pass the read:org scope similarly to how it works in work.ubq.fi?

I setup my auth using a GitHub App not an OAuth App (more here) for a couple of reasons. Finer control over scopes and gets us access to potentially private orgs too. I used the same app as my UbiquityOS dev instance as it made sense to do the same for prod.

const userOrgs = await auth.getGitHubUserOrgs();
const appInstallations = await auth.octokit?.apps.listInstallationsForAuthenticatedUser();
const installs = appInstallations?.data.installations;
const orgsWithInstalls = userOrgs.map((org) => {
const orgInstall = installs?.find((install) => {
if (install.account && "login" in install.account) {
return install.account.login.toLowerCase() === org.toLowerCase();

  1. Collect orgs via authenticated user (our GitHub app permissions setup controls visibility)
  2. Use app to obtain all installs
  3. Map over the user's orgs and find only the orgs which have UbiquityOS installed

In general, GitHub Apps are preferred over OAuth apps. GitHub Apps use fine-grained permissions, give the user more control over which repositories the app can access, and use short-lived tokens. These properties can harden the security of your app by limiting the damage that could be done if your app's credentials were leaked.

image

Supabase auth needs updated with your GitHub app Client ID and secret.

What do you mean with this, exactly? Is it in a secrets format, or an oauth config perhaps? Where do I set this up?

You'll find that in the Authentication > Providers section on Supabase.

image

Pls make all CI workflows passing:

I'll make changes so that they pass for now no problem

@zugdev
Copy link

zugdev commented Nov 15, 2024

Thanks for the guide, I'll QA it soon.

@Keyrxng
Copy link
Member Author

Keyrxng commented Nov 15, 2024

Thanks for the guide, I'll QA it soon.

Np. It would be better if I could QA with the production app details but I'm basing my logic on these responses.

I have only one org but my dev app is installed on my personal account too (production will only ever be installed to orgs) so it follows that the owner of the org (or admins etc if we support that) would be the one to install plugins (at least the initial setup).

image

I assume we'd support other roles besides owner but that will require additional logic for validating the user has permissions to update the config etc. Which roles would be allowed to install/update/remove, is this configurable at the partner level or UI level for example (org config sounds good for this)

@Keyrxng
Copy link
Member Author

Keyrxng commented Nov 15, 2024

Empty strings CI is not failing because of empty strings in the code it presents warnings in the review diff as sometimes their usage is needed, instead it's failing because of:

Error: An error occurred: Resource not accessible by integration - https://docs.github.com/rest/checks/runs#create-a-check-run

I've implemented the requested changes and previous auth issues were not because of the code itself so I think this is ready for review.

@Keyrxng Keyrxng marked this pull request as ready for review November 15, 2024 17:08
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.

Create add/remove config logic
4 participants