Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Allow users to add Gerrit HTTP Credentials#46763

Merged
pjlast merged 25 commits into
mainfrom
pjlast/46622-gerrit-account
Jan 27, 2023
Merged

Allow users to add Gerrit HTTP Credentials#46763
pjlast merged 25 commits into
mainfrom
pjlast/46622-gerrit-account

Conversation

@pjlast

@pjlast pjlast commented Jan 23, 2023

Copy link
Copy Markdown
Contributor

Closes #46622

Adds a Gerrit auth provider. It does not provide a sign in option. It appears in the Account Security page where users can add Gerrit HTTP credentials to sync Gerrit permissions.

See loom: https://www.loom.com/share/1fa6d6e5f157481a8a62f7a3703e33ca

Test plan

Lots of unit tests added and updated and I did a lot of manual testing as well.

@sg-e2e-regression-test-bob

sg-e2e-regression-test-bob commented Jan 23, 2023

Copy link
Copy Markdown

Bundle size report 📦

Initial size Total size Async size Modules
0.00% (0.00 kb) 0.02% (+2.87 kb) 0.02% (+2.87 kb) 0.00% (0)

Look at the Statoscope report for a full comparison between the commits ea486c8 and 5bea6c7 or learn more.

Open explanation
  • Initial size is the size of the initial bundle (the one that is loaded when you open the page)
  • Total size is the size of the initial bundle + all the async loaded chunks
  • Async size is the size of all the async loaded chunks
  • Modules is the number of modules in the initial bundle

@pjlast pjlast marked this pull request as ready for review January 23, 2023 11:08
@pjlast pjlast requested a review from a team January 23, 2023 11:08
@sourcegraph-bot

sourcegraph-bot commented Jan 23, 2023

Copy link
Copy Markdown
Contributor

Codenotify: Notifying subscribers in CODENOTIFY files for diff 5bea6c7...ea486c8.

Notify File(s)
@eseliger internal/extsvc/gerrit/account.go
internal/extsvc/gerrit/client.go
internal/extsvc/gerrit/client_test.go
internal/extsvc/gerrit/externalaccount/externalaccount.go
internal/extsvc/gerrit/testdata/golden/ListProjects.json
internal/extsvc/gerrit/testdata/vcr/ListProjects.yaml
@indradhanush internal/repos/gerrit.go
internal/repos/gerrit_test.go
@ryanslade internal/repos/gerrit.go
internal/repos/gerrit_test.go
@sashaostrikov internal/repos/gerrit.go
internal/repos/gerrit_test.go
@sourcegraph/delivery doc/admin/auth/index.md
doc/admin/external_service/gerrit.md
doc/admin/external_service/gerrit.schema.json
doc/admin/external_service/index.md
doc/admin/external_service/other.md
doc/admin/repo/permissions.md
@unknwon enterprise/cmd/frontend/internal/auth/gerrit/config.go
enterprise/cmd/frontend/internal/auth/gerrit/config_test.go
enterprise/cmd/frontend/internal/auth/init.go
enterprise/internal/authz/authz.go
enterprise/internal/authz/authz_test.go
enterprise/internal/authz/bitbucketcloud/authz.go
enterprise/internal/authz/bitbucketcloud/authz_test.go
enterprise/internal/authz/bitbucketserver/authz.go
enterprise/internal/authz/gerrit/authz.go
enterprise/internal/authz/gerrit/client.go
enterprise/internal/authz/gerrit/gerrit.go
enterprise/internal/authz/gerrit/gerrit_test.go
enterprise/internal/authz/github/authz.go
enterprise/internal/authz/github/authz_test.go
enterprise/internal/authz/gitlab/authz.go
enterprise/internal/authz/perforce/authz.go
enterprise/internal/authz/types/types.go

@mrnugget mrnugget left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice!

Comment on lines +148 to +146
permssync.SchedulePermsSync(ctx, r.logger, r.db, protocol.PermsSyncRequest{
UserIDs: []int32{account.UserID},
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We didn't have this before? 🤨

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Good catch 👍

Comment on lines 51 to +56
if (provider.serviceType === 'sourcegraph-operator') {
return new URLSearchParams(location.search).has('sourcegraph-operator')
}
if (provider.serviceType === 'gerrit') {
return false
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Instead of building up a list of hardcoded auth provider names - can we add a property to the authProviders like supportsSignIn?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Plus 1 on this. I was wondering how the PR managed to get rid of gerrit on the sign in list.

We can theoretically use this to hide the builtin auth provider on customer instances after they finish setting up other auth provider. As there were multiple complaints about it being confusing for the engineers on customer side. Or to hide the sourcegraph-operator as well :)

Comment thread cmd/frontend/graphqlbackend/external_accounts.go Outdated
Comment thread cmd/frontend/graphqlbackend/external_accounts.go Outdated
Comment thread cmd/frontend/graphqlbackend/external_accounts.go Outdated
Comment thread cmd/frontend/graphqlbackend/external_accounts.go Outdated
Comment thread cmd/frontend/graphqlbackend/external_accounts.go Outdated
Comment thread enterprise/cmd/frontend/internal/auth/gerrit/config.go Outdated
Comment thread enterprise/cmd/frontend/internal/auth/gerrit/config.go
Comment thread enterprise/cmd/frontend/internal/auth/gerrit/config.go Outdated

@kopancek kopancek left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great work! Sorry for many comments, but I really dived deep into this one as it's important to get it right 🙇

Comment on lines 51 to +56
if (provider.serviceType === 'sourcegraph-operator') {
return new URLSearchParams(location.search).has('sourcegraph-operator')
}
if (provider.serviceType === 'gerrit') {
return false
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Plus 1 on this. I was wondering how the PR managed to get rid of gerrit on the sign in list.

We can theoretically use this to hide the builtin auth provider on customer instances after they finish setting up other auth provider. As there were multiple complaints about it being confusing for the engineers on customer side. Or to hide the sourcegraph-operator as well :)

Comment thread client/web/src/user/settings/auth/AddGerritAccountModal.tsx Outdated
username: { value: string }
password: { value: string }
}
event.preventDefault()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we need the preventDefault here? What will happen if it's removed? (I would expect nothing, since the action is defined as onSubmit on the Form element itself, but I may be wrong...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Based on the React docs: https://reactjs.org/docs/forms.html it seems like you still need to do preventDefault(), otherwise it will do a form submission and do a post request.

Comment on lines +36 to +56
setIsLoading(true)

addExternalAccount({
variables: {
serviceType: 'gerrit',
serviceID,
accountDetails: JSON.stringify({
username: target.username.value,
password: target.password.value,
}),
},
})
.then(() => {
setIsLoading(false)
onDidAdd()
})
.catch(() => {
setIsLoading(false)
})
},
[addExternalAccount, onDidAdd, serviceID]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why is this so complicated? Can we use {loading, data, error} from the useMutation hook instead of calling setIsLoading and handling the promise? For calling onDidAdd you could leverage the onCompleted option on the useMutation hook. Or does it not want to work well with useCallback above?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I just completely blanked on the loading state and the onCompleted option 🤦

Updated, looks a gazillion times better now, thanks!

Comment on lines +33 to +36
if (authProvider.serviceType === 'gerrit') {
setIsGerritAccountModalOpen(true)
return
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We could theoretically get around special casing here by creating another route, say /login/gerrit/openmodal and routing to that from the auth provider button.

But it might be too much hassle for not such a big gain, so feel free to disregard.

ServiceType string
}

func parseConfig(cfg conftypes.SiteConfigQuerier) (ps []Provider, problems conf.Problems) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Consider adding a boolean to return parameters and return true if a gerrit provider config changed (which would mean that the list of providers changed).

func (p *Provider) ConfigID() providers.ConfigID {
return providers.ConfigID{
Type: extsvc.TypeGerrit,
ID: p.ServiceID,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Other auth providers add an identifier to the providers.ConfigID.ID, should we do a similar thing here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

So that makes sense in the case of OAuth because you can have multiple OAuth clients for the same host. But here we're using basic HTTP auth, so there's only client for the entire host.

githuboauth.Init(logger, db)
gitlaboauth.Init(logger, db)
bitbucketcloudoauth.Init(logger, db)
gerrit.Init()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't we need logger in the gerrit instance? Or db?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The Gerrit auth provider does nothing fancy because it's basic HTTP auth. The other ones have a logger and db because they do complex stuff with all the back and forth while doing OAuth, and all those actions get initialised from there.

But for Gerrit it's only "oh here's the URL on you go then".

Comment thread internal/extsvc/gerrit/account.go Outdated
Comment on lines +53 to +54
Login: &blank,
URL: &blank,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Instead of returning empty string, why not omit the lines? These are pointers to a string in the end...

Suggested change
Login: &blank,
URL: &blank,

if err != nil {
return err
}
serializedCreds, err := json.Marshal(creds)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since we store the credentials in the DB as is, what should we do about our dev instances, where DB encryption is off by default if I remember correctly? This might theoretically leak Gerrit credentials...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I mean in those cases we're also storing private keys and oauth tokens unencrypted as well. I'm not sure if this is any more scary than that.

@pjlast pjlast force-pushed the pjlast/46622-gerrit-account branch from 7616b27 to aa3a8b4 Compare January 26, 2023 08:08
@pjlast pjlast force-pushed the pjlast/46622-gerrit-account branch from f65e34e to 48b27d0 Compare January 27, 2023 14:40
@pjlast pjlast enabled auto-merge (squash) January 27, 2023 15:19
@pjlast pjlast merged commit 6394b92 into main Jan 27, 2023
@pjlast pjlast deleted the pjlast/46622-gerrit-account branch January 27, 2023 15:33
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow users to link Gerrit credentials

5 participants