@@ -111,6 +111,155 @@ func TestBearerAuthorizer(t *testing.T) {
111111 })
112112 })
113113
114+ Convey ("Access entry with per-entry ExpiresAt" , func () {
115+ now := time .Now ()
116+
117+ Convey ("Authorized when ExpiresAt is in the future" , func () {
118+ access := []api.ResourceAccess {
119+ {
120+ Name : "authorized-repository" ,
121+ Type : "repository" ,
122+ Actions : []string {"pull" },
123+ ExpiresAt : jwt .NewNumericDate (now .Add (time .Hour )),
124+ },
125+ }
126+
127+ claims := api.ClaimsWithAccess {
128+ Access : access ,
129+ RegisteredClaims : jwt.RegisteredClaims {
130+ ExpiresAt : jwt .NewNumericDate (now .Add (time .Hour )),
131+ IssuedAt : jwt .NewNumericDate (now ),
132+ Issuer : "Zot" ,
133+ Audience : []string {"Zot Registry" },
134+ },
135+ }
136+
137+ token , err := jwt .NewWithClaims (signingMethod , claims ).SignedString (privKey )
138+ So (err , ShouldBeNil )
139+
140+ requested := & api.ResourceAction {
141+ Type : "repository" ,
142+ Name : "authorized-repository" ,
143+ Action : "pull" ,
144+ }
145+
146+ err = authorizer .Authorize ("Bearer " + token , requested )
147+ So (err , ShouldBeNil )
148+ })
149+
150+ Convey ("Denied when ExpiresAt is in the past" , func () {
151+ access := []api.ResourceAccess {
152+ {
153+ Name : "authorized-repository" ,
154+ Type : "repository" ,
155+ Actions : []string {"pull" },
156+ ExpiresAt : jwt .NewNumericDate (now .Add (- time .Hour )),
157+ },
158+ }
159+
160+ claims := api.ClaimsWithAccess {
161+ Access : access ,
162+ RegisteredClaims : jwt.RegisteredClaims {
163+ ExpiresAt : jwt .NewNumericDate (now .Add (time .Hour )),
164+ IssuedAt : jwt .NewNumericDate (now ),
165+ Issuer : "Zot" ,
166+ Audience : []string {"Zot Registry" },
167+ },
168+ }
169+
170+ token , err := jwt .NewWithClaims (signingMethod , claims ).SignedString (privKey )
171+ So (err , ShouldBeNil )
172+
173+ requested := & api.ResourceAction {
174+ Type : "repository" ,
175+ Name : "authorized-repository" ,
176+ Action : "pull" ,
177+ }
178+
179+ err = authorizer .Authorize ("Bearer " + token , requested )
180+ So (err , ShouldHaveSameTypeAs , & api.AuthChallengeError {})
181+ So (err , ShouldBeError , zerr .ErrInsufficientScope )
182+ })
183+
184+ Convey ("Only the expired entry is skipped, other entries still work" , func () {
185+ access := []api.ResourceAccess {
186+ {
187+ Name : "authorized-repository" ,
188+ Type : "repository" ,
189+ Actions : []string {"pull" },
190+ ExpiresAt : jwt .NewNumericDate (now .Add (- time .Hour )),
191+ },
192+ {
193+ Name : "authorized-repository" ,
194+ Type : "repository" ,
195+ Actions : []string {"pull" , "push" },
196+ },
197+ }
198+
199+ claims := api.ClaimsWithAccess {
200+ Access : access ,
201+ RegisteredClaims : jwt.RegisteredClaims {
202+ ExpiresAt : jwt .NewNumericDate (now .Add (time .Hour )),
203+ IssuedAt : jwt .NewNumericDate (now ),
204+ Issuer : "Zot" ,
205+ Audience : []string {"Zot Registry" },
206+ },
207+ }
208+
209+ token , err := jwt .NewWithClaims (signingMethod , claims ).SignedString (privKey )
210+ So (err , ShouldBeNil )
211+
212+ requested := & api.ResourceAction {
213+ Type : "repository" ,
214+ Name : "authorized-repository" ,
215+ Action : "pull" ,
216+ }
217+
218+ err = authorizer .Authorize ("Bearer " + token , requested )
219+ So (err , ShouldBeNil )
220+ })
221+
222+ Convey ("All entries expired results in insufficient scope" , func () {
223+ access := []api.ResourceAccess {
224+ {
225+ Name : "authorized-repository" ,
226+ Type : "repository" ,
227+ Actions : []string {"pull" },
228+ ExpiresAt : jwt .NewNumericDate (now .Add (- time .Hour )),
229+ },
230+ {
231+ Name : "authorized-repository" ,
232+ Type : "repository" ,
233+ Actions : []string {"pull" },
234+ ExpiresAt : jwt .NewNumericDate (now .Add (- 2 * time .Hour )),
235+ },
236+ }
237+
238+ claims := api.ClaimsWithAccess {
239+ Access : access ,
240+ RegisteredClaims : jwt.RegisteredClaims {
241+ ExpiresAt : jwt .NewNumericDate (now .Add (time .Hour )),
242+ IssuedAt : jwt .NewNumericDate (now ),
243+ Issuer : "Zot" ,
244+ Audience : []string {"Zot Registry" },
245+ },
246+ }
247+
248+ token , err := jwt .NewWithClaims (signingMethod , claims ).SignedString (privKey )
249+ So (err , ShouldBeNil )
250+
251+ requested := & api.ResourceAction {
252+ Type : "repository" ,
253+ Name : "authorized-repository" ,
254+ Action : "pull" ,
255+ }
256+
257+ err = authorizer .Authorize ("Bearer " + token , requested )
258+ So (err , ShouldHaveSameTypeAs , & api.AuthChallengeError {})
259+ So (err , ShouldBeError , zerr .ErrInsufficientScope )
260+ })
261+ })
262+
114263 Convey ("Invalid token" , func () {
115264 authHeader := "invalid"
116265
0 commit comments