Skip to content

Commit

Permalink
add support for JIRA servers prior to v9 (#198)
Browse files Browse the repository at this point in the history
Co-authored-by: pmihaylov_bp <preslav.mihaylov@bottlepay.com>
  • Loading branch information
preslavmihaylov and pmihaylov_bp committed Sep 20, 2022
1 parent 845d11f commit b9fe5d7
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 7 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ Currently, todocheck supports the following issue trackers:
|-------------------------------------------------|-----------------------------------------------------------------------|
| [Github](https://github.com) | Both public & private repositories are supported |
| [Gitlab](https://gitlab.com/) | Both public & private repositories are supported |
| [Jira](https://www.atlassian.com/software/jira) | Supported via offline tokens |
| [Jira](https://www.atlassian.com/software/jira) | Supported via offline and API tokens |
| [Pivotal Tracker](https://pivotaltracker.com/) | Supported via an API token |
| [Redmine](https://redmine.org/) | Supports public access with no auth & private access via an API token |
| [YouTrack](https://www.jetbrains.com/youtrack/) | Supported via an API token
Expand Down
2 changes: 1 addition & 1 deletion config/issuetracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ var validIssueTrackers = []IssueTracker{
}

var originPatterns = map[IssueTracker]*regexp.Regexp{
IssueTrackerJira: regexp.MustCompile(`^(https?://)?[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]+)+(:[0-9]+)?$`),
IssueTrackerJira: regexp.MustCompile(`^(https?://)?[a-zA-Z0-9\-\.]+(:[0-9]+)?$`),
IssueTrackerGithub: regexp.MustCompile(`^(https?://)?(www\.)?github\.com/[\w-]+/[\w-]+`),
IssueTrackerGitlab: regexp.MustCompile(`^(https?://)?[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]+)+(:[0-9]+)?/[\w-]+/[\w-]+$`),
IssueTrackerPivotal: regexp.MustCompile(`^(https?://)?(www\.)?pivotaltracker\.com/n/projects/[0-9]+`),
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ require (
github.com/fatih/color v1.9.0
github.com/mitchellh/go-homedir v1.1.0
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 // indirect
gopkg.in/yaml.v2 v2.2.8
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 h1:ohgcoMbSofXygzo6AD2I1kz3BFmW1QArPYTtwEM3UXc=
golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
49 changes: 44 additions & 5 deletions issuetracker/internal/jira/jira.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,57 @@ package jira

import (
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"

"github.com/preslavmihaylov/todocheck/common"
"github.com/preslavmihaylov/todocheck/config"
"github.com/preslavmihaylov/todocheck/issuetracker"
)

const defaultJIRAVersion = 9

// New creates a new jira issuetracker instance
func New(origin string, authCfg *config.Auth) (*IssueTracker, error) {
return &IssueTracker{origin, authCfg}, nil
return &IssueTracker{
Origin: origin,
AuthCfg: authCfg,
serverVersion: deriveJIRAServerVersion(origin),
}, nil
}

func deriveJIRAServerVersion(origin string) int {
resp, err := http.Get(origin + "/rest/api/2/serverInfo")
if err != nil {
return defaultJIRAVersion
}

type serverInfo struct {
Version string `json:"version"`
}

info := &serverInfo{}
err = json.NewDecoder(resp.Body).Decode(info)
if err != nil || info == nil || info.Version == "" {
return defaultJIRAVersion
}

version, err := strconv.Atoi(strings.Split(info.Version, ".")[0])
if err != nil {
return defaultJIRAVersion
}

return version
}

// IssueTracker is an issue tracker implementation for integrating with private Jira servers
type IssueTracker struct {
Origin string
AuthCfg *config.Auth
Origin string
AuthCfg *config.Auth
serverVersion int
}

// TaskModel returns the model representing a deserialized Jira task
Expand Down Expand Up @@ -49,8 +83,13 @@ func (it *IssueTracker) InstrumentMiddleware(r *http.Request) error {
r.Header.Add("Authorization", "Bearer "+it.AuthCfg.Token)
case config.AuthTypeAPIToken:
common.Assert(it.AuthCfg.Token != "", "authentication token is empty")
data := []byte(fmt.Sprintf("%s:%s", it.AuthCfg.Options["username"], it.AuthCfg.Token))
r.Header.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString(data))
if it.serverVersion >= defaultJIRAVersion {
data := []byte(fmt.Sprintf("%s:%s", it.AuthCfg.Options["username"], it.AuthCfg.Token))
r.Header.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString(data))
} else {
// versions prior to v8 use a Bearer authorization scheme
r.Header.Add("Authorization", "Bearer "+it.AuthCfg.Token)
}
default:
return fmt.Errorf("unsupported authentication token type for jira: %s", it.AuthCfg.Type)
}
Expand Down

0 comments on commit b9fe5d7

Please sign in to comment.