diff --git a/README.md b/README.md index 23d3db8..a75f25c 100644 --- a/README.md +++ b/README.md @@ -73,10 +73,17 @@ check that the server is still running. {} +Some `AuthRealms` support "Starter Links". These are HTTP URLs which knowledgeable clients should use to *start* the auth process. They are commonly returned as metadata to `!commands`. +These links require the client to prove that they own a given user ID by appending a token +to the Starter Link. This token will be used to verify the client's identity by making an +Open ID request to the user's Homeserver via federation. + ## Starting a Github Service ### Register a Github realm +This API allows for an optional `StarterLink` value. + ``` curl -X POST localhost:4050/admin/configureAuthRealm --data-binary '{ "ID": "mygithubrealm", @@ -84,6 +91,7 @@ curl -X POST localhost:4050/admin/configureAuthRealm --data-binary '{ "Config": { "ClientSecret": "YOUR_CLIENT_SECRET", "ClientID": "YOUR_CLIENT_ID", + "StarterLink": "https://example.com/requestGithubOAuthToken", "RedirectBaseURI": "https://public.path.to.neb" } }' @@ -97,6 +105,7 @@ Returns: "NewConfig":{ "ClientSecret":"YOUR_CLIENT_SECRET", "ClientID":"YOUR_CLIENT_ID", + "StarterLink": "https://example.com/requestGithubOAuthToken", "RedirectBaseURI":"https://public.path.to.neb" } } @@ -157,7 +166,7 @@ openssl genrsa -out privkey.pem 2048 cat privkey.pem ``` -Create the realm: +This API allows for an optional `StarterLink` value. Create the realm: ``` curl -X POST localhost:4050/admin/configureAuthRealm --data-binary '{ @@ -165,6 +174,7 @@ curl -X POST localhost:4050/admin/configureAuthRealm --data-binary '{ "Type": "jira", "Config": { "JIRAEndpoint": "matrix.org/jira/", + "StarterLink": "https://example.com/requestJIRAOAuthToken", "ConsumerName": "goneb", "ConsumerKey": "goneb", "ConsumerSecret": "random_long_string", @@ -173,7 +183,14 @@ curl -X POST localhost:4050/admin/configureAuthRealm --data-binary '{ }' ``` +The following keys will be modified/added: + - `JIRAEndpoint` in canonicalised form. + - `Server` and `Version` keys which are purely informational for the caller. + - `PublicKeyPEM` which the caller needs a human to insert into the JIRA Application Links web form. + + Returns: + ```json { "ID": "jirarealm", @@ -181,6 +198,7 @@ Returns: "OldConfig": null, "NewConfig": { "JIRAEndpoint": "https://matrix.org/jira/", + "StarterLink": "https://example.com/requestJIRAOAuthToken", "Server": "Matrix.org", "Version": "6.3.5a", "ConsumerName": "goneb", diff --git a/src/github.com/matrix-org/go-neb/realms/jira/jira.go b/src/github.com/matrix-org/go-neb/realms/jira/jira.go index 27c5a02..765f2a8 100644 --- a/src/github.com/matrix-org/go-neb/realms/jira/jira.go +++ b/src/github.com/matrix-org/go-neb/realms/jira/jira.go @@ -33,6 +33,7 @@ type JIRARealm struct { PublicKeyPEM string // clobbered based on PrivateKeyPEM PrivateKeyPEM string HasWebhook bool // clobbered based on NEB + StarterLink string } // JIRASession represents a single authentication session between a user and a JIRA endpoint. @@ -256,9 +257,7 @@ func (r *JIRARealm) JIRAClient(userID string, allowUnauth bool) (*jira.Client, e // make an unauthenticated client return jira.NewClient(nil, r.JIRAEndpoint) } - return nil, errors.New("No authenticated session found for " + userID) } - // some other error return nil, err } diff --git a/src/github.com/matrix-org/go-neb/services/jira/jira.go b/src/github.com/matrix-org/go-neb/services/jira/jira.go index 9e92af6..8793705 100644 --- a/src/github.com/matrix-org/go-neb/services/jira/jira.go +++ b/src/github.com/matrix-org/go-neb/services/jira/jira.go @@ -117,6 +117,15 @@ func (s *jiraService) cmdJiraCreate(roomID, userID string, args []string) (inter } cli, err := r.JIRAClient(userID, false) if err != nil { + if err == sql.ErrNoRows { // no client found + return matrix.StarterLinkMessage{ + Body: fmt.Sprintf( + "You need to OAuth with JIRA on %s before you can create issues.", + r.JIRAEndpoint, + ), + Link: r.StarterLink, + }, nil + } return nil, err } i, res, err := cli.Issue.Create(&iss) @@ -286,7 +295,6 @@ func (s *jiraService) projectToRealm(userID, pkey string) (*realms.JIRARealm, er // - If there is a matching project with that key, return that realm. // We search installations which the user has already OAuthed with first as most likely // the project key will be on a JIRA they have access to. - // TODO: Return whether they have authed or not so they know if they need to make a starter link logger := log.WithFields(log.Fields{ "user_id": userID, "project": pkey, diff --git a/src/github.com/matrix-org/go-neb/services/jira/webhook/webhook.go b/src/github.com/matrix-org/go-neb/services/jira/webhook/webhook.go index a34765c..b5635d9 100644 --- a/src/github.com/matrix-org/go-neb/services/jira/webhook/webhook.go +++ b/src/github.com/matrix-org/go-neb/services/jira/webhook/webhook.go @@ -119,6 +119,9 @@ func OnReceiveRequest(req *http.Request) (string, *Event, *errors.HTTPError) { func createWebhook(jrealm *realms.JIRARealm, webhookEndpointURL, userID string) error { cli, err := jrealm.JIRAClient(userID, false) + if err != nil { + return err + } req, err := cli.NewRequest("POST", "rest/webhooks/1.0/webhook", jiraWebhook{ Name: "Go-NEB",