-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathconnection.go
More file actions
134 lines (109 loc) · 3.07 KB
/
connection.go
File metadata and controls
134 lines (109 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1
package jira
import (
"context"
"errors"
"net/url"
"os"
"strings"
v2 "github.com/ctreminiom/go-atlassian/v2/jira/v2"
"go.mondoo.com/mql/v13/providers-sdk/v1/inventory"
"go.mondoo.com/mql/v13/providers-sdk/v1/plugin"
"go.mondoo.com/mql/v13/providers/atlassian/connection/shared"
)
const (
Jira shared.ConnectionType = "jira"
)
type JiraConnection struct {
plugin.Connection
Conf *inventory.Config
asset *inventory.Asset
client *v2.Client
name string
}
// normalizeAndValidateHost normalizes the host to https:// format and validates it's a proper domain
func normalizeAndValidateHost(val string) (string, error) {
if val == "" {
return "", errors.New("host cannot be empty")
}
// Add https:// scheme if not present
if !strings.HasPrefix(val, "http://") && !strings.HasPrefix(val, "https://") {
val = "https://" + val
}
// Parse the URL to validate it
u, err := url.Parse(val)
if err != nil {
return "", errors.New("invalid host format")
}
// Ensure we have a valid scheme and host
if u.Scheme == "" || u.Host == "" {
return "", errors.New("invalid host format")
}
// Force https scheme
u.Scheme = "https"
return u.String(), nil
}
func NewConnection(id uint32, asset *inventory.Asset, conf *inventory.Config) (*JiraConnection, error) {
host := conf.Options["host"]
if host == "" {
host = os.Getenv("ATLASSIAN_HOST")
}
normalizedHost, err := normalizeAndValidateHost(host)
if err != nil {
return nil, errors.New("you must provide a valid Atlassian host e.g. via ATLASSIAN_HOST env or via the --host flag (e.g., 'foo.atlassian.net' or 'https://foo.atlassian.net')")
}
host = normalizedHost
user := conf.Options["user"]
if user == "" {
user = os.Getenv("ATLASSIAN_USER")
}
if user == "" {
return nil, errors.New("you must provide an Atlassian user e.g. via ATLASSIAN_USER env or via the --user flag")
}
token := conf.Options["user-token"]
if token == "" {
token = os.Getenv("ATLASSIAN_USER_TOKEN")
}
if token == "" {
return nil, errors.New("you must provide an Atlassian user token e.g. via ATLASSIAN_USER_TOKEN env or via the --user-token flag")
}
client, err := v2.New(nil, host)
if err != nil {
return nil, err
}
client.Auth.SetBasicAuth(user, token)
client.Auth.SetUserAgent("curl/7.54.0")
expand := []string{""}
_, response, _ := client.MySelf.Details(context.Background(), expand)
if response != nil {
if response.StatusCode == 401 {
return nil, errors.New("failed to authenticate")
}
}
return &JiraConnection{
Connection: plugin.NewConnection(id, asset),
Conf: conf,
asset: asset,
client: client,
name: host,
}, nil
}
func (c *JiraConnection) Name() string {
return c.name
}
func (c *JiraConnection) Asset() *inventory.Asset {
return c.asset
}
func (c *JiraConnection) Client() *v2.Client {
return c.client
}
func (p *JiraConnection) Type() shared.ConnectionType {
return Jira
}
func (c *JiraConnection) ConnectionType() string {
return "jira"
}
func (c *JiraConnection) Config() *inventory.Config {
return c.Conf
}