github.com/inteleradmedicalsystems/go-codecommit@v0.1.0/pkg/codecommit/codecommit.go (about) 1 package codecommit 2 3 import ( 4 "fmt" 5 nurl "net/url" 6 "regexp" 7 "strings" 8 "time" 9 10 "github.com/aws/aws-sdk-go/aws/credentials" 11 "github.com/aws/aws-sdk-go/aws/endpoints" 12 "github.com/aws/aws-sdk-go/aws/session" 13 ) 14 15 // 16 var RegionRe *regexp.Regexp 17 18 func init() { 19 RegionRe = regexp.MustCompile(`git-codecommit\.([^.]+)\.amazonaws\.com`) 20 } 21 22 //IsCodeCommitURL return true if the url is for a CodeCommit Git repo. 23 func IsCodeCommitURL(url string) bool { 24 u, err := nurl.Parse(url) 25 if err != nil { 26 return false 27 } 28 return RegionRe.MatchString(u.Host) 29 } 30 31 //NewCloneURL return CloneURL object for CodeCommit 32 func NewCloneURL(sess *session.Session, url string) (*CloneURL, error) { 33 var err error 34 if creds, err := sess.Config.Credentials.Get(); err == nil { 35 c := &CloneURL{ 36 RawURL: url, 37 CredValues: creds, 38 } 39 if err = c.setURL(); err == nil { 40 return c, nil 41 } 42 } 43 return nil, err 44 } 45 46 type CloneURL struct { 47 RawURL string 48 CredValues credentials.Value 49 u *nurl.URL 50 } 51 52 func (c *CloneURL) setURL() error { 53 u, err := nurl.Parse(c.RawURL) 54 if err != nil { 55 return err 56 } 57 c.u = u 58 return nil 59 } 60 61 // 62 func (c *CloneURL) buildCloneURL() error { 63 err := c.setURL() 64 if err != nil { 65 return err 66 } 67 if c.u.User == nil && strings.Split(c.u.Hostname(), ".")[0] == "git-codecommit" { 68 if err = c.addCodeCommitCreds(); err != nil { 69 return err 70 } 71 } 72 return err 73 } 74 75 // Include the CodeCommit HTTP AUTH params . 76 func (c *CloneURL) addCodeCommitCreds() error { 77 if creds, err := c.GetCodeCommitCredentials(); err == nil { 78 c.u.User = nurl.UserPassword(creds.Username, creds.Password) 79 } else { 80 return err 81 } 82 return nil 83 } 84 85 func (c *CloneURL) String() string { 86 err := c.buildCloneURL() 87 if err != nil { 88 return "" 89 } 90 return c.u.String() 91 } 92 93 //GetCodeCommitCredentials return CodeCommitCredentials for URL 94 func (c *CloneURL) GetCodeCommitCredentials() (*CodeCommitCredentials, error) { 95 region, err := c.parseRegion() 96 if err != nil { 97 return nil, err 98 } 99 100 ctx := NewSigningContext(c.u, region, endpoints.CodecommitServiceID, c.CredValues, time.Now()) 101 username := c.CredValues.AccessKeyID 102 if c.CredValues.SessionToken != "" { 103 username = fmt.Sprintf("%s%%%s", username, c.CredValues.SessionToken) 104 } 105 106 return &CodeCommitCredentials{ 107 Username: username, 108 Password: ctx.signCodeCommitRequest(), 109 }, nil 110 } 111 112 func (c *CloneURL) parseRegion() (string, error) { 113 if c.u == nil { 114 return "", fmt.Errorf("url is not set") 115 116 } 117 match := RegionRe.FindStringSubmatch(c.u.Host) 118 if match != nil { 119 return match[1], nil 120 } 121 122 return "", fmt.Errorf("invalid CodeCommit URL %q", c.u.String()) 123 } 124 125 type CodeCommitCredentials struct { 126 Username string 127 Password string 128 }