@@ -4,13 +4,15 @@ import (
44 "fmt"
55 "net/url"
66 "os"
7+ "strings"
78 "testing"
89 "time"
910
1011 "github.com/containrrr/watchtower/internal/actions/mocks"
1112 "github.com/containrrr/watchtower/pkg/registry/auth"
1213
1314 wtTypes "github.com/containrrr/watchtower/pkg/types"
15+ ref "github.com/docker/distribution/reference"
1416 . "github.com/onsi/ginkgo"
1517 . "github.com/onsi/gomega"
1618)
@@ -52,7 +54,7 @@ var _ = Describe("the auth module", func() {
5254 mockCreated ,
5355 mockDigest )
5456
55- When ( "getting an auth url " , func () {
57+ Describe ( "GetToken " , func () {
5658 It ("should parse the token from the response" ,
5759 SkipIfCredentialsEmpty (GHCRCredentials , func () {
5860 creds := fmt .Sprintf ("%s:%s" , GHCRCredentials .Username , GHCRCredentials .Password )
@@ -61,73 +63,100 @@ var _ = Describe("the auth module", func() {
6163 Expect (token ).NotTo (Equal ("" ))
6264 }),
6365 )
66+ })
6467
68+ Describe ("GetAuthURL" , func () {
6569 It ("should create a valid auth url object based on the challenge header supplied" , func () {
66- input := `bearer realm="https://ghcr.io/token",service="ghcr.io",scope="repository:user/image:pull"`
70+ challenge := `bearer realm="https://ghcr.io/token",service="ghcr.io",scope="repository:user/image:pull"`
71+ imageRef , err := ref .ParseNormalizedNamed ("containrrr/watchtower" )
72+ Expect (err ).NotTo (HaveOccurred ())
6773 expected := & url.URL {
6874 Host : "ghcr.io" ,
6975 Scheme : "https" ,
7076 Path : "/token" ,
7177 RawQuery : "scope=repository%3Acontainrrr%2Fwatchtower%3Apull&service=ghcr.io" ,
7278 }
73- res , err := auth .GetAuthURL (input , "containrrr/watchtower" )
79+
80+ URL , err := auth .GetAuthURL (challenge , imageRef )
7481 Expect (err ).NotTo (HaveOccurred ())
75- Expect (res ).To (Equal (expected ))
82+ Expect (URL ).To (Equal (expected ))
7683 })
77- It ("should create a valid auth url object based on the challenge header supplied" , func () {
78- input := `bearer realm="https://ghcr.io/token"`
79- res , err := auth .GetAuthURL (input , "containrrr/watchtower" )
80- Expect (err ).To (HaveOccurred ())
81- Expect (res ).To (BeNil ())
84+
85+ When ("given an invalid challenge header" , func () {
86+ It ("should return an error" , func () {
87+ challenge := `bearer realm="https://ghcr.io/token"`
88+ imageRef , err := ref .ParseNormalizedNamed ("containrrr/watchtower" )
89+ Expect (err ).NotTo (HaveOccurred ())
90+ URL , err := auth .GetAuthURL (challenge , imageRef )
91+ Expect (err ).To (HaveOccurred ())
92+ Expect (URL ).To (BeNil ())
93+ })
94+ })
95+
96+ When ("deriving the auth scope from an image name" , func () {
97+ It ("should prepend official dockerhub images with \" library/\" " , func () {
98+ Expect (getScopeFromImageAuthURL ("registry" )).To (Equal ("library/registry" ))
99+ Expect (getScopeFromImageAuthURL ("docker.io/registry" )).To (Equal ("library/registry" ))
100+ Expect (getScopeFromImageAuthURL ("index.docker.io/registry" )).To (Equal ("library/registry" ))
101+ })
102+ It ("should not include vanity hosts\" " , func () {
103+ Expect (getScopeFromImageAuthURL ("docker.io/containrrr/watchtower" )).To (Equal ("containrrr/watchtower" ))
104+ Expect (getScopeFromImageAuthURL ("index.docker.io/containrrr/watchtower" )).To (Equal ("containrrr/watchtower" ))
105+ })
106+ It ("should not destroy three segment image names\" " , func () {
107+ Expect (getScopeFromImageAuthURL ("piksel/containrrr/watchtower" )).To (Equal ("piksel/containrrr/watchtower" ))
108+ Expect (getScopeFromImageAuthURL ("ghcr.io/piksel/containrrr/watchtower" )).To (Equal ("piksel/containrrr/watchtower" ))
109+ })
110+ It ("should not prepend library/ to image names if they're not on dockerhub" , func () {
111+ Expect (getScopeFromImageAuthURL ("ghcr.io/watchtower" )).To (Equal ("watchtower" ))
112+ Expect (getScopeFromImageAuthURL ("ghcr.io/containrrr/watchtower" )).To (Equal ("containrrr/watchtower" ))
113+ })
82114 })
83115 It ("should not crash when an empty field is recieved" , func () {
84116 input := `bearer realm="https://ghcr.io/token",service="ghcr.io",scope="repository:user/image:pull",`
85- res , err := auth .GetAuthURL (input , "containrrr/watchtower" )
117+ imageRef , err := ref .ParseNormalizedNamed ("containrrr/watchtower" )
118+ Expect (err ).NotTo (HaveOccurred ())
119+ res , err := auth .GetAuthURL (input , imageRef )
86120 Expect (err ).NotTo (HaveOccurred ())
87121 Expect (res ).NotTo (BeNil ())
88122 })
89123 It ("should not crash when a field without a value is recieved" , func () {
90124 input := `bearer realm="https://ghcr.io/token",service="ghcr.io",scope="repository:user/image:pull",valuelesskey`
91- res , err := auth .GetAuthURL (input , "containrrr/watchtower" )
125+ imageRef , err := ref .ParseNormalizedNamed ("containrrr/watchtower" )
126+ Expect (err ).NotTo (HaveOccurred ())
127+ res , err := auth .GetAuthURL (input , imageRef )
92128 Expect (err ).NotTo (HaveOccurred ())
93129 Expect (res ).NotTo (BeNil ())
94130 })
95131 })
96- When ("getting a challenge url" , func () {
132+
133+ Describe ("GetChallengeURL" , func () {
97134 It ("should create a valid challenge url object based on the image ref supplied" , func () {
98135 expected := url.URL {Host : "ghcr.io" , Scheme : "https" , Path : "/v2/" }
99- Expect (auth .GetChallengeURL ("ghcr.io/containrrr/watchtower:latest" )).To (Equal (expected ))
136+ imageRef , _ := ref .ParseNormalizedNamed ("ghcr.io/containrrr/watchtower:latest" )
137+ Expect (auth .GetChallengeURL (imageRef )).To (Equal (expected ))
100138 })
101- It ("should assume dockerhub if the image ref is not fully qualified " , func () {
139+ It ("should assume Docker Hub for image refs with no explicit registry " , func () {
102140 expected := url.URL {Host : "index.docker.io" , Scheme : "https" , Path : "/v2/" }
103- Expect (auth .GetChallengeURL ("containrrr/watchtower:latest" )).To (Equal (expected ))
141+ imageRef , _ := ref .ParseNormalizedNamed ("containrrr/watchtower:latest" )
142+ Expect (auth .GetChallengeURL (imageRef )).To (Equal (expected ))
104143 })
105- It ("should convert legacy dockerhub hostnames to index. docker.io" , func () {
144+ It ("should use index.docker.io if the image ref specifies docker.io" , func () {
106145 expected := url.URL {Host : "index.docker.io" , Scheme : "https" , Path : "/v2/" }
107- Expect ( auth . GetChallengeURL ("docker.io/containrrr/watchtower:latest" )). To ( Equal ( expected ) )
108- Expect (auth .GetChallengeURL ("registry-1.docker.io/containrrr/watchtower:latest" )).To (Equal (expected ))
146+ imageRef , _ := ref . ParseNormalizedNamed ("docker.io/containrrr/watchtower:latest" )
147+ Expect (auth .GetChallengeURL (imageRef )).To (Equal (expected ))
109148 })
110149 })
111- When ("getting the auth scope from an image name" , func () {
112- It ("should prepend official dockerhub images with \" library/\" " , func () {
113- Expect (auth .GetScopeFromImageName ("docker.io/registry" , "index.docker.io" )).To (Equal ("library/registry" ))
114- Expect (auth .GetScopeFromImageName ("docker.io/registry" , "docker.io" )).To (Equal ("library/registry" ))
150+ })
115151
116- Expect (auth .GetScopeFromImageName ("registry" , "index.docker.io" )).To (Equal ("library/registry" ))
117- Expect (auth .GetScopeFromImageName ("watchtower" , "registry-1.docker.io" )).To (Equal ("library/watchtower" ))
152+ var scopeImageRegexp = MatchRegexp ("^repository:[a-z0-9]+(/[a-z0-9]+)*:pull$" )
118153
119- })
120- It ("should not include vanity hosts\" " , func () {
121- Expect (auth .GetScopeFromImageName ("docker.io/containrrr/watchtower" , "index.docker.io" )).To (Equal ("containrrr/watchtower" ))
122- Expect (auth .GetScopeFromImageName ("index.docker.io/containrrr/watchtower" , "index.docker.io" )).To (Equal ("containrrr/watchtower" ))
123- })
124- It ("should not destroy three segment image names\" " , func () {
125- Expect (auth .GetScopeFromImageName ("piksel/containrrr/watchtower" , "index.docker.io" )).To (Equal ("containrrr/watchtower" ))
126- Expect (auth .GetScopeFromImageName ("piksel/containrrr/watchtower" , "ghcr.io" )).To (Equal ("piksel/containrrr/watchtower" ))
127- })
128- It ("should not add \" library/\" for one segment image names if they're not on dockerhub" , func () {
129- Expect (auth .GetScopeFromImageName ("ghcr.io/watchtower" , "ghcr.io" )).To (Equal ("watchtower" ))
130- Expect (auth .GetScopeFromImageName ("watchtower" , "ghcr.io" )).To (Equal ("watchtower" ))
131- })
132- })
133- })
154+ func getScopeFromImageAuthURL (imageName string ) string {
155+ normalizedRef , _ := ref .ParseNormalizedNamed (imageName )
156+ challenge := `bearer realm="https://dummy.host/token",service="dummy.host",scope="repository:user/image:pull"`
157+ URL , _ := auth .GetAuthURL (challenge , normalizedRef )
158+
159+ scope := URL .Query ().Get ("scope" )
160+ Expect (scopeImageRegexp .Match (scope )).To (BeTrue ())
161+ return strings .Replace (scope [11 :], ":pull" , "" , 1 )
162+ }
0 commit comments