Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit92e0cbf

Browse files
committed
add expires on idp
1 parent72b4dae commit92e0cbf

File tree

1 file changed

+51
-19
lines changed
  • coderd/coderdtest/oidctest

1 file changed

+51
-19
lines changed

‎coderd/coderdtest/oidctest/idp.go‎

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ import (
3939
"github.com/coder/coder/v2/codersdk"
4040
)
4141

42+
typetokenstruct {
43+
issued time.Time
44+
emailstring
45+
exp time.Time
46+
}
47+
4248
// FakeIDP is a functional OIDC provider.
4349
// It only supports 1 OIDC client.
4450
typeFakeIDPstruct {
@@ -65,7 +71,7 @@ type FakeIDP struct {
6571
// That is the various access tokens, refresh tokens, states, etc.
6672
codeToStateMap*syncmap.Map[string,string]
6773
// Token -> Email
68-
accessTokens*syncmap.Map[string,string]
74+
accessTokens*syncmap.Map[string,token]
6975
// Refresh Token -> Email
7076
refreshTokensUsed*syncmap.Map[string,bool]
7177
refreshTokens*syncmap.Map[string,string]
@@ -173,6 +179,12 @@ func WithLogging(t testing.TB, options *slogtest.Options) func(*FakeIDP) {
173179
}
174180
}
175181

182+
funcWithLogger(logger slog.Logger)func(*FakeIDP) {
183+
returnfunc(f*FakeIDP) {
184+
f.logger=logger
185+
}
186+
}
187+
176188
// WithStaticUserInfo is optional, but will return the same user info for
177189
// every user on the /userinfo endpoint.
178190
funcWithStaticUserInfo(info jwt.MapClaims)func(*FakeIDP) {
@@ -229,7 +241,7 @@ func NewFakeIDP(t testing.TB, opts ...FakeIDPOpt) *FakeIDP {
229241
clientSecret:uuid.NewString(),
230242
logger:slog.Make(),
231243
codeToStateMap:syncmap.New[string,string](),
232-
accessTokens:syncmap.New[string,string](),
244+
accessTokens:syncmap.New[string,token](),
233245
refreshTokens:syncmap.New[string,string](),
234246
refreshTokensUsed:syncmap.New[string,bool](),
235247
stateToIDTokenClaims:syncmap.New[string, jwt.MapClaims](),
@@ -284,7 +296,7 @@ func (f *FakeIDP) updateIssuerURL(t testing.TB, issuer string) {
284296
Algorithms: []string{
285297
"RS256",
286298
},
287-
ExternalAuthURL:u.ResolveReference(&url.URL{Path:fmt.Sprintf("/external-auth-validate/%s",f.externalProviderID)}).String(),
299+
ExternalAuthURL:u.ResolveReference(&url.URL{Path:"/external-auth-validate/user"}).String(),
288300
}
289301
}
290302

@@ -417,7 +429,7 @@ func (f *FakeIDP) LoginWithClient(t testing.TB, client *codersdk.Client, idToken
417429
// ExternalLogin does the oauth2 flow for external auth providers. This requires
418430
// an authenticated coder client.
419431
func (f*FakeIDP)ExternalLogin(t testing.TB,client*codersdk.Client,opts...func(r*http.Request)) {
420-
coderOauthURL,err:=client.URL.Parse(fmt.Sprintf("/external-auth/%s/callback",f.externalProviderID))
432+
coderOauthURL,err:=client.URL.Parse("/external-auth/callback")
421433
require.NoError(t,err)
422434
f.SetRedirect(t,coderOauthURL.String())
423435

@@ -544,9 +556,13 @@ func (f *FakeIDP) newCode(state string) string {
544556

545557
// newToken enforces the access token exchanged is actually a valid access token
546558
// created by the IDP.
547-
func (f*FakeIDP)newToken(emailstring)string {
559+
func (f*FakeIDP)newToken(emailstring,expires time.Time)string {
548560
accessToken:=uuid.NewString()
549-
f.accessTokens.Store(accessToken,email)
561+
f.accessTokens.Store(accessToken,token{
562+
issued:time.Now(),
563+
email:email,
564+
exp:expires,
565+
})
550566
returnaccessToken
551567
}
552568

@@ -562,10 +578,15 @@ func (f *FakeIDP) authenticateBearerTokenRequest(t testing.TB, req *http.Request
562578

563579
auth:=req.Header.Get("Authorization")
564580
token:=strings.TrimPrefix(auth,"Bearer ")
565-
_,ok:=f.accessTokens.Load(token)
581+
authToken,ok:=f.accessTokens.Load(token)
566582
if!ok {
567583
return"",xerrors.New("invalid access token")
568584
}
585+
586+
if!authToken.exp.IsZero()&&authToken.exp.Before(time.Now()) {
587+
return"",xerrors.New("access token expired")
588+
}
589+
569590
returntoken,nil
570591
}
571592

@@ -690,7 +711,8 @@ func (f *FakeIDP) httpHandler(t testing.TB) http.Handler {
690711
mux.Handle(tokenPath,http.HandlerFunc(func(rw http.ResponseWriter,r*http.Request) {
691712
values,err:=f.authenticateOIDCClientRequest(t,r)
692713
f.logger.Info(r.Context(),"http idp call token",
693-
slog.Error(err),
714+
slog.F("valid",err==nil),
715+
slog.F("grant_type",values.Get("grant_type")),
694716
slog.F("values",values.Encode()),
695717
)
696718
iferr!=nil {
@@ -773,7 +795,7 @@ func (f *FakeIDP) httpHandler(t testing.TB) http.Handler {
773795
email:=getEmail(claims)
774796
refreshToken:=f.newRefreshTokens(email)
775797
token:=map[string]interface{}{
776-
"access_token":f.newToken(email),
798+
"access_token":f.newToken(email,exp),
777799
"refresh_token":refreshToken,
778800
"token_type":"Bearer",
779801
"expires_in":int64((f.defaultExpire).Seconds()),
@@ -791,25 +813,31 @@ func (f *FakeIDP) httpHandler(t testing.TB) http.Handler {
791813

792814
validateMW:=func(rw http.ResponseWriter,r*http.Request) (emailstring,okbool) {
793815
token,err:=f.authenticateBearerTokenRequest(t,r)
794-
f.logger.Info(r.Context(),"http call idp user info",
795-
slog.Error(err),
796-
slog.F("url",r.URL.String()),
797-
)
798816
iferr!=nil {
799-
http.Error(rw,fmt.Sprintf("invalid user info request: %s",err.Error()),http.StatusBadRequest)
817+
http.Error(rw,fmt.Sprintf("invalid user info request: %s",err.Error()),http.StatusUnauthorized)
800818
return"",false
801819
}
802820

803-
email,ok=f.accessTokens.Load(token)
821+
authToken,ok:=f.accessTokens.Load(token)
804822
if!ok {
805823
t.Errorf("access token user for user_info has no email to indicate which user")
806-
http.Error(rw,"invalid access token, missing user info",http.StatusBadRequest)
824+
http.Error(rw,"invalid access token, missing user info",http.StatusUnauthorized)
825+
return"",false
826+
}
827+
828+
if!authToken.exp.IsZero()&&authToken.exp.Before(time.Now()) {
829+
http.Error(rw,"auth token expired",http.StatusUnauthorized)
807830
return"",false
808831
}
809-
returnemail,true
832+
833+
returnauthToken.email,true
810834
}
811835
mux.Handle(userInfoPath,http.HandlerFunc(func(rw http.ResponseWriter,r*http.Request) {
812836
email,ok:=validateMW(rw,r)
837+
f.logger.Info(r.Context(),"http userinfo",
838+
slog.F("valid",ok),
839+
slog.F("email",email),
840+
)
813841
if!ok {
814842
return
815843
}
@@ -827,6 +855,10 @@ func (f *FakeIDP) httpHandler(t testing.TB) http.Handler {
827855
// should be strict, and this one needs to handle sub routes.
828856
mux.Mount("/external-auth-validate/",http.HandlerFunc(func(rw http.ResponseWriter,r*http.Request) {
829857
email,ok:=validateMW(rw,r)
858+
f.logger.Info(r.Context(),"http external auth validate",
859+
slog.F("valid",ok),
860+
slog.F("email",email),
861+
)
830862
if!ok {
831863
return
832864
}
@@ -978,7 +1010,7 @@ func (f *FakeIDP) ExternalAuthConfig(t testing.TB, id string, custom *ExternalAu
9781010
}
9791011
f.externalProviderID=id
9801012
f.externalAuthValidate=func(emailstring,rw http.ResponseWriter,r*http.Request) {
981-
newPath:=strings.TrimPrefix(r.URL.Path,fmt.Sprintf("/external-auth-validate/%s",id))
1013+
newPath:=strings.TrimPrefix(r.URL.Path,"/external-auth-validate")
9821014
switchnewPath {
9831015
// /user is ALWAYS supported under the `/` path too.
9841016
case"/user","/","":
@@ -1010,7 +1042,7 @@ func (f *FakeIDP) ExternalAuthConfig(t testing.TB, id string, custom *ExternalAu
10101042
DisplayIcon:f.WellknownConfig().UserInfoURL,
10111043
// Omit the /user for the validate so we can easily append to it when modifying
10121044
// the cfg for advanced tests.
1013-
ValidateURL:f.issuerURL.ResolveReference(&url.URL{Path:fmt.Sprintf("/external-auth-validate/%s",id)}).String(),
1045+
ValidateURL:f.issuerURL.ResolveReference(&url.URL{Path:"/external-auth-validate/user"}).String(),
10141046
}
10151047
for_,opt:=rangeopts {
10161048
opt(cfg)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp