From 2534b8549a6b79766355e1844d0daad1e84df600 Mon Sep 17 00:00:00 2001 From: kyosu-1 Date: Fri, 17 May 2024 00:45:28 +0900 Subject: [PATCH 1/5] add confidential field in oauth client --- docs/v3-api.yaml | 15 +++++++++++++++ router/v3/clients.go | 5 ++++- router/v3/responses.go | 4 ++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/docs/v3-api.yaml b/docs/v3-api.yaml index 58811e346..6cfc0f1c5 100644 --- a/docs/v3-api.yaml +++ b/docs/v3-api.yaml @@ -5848,12 +5848,16 @@ components: description: 要求スコープの配列 items: $ref: '#/components/schemas/OAuth2Scope' + confidential: + type: boolean + description: confidential client なら true, public client なら false required: - id - name - description - developerId - scopes + - confidential PatchClientRequest: title: PatchClientRequest type: object @@ -5876,6 +5880,9 @@ components: type: string description: クライアント開発者UUID format: uuid + confidential: + type: boolean + description: confidential client なら true, public client なら false OAuth2ClientDetail: title: OAuth2ClientDetail description: OAuth2クライアント詳細情報 @@ -5909,6 +5916,9 @@ components: secret: type: string description: クライアントシークレット + confidential: + type: boolean + description: confidential client なら true, public client なら false required: - id - developerId @@ -5917,6 +5927,7 @@ components: - scopes - callbackUrl - secret + - confidential PostClientRequest: title: PostClientRequest type: object @@ -5940,6 +5951,10 @@ components: type: string description: 説明 maxLength: 1000 + confidential: + type: boolean + description: confidential client なら true, public cleint なら false + default: false required: - name - callbackUrl diff --git a/router/v3/clients.go b/router/v3/clients.go index f78ab72b5..8d77fe5c8 100644 --- a/router/v3/clients.go +++ b/router/v3/clients.go @@ -38,6 +38,7 @@ type PostClientsRequest struct { Description string `json:"description"` CallbackURL string `json:"callbackUrl"` Scopes model.AccessScopes `json:"scopes"` + Confidential bool `json:"confidential"` // default false (public client) } func (r PostClientsRequest) Validate() error { @@ -62,7 +63,7 @@ func (h *Handlers) CreateClient(c echo.Context) error { ID: random.SecureAlphaNumeric(36), Name: req.Name, Description: req.Description, - Confidential: false, + Confidential: req.Confidential, CreatorID: userID, RedirectURI: req.CallbackURL, Secret: random.SecureAlphaNumeric(36), @@ -96,6 +97,7 @@ type PatchClientRequest struct { Description optional.Of[string] `json:"description"` CallbackURL optional.Of[string] `json:"callbackUrl"` DeveloperID optional.Of[uuid.UUID] `json:"developerId"` + Confidential optional.Of[bool] `json:"confidential"` } func (r PatchClientRequest) Validate() error { @@ -121,6 +123,7 @@ func (h *Handlers) EditClient(c echo.Context) error { Description: req.Description, DeveloperID: req.DeveloperID, CallbackURL: req.CallbackURL, + Confidential: req.Confidential, } if err := h.Repo.UpdateClient(oc.ID, args); err != nil { return herror.InternalServerError(err) diff --git a/router/v3/responses.go b/router/v3/responses.go index 7e09f1375..080588464 100644 --- a/router/v3/responses.go +++ b/router/v3/responses.go @@ -502,6 +502,7 @@ type OAuth2Client struct { Description string `json:"description"` DeveloperID uuid.UUID `json:"developerId"` Scopes model.AccessScopes `json:"scopes"` + Confidential bool `json:"confidential"` } func formatOAuth2Client(oc *model.OAuth2Client) *OAuth2Client { @@ -511,6 +512,7 @@ func formatOAuth2Client(oc *model.OAuth2Client) *OAuth2Client { Description: oc.Description, DeveloperID: oc.CreatorID, Scopes: oc.Scopes, + Confidential: oc.Confidential, } } @@ -530,6 +532,7 @@ type OAuth2ClientDetail struct { Scopes model.AccessScopes `json:"scopes"` CallbackURL string `json:"callbackUrl"` Secret string `json:"secret"` + Confidential bool `json:"confidential"` } func formatOAuth2ClientDetail(oc *model.OAuth2Client) *OAuth2ClientDetail { @@ -541,6 +544,7 @@ func formatOAuth2ClientDetail(oc *model.OAuth2Client) *OAuth2ClientDetail { Scopes: oc.Scopes, CallbackURL: oc.RedirectURI, Secret: oc.Secret, + Confidential: oc.Confidential, } } From bc47d80aaafb2f3d128601748aece03adc8cad9a Mon Sep 17 00:00:00 2001 From: kyosu-1 Date: Fri, 17 May 2024 00:46:37 +0900 Subject: [PATCH 2/5] fmt --- router/v3/clients.go | 28 +++++++++++------------ router/v3/responses.go | 50 +++++++++++++++++++++--------------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/router/v3/clients.go b/router/v3/clients.go index 8d77fe5c8..4248346c5 100644 --- a/router/v3/clients.go +++ b/router/v3/clients.go @@ -34,11 +34,11 @@ func (h *Handlers) GetClients(c echo.Context) error { // PostClientsRequest POST /clients リクエストボディ type PostClientsRequest struct { - Name string `json:"name"` - Description string `json:"description"` - CallbackURL string `json:"callbackUrl"` - Scopes model.AccessScopes `json:"scopes"` - Confidential bool `json:"confidential"` // default false (public client) + Name string `json:"name"` + Description string `json:"description"` + CallbackURL string `json:"callbackUrl"` + Scopes model.AccessScopes `json:"scopes"` + Confidential bool `json:"confidential"` // default false (public client) } func (r PostClientsRequest) Validate() error { @@ -93,11 +93,11 @@ func (h *Handlers) GetClient(c echo.Context) error { // PatchClientRequest PATCH /clients/:clientID リクエストボディ type PatchClientRequest struct { - Name optional.Of[string] `json:"name"` - Description optional.Of[string] `json:"description"` - CallbackURL optional.Of[string] `json:"callbackUrl"` - DeveloperID optional.Of[uuid.UUID] `json:"developerId"` - Confidential optional.Of[bool] `json:"confidential"` + Name optional.Of[string] `json:"name"` + Description optional.Of[string] `json:"description"` + CallbackURL optional.Of[string] `json:"callbackUrl"` + DeveloperID optional.Of[uuid.UUID] `json:"developerId"` + Confidential optional.Of[bool] `json:"confidential"` } func (r PatchClientRequest) Validate() error { @@ -119,10 +119,10 @@ func (h *Handlers) EditClient(c echo.Context) error { } args := repository.UpdateClientArgs{ - Name: req.Name, - Description: req.Description, - DeveloperID: req.DeveloperID, - CallbackURL: req.CallbackURL, + Name: req.Name, + Description: req.Description, + DeveloperID: req.DeveloperID, + CallbackURL: req.CallbackURL, Confidential: req.Confidential, } if err := h.Repo.UpdateClient(oc.ID, args); err != nil { diff --git a/router/v3/responses.go b/router/v3/responses.go index 080588464..5ffb474fb 100644 --- a/router/v3/responses.go +++ b/router/v3/responses.go @@ -497,21 +497,21 @@ func formatFileInfos(metas []model.File) []*FileInfo { } type OAuth2Client struct { - ID string `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - DeveloperID uuid.UUID `json:"developerId"` - Scopes model.AccessScopes `json:"scopes"` - Confidential bool `json:"confidential"` + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + DeveloperID uuid.UUID `json:"developerId"` + Scopes model.AccessScopes `json:"scopes"` + Confidential bool `json:"confidential"` } func formatOAuth2Client(oc *model.OAuth2Client) *OAuth2Client { return &OAuth2Client{ - ID: oc.ID, - Name: oc.Name, - Description: oc.Description, - DeveloperID: oc.CreatorID, - Scopes: oc.Scopes, + ID: oc.ID, + Name: oc.Name, + Description: oc.Description, + DeveloperID: oc.CreatorID, + Scopes: oc.Scopes, Confidential: oc.Confidential, } } @@ -525,25 +525,25 @@ func formatOAuth2Clients(ocs []*model.OAuth2Client) []*OAuth2Client { } type OAuth2ClientDetail struct { - ID string `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - DeveloperID uuid.UUID `json:"developerId"` - Scopes model.AccessScopes `json:"scopes"` - CallbackURL string `json:"callbackUrl"` - Secret string `json:"secret"` + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + DeveloperID uuid.UUID `json:"developerId"` + Scopes model.AccessScopes `json:"scopes"` + CallbackURL string `json:"callbackUrl"` + Secret string `json:"secret"` Confidential bool `json:"confidential"` } func formatOAuth2ClientDetail(oc *model.OAuth2Client) *OAuth2ClientDetail { return &OAuth2ClientDetail{ - ID: oc.ID, - Name: oc.Name, - Description: oc.Description, - DeveloperID: oc.CreatorID, - Scopes: oc.Scopes, - CallbackURL: oc.RedirectURI, - Secret: oc.Secret, + ID: oc.ID, + Name: oc.Name, + Description: oc.Description, + DeveloperID: oc.CreatorID, + Scopes: oc.Scopes, + CallbackURL: oc.RedirectURI, + Secret: oc.Secret, Confidential: oc.Confidential, } } From 9c6b560e0d372aee56d1f2b7318a270856ed0417 Mon Sep 17 00:00:00 2001 From: kyosu-1 Date: Fri, 17 May 2024 01:22:49 +0900 Subject: [PATCH 3/5] add confidential client test --- router/v3/clients_test.go | 134 +++++++++++++++++++++++++++++++------ router/v3/router_test.go | 24 ++++++- router/v3/sessions_test.go | 4 +- 3 files changed, 136 insertions(+), 26 deletions(-) diff --git a/router/v3/clients_test.go b/router/v3/clients_test.go index af1afccb0..65dc3d7af 100644 --- a/router/v3/clients_test.go +++ b/router/v3/clients_test.go @@ -28,6 +28,7 @@ func oAuth2ClientEquals(t *testing.T, expect *model.OAuth2Client, actual *httpex scopes = append(scopes, scope) } actual.Value("scopes").Array().ContainsOnly(scopes...) + actual.Value("confidential").Boolean().IsEqual(expect.Confidential) } func TestHandlers_GetClients(t *testing.T) { @@ -37,8 +38,8 @@ func TestHandlers_GetClients(t *testing.T) { env := Setup(t, s1) user := env.CreateUser(t, rand) user2 := env.CreateUser(t, rand) - c1 := env.CreateOAuth2Client(t, rand, user.GetID()) - c2 := env.CreateOAuth2Client(t, rand, user2.GetID()) + c1 := env.CreateOAuth2PublicClient(t, rand, user.GetID()) + c2 := env.CreateOAuth2ConfidentialClient(t, rand, user2.GetID()) commonSession := env.S(t, user.GetID()) t.Run("not logged in", func(t *testing.T) { @@ -95,10 +96,11 @@ func TestPostClientsRequest_Validate(t *testing.T) { t.Parallel() type fields struct { - Name string - Description string - CallbackURL string - Scopes model.AccessScopes + Name string + Description string + CallbackURL string + Scopes model.AccessScopes + Confidential bool } tests := []struct { name string @@ -163,6 +165,17 @@ func TestPostClientsRequest_Validate(t *testing.T) { }, false, }, + { + "success (confidential client)", + fields{ + Name: "test", + Description: "desc", + CallbackURL: "https://example.com", + Scopes: map[model.AccessScope]struct{}{"read": {}}, + Confidential: true, + }, + false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -194,6 +207,15 @@ func TestHandlers_CreateClient(t *testing.T) { Scopes: map[model.AccessScope]struct{}{"read": {}}, } + // confidential client + req2 := &PostClientsRequest{ + Name: "test", + Description: "desc", + CallbackURL: "https://example.com", + Scopes: map[model.AccessScope]struct{}{"read": {}}, + Confidential: true, + } + t.Run("not logged in", func(t *testing.T) { t.Parallel() e := env.R(t) @@ -233,6 +255,34 @@ func TestHandlers_CreateClient(t *testing.T) { scopes.Value(0).String().IsEqual("read") obj.Value("callbackUrl").String().IsEqual("https://example.com") obj.Value("secret").String().NotEmpty() + obj.Value("confidential").Boolean().IsFalse() + + c, err := env.Repository.GetClient(obj.Value("id").String().Raw()) + assert.NoError(t, err) + oAuth2ClientEquals(t, c, obj) + }) + + t.Run("success (confidential client)", func(t *testing.T) { + t.Parallel() + e := env.R(t) + obj := e.POST(path). + WithCookie(session.CookieName, commonSession). + WithJSON(req2). + Expect(). + Status(http.StatusCreated). + JSON(). + Object() + + obj.Value("id").String().NotEmpty() + obj.Value("developerId").String().IsEqual(user.GetID().String()) + obj.Value("description").String().IsEqual("desc") + obj.Value("name").String().IsEqual("test") + scopes := obj.Value("scopes").Array() + scopes.Length().IsEqual(1) + scopes.Value(0).String().IsEqual("read") + obj.Value("callbackUrl").String().IsEqual("https://example.com") + obj.Value("secret").String().NotEmpty() + obj.Value("confidential").Boolean().IsTrue() c, err := env.Repository.GetClient(obj.Value("id").String().Raw()) assert.NoError(t, err) @@ -248,8 +298,9 @@ func TestHandlers_GetClient(t *testing.T) { user1 := env.CreateUser(t, rand) user2 := env.CreateUser(t, rand) admin := env.CreateAdmin(t, rand) - c1 := env.CreateOAuth2Client(t, rand, user1.GetID()) - c2 := env.CreateOAuth2Client(t, rand, user2.GetID()) + c1 := env.CreateOAuth2PublicClient(t, rand, user1.GetID()) + c2 := env.CreateOAuth2PublicClient(t, rand, user2.GetID()) + c3 := env.CreateOAuth2ConfidentialClient(t, rand, user1.GetID()) user1Session := env.S(t, user1.GetID()) adminSession := env.S(t, admin.GetID()) @@ -337,16 +388,34 @@ func TestHandlers_GetClient(t *testing.T) { obj.Value("callbackUrl").String().NotEmpty() obj.Value("secret").String().NotEmpty() }) + + t.Run("success (c3, detail=true)", func(t *testing.T) { + t.Parallel() + e := env.R(t) + obj := e.GET(path, c3.ID). + WithCookie(session.CookieName, user1Session). + WithQuery("detail", true). + Expect(). + Status(http.StatusOK). + JSON(). + Object() + + oAuth2ClientEquals(t, c3, obj) + obj.Value("callbackUrl").String().NotEmpty() + obj.Value("secret").String().NotEmpty() + obj.Value("confidential").Boolean().IsTrue() + }) } func TestPatchClientRequest_Validate(t *testing.T) { t.Parallel() type fields struct { - Name optional.Of[string] - Description optional.Of[string] - CallbackURL optional.Of[string] - DeveloperID optional.Of[uuid.UUID] + Name optional.Of[string] + Description optional.Of[string] + CallbackURL optional.Of[string] + DeveloperID optional.Of[uuid.UUID] + Confidential optional.Of[bool] } tests := []struct { name string @@ -393,14 +462,20 @@ func TestPatchClientRequest_Validate(t *testing.T) { fields{Name: optional.From("po")}, false, }, + { + "success (confidential client)", + fields{Confidential: optional.From(true)}, + false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { r := PatchClientRequest{ - Name: tt.fields.Name, - Description: tt.fields.Description, - CallbackURL: tt.fields.CallbackURL, - DeveloperID: tt.fields.DeveloperID, + Name: tt.fields.Name, + Description: tt.fields.Description, + CallbackURL: tt.fields.CallbackURL, + DeveloperID: tt.fields.DeveloperID, + Confidential: tt.fields.Confidential, } if err := r.Validate(); (err != nil) != tt.wantErr { t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr) @@ -417,8 +492,9 @@ func TestHandlers_EditClient(t *testing.T) { user1 := env.CreateUser(t, rand) user2 := env.CreateUser(t, rand) admin := env.CreateAdmin(t, rand) - c1 := env.CreateOAuth2Client(t, rand, user1.GetID()) - c2 := env.CreateOAuth2Client(t, rand, user2.GetID()) + c1 := env.CreateOAuth2PublicClient(t, rand, user1.GetID()) + c2 := env.CreateOAuth2PublicClient(t, rand, user2.GetID()) + c3 := env.CreateOAuth2ConfidentialClient(t, rand, user1.GetID()) user1Session := env.S(t, user1.GetID()) adminSession := env.S(t, admin.GetID()) @@ -488,6 +564,20 @@ func TestHandlers_EditClient(t *testing.T) { require.NoError(t, err) assert.EqualValues(t, c.Name, "po2") }) + + t.Run("success (user1, c3, confidential)", func(t *testing.T) { + t.Parallel() + e := env.R(t) + e.PATCH(path, c3.ID). + WithCookie(session.CookieName, user1Session). + WithJSON(&PatchClientRequest{Confidential: optional.From(true)}). + Expect(). + Status(http.StatusNoContent) + + c, err := env.Repository.GetClient(c3.ID) + require.NoError(t, err) + assert.True(t, c.Confidential) + }) } func TestHandlers_DeleteClient(t *testing.T) { @@ -498,10 +588,10 @@ func TestHandlers_DeleteClient(t *testing.T) { user1 := env.CreateUser(t, rand) user2 := env.CreateUser(t, rand) admin := env.CreateAdmin(t, rand) - c1 := env.CreateOAuth2Client(t, rand, user1.GetID()) - c2 := env.CreateOAuth2Client(t, rand, user2.GetID()) - c3 := env.CreateOAuth2Client(t, rand, user1.GetID()) - c4 := env.CreateOAuth2Client(t, rand, user2.GetID()) + c1 := env.CreateOAuth2PublicClient(t, rand, user1.GetID()) + c2 := env.CreateOAuth2PublicClient(t, rand, user2.GetID()) + c3 := env.CreateOAuth2PublicClient(t, rand, user1.GetID()) + c4 := env.CreateOAuth2PublicClient(t, rand, user2.GetID()) user1Session := env.S(t, user1.GetID()) adminSession := env.S(t, admin.GetID()) diff --git a/router/v3/router_test.go b/router/v3/router_test.go index 220e8b84a..018c3f5f9 100644 --- a/router/v3/router_test.go +++ b/router/v3/router_test.go @@ -407,8 +407,8 @@ func (env *Env) CreateWebhook(t *testing.T, name string, creatorID, channelID uu return w } -// CreateOAuth2Client OAuth2クライアントを必ず作成します -func (env *Env) CreateOAuth2Client(t *testing.T, name string, creatorID uuid.UUID) *model.OAuth2Client { +// CreateOAuth2PublicClient OAuth2 Publicクライアントを必ず作成します +func (env *Env) CreateOAuth2PublicClient(t *testing.T, name string, creatorID uuid.UUID) *model.OAuth2Client { t.Helper() if name == rand { name = random.AlphaNumeric(20) @@ -427,6 +427,26 @@ func (env *Env) CreateOAuth2Client(t *testing.T, name string, creatorID uuid.UUI return client } +// CreateOAuth2ConfidentialClient OAuth2 Confidentialクライアントを必ず作成します +func (env *Env) CreateOAuth2ConfidentialClient(t *testing.T, name string, creatorID uuid.UUID) *model.OAuth2Client { + t.Helper() + if name == rand { + name = random.AlphaNumeric(20) + } + client := &model.OAuth2Client{ + ID: random.SecureAlphaNumeric(36), + Name: name, + Description: "desc", + Confidential: true, + CreatorID: creatorID, + RedirectURI: "https://example.com", + Secret: random.SecureAlphaNumeric(36), + Scopes: model.AccessScopes{"read": {}}, + } + require.NoError(t, env.Repository.SaveClient(client)) + return client +} + // IssueToken OAuth2トークンを必ず発行します func (env *Env) IssueToken(t *testing.T, client *model.OAuth2Client, userID uuid.UUID) *model.OAuth2Token { t.Helper() diff --git a/router/v3/sessions_test.go b/router/v3/sessions_test.go index fef820d26..116b0a162 100644 --- a/router/v3/sessions_test.go +++ b/router/v3/sessions_test.go @@ -333,7 +333,7 @@ func TestHandlers_GetMyTokens(t *testing.T) { path := "/api/v3/users/me/tokens" env := Setup(t, common1) user := env.CreateUser(t, rand) - client := env.CreateOAuth2Client(t, rand, user.GetID()) + client := env.CreateOAuth2PublicClient(t, rand, user.GetID()) tok := env.IssueToken(t, client, user.GetID()) require.ElementsMatch(t, tok.Scopes.StringArray(), []interface{}{"read"}) s := env.S(t, user.GetID()) @@ -374,7 +374,7 @@ func TestHandlers_RevokeMyToken(t *testing.T) { env := Setup(t, common1) user := env.CreateUser(t, rand) user2 := env.CreateUser(t, rand) - client := env.CreateOAuth2Client(t, rand, user.GetID()) + client := env.CreateOAuth2PublicClient(t, rand, user.GetID()) tok := env.IssueToken(t, client, user.GetID()) tok2 := env.IssueToken(t, client, user2.GetID()) s := env.S(t, user.GetID()) From 2d0610b63ea3ff98e0859794465f0e0c0df5c130 Mon Sep 17 00:00:00 2001 From: kyosu-1 Date: Wed, 19 Jun 2024 21:43:06 +0900 Subject: [PATCH 4/5] =?UTF-8?q?CreateOAuth2Client=E3=81=A7functional=20opt?= =?UTF-8?q?ion=20pattern=E3=82=92=E4=BD=BF=E3=81=86=E5=BD=A2=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- router/v3/clients_test.go | 24 ++++++++++++------------ router/v3/router_test.go | 35 ++++++++++++++--------------------- router/v3/sessions_test.go | 4 ++-- 3 files changed, 28 insertions(+), 35 deletions(-) diff --git a/router/v3/clients_test.go b/router/v3/clients_test.go index 65dc3d7af..c6ff15038 100644 --- a/router/v3/clients_test.go +++ b/router/v3/clients_test.go @@ -38,8 +38,8 @@ func TestHandlers_GetClients(t *testing.T) { env := Setup(t, s1) user := env.CreateUser(t, rand) user2 := env.CreateUser(t, rand) - c1 := env.CreateOAuth2PublicClient(t, rand, user.GetID()) - c2 := env.CreateOAuth2ConfidentialClient(t, rand, user2.GetID()) + c1 := env.CreateOAuth2Client(t, rand, user.GetID()) + c2 := env.CreateOAuth2Client(t, rand, user2.GetID(), WithConfidential(true)) commonSession := env.S(t, user.GetID()) t.Run("not logged in", func(t *testing.T) { @@ -298,9 +298,9 @@ func TestHandlers_GetClient(t *testing.T) { user1 := env.CreateUser(t, rand) user2 := env.CreateUser(t, rand) admin := env.CreateAdmin(t, rand) - c1 := env.CreateOAuth2PublicClient(t, rand, user1.GetID()) - c2 := env.CreateOAuth2PublicClient(t, rand, user2.GetID()) - c3 := env.CreateOAuth2ConfidentialClient(t, rand, user1.GetID()) + c1 := env.CreateOAuth2Client(t, rand, user1.GetID()) + c2 := env.CreateOAuth2Client(t, rand, user2.GetID()) + c3 := env.CreateOAuth2Client(t, rand, user1.GetID(), WithConfidential(true)) user1Session := env.S(t, user1.GetID()) adminSession := env.S(t, admin.GetID()) @@ -492,9 +492,9 @@ func TestHandlers_EditClient(t *testing.T) { user1 := env.CreateUser(t, rand) user2 := env.CreateUser(t, rand) admin := env.CreateAdmin(t, rand) - c1 := env.CreateOAuth2PublicClient(t, rand, user1.GetID()) - c2 := env.CreateOAuth2PublicClient(t, rand, user2.GetID()) - c3 := env.CreateOAuth2ConfidentialClient(t, rand, user1.GetID()) + c1 := env.CreateOAuth2Client(t, rand, user1.GetID()) + c2 := env.CreateOAuth2Client(t, rand, user2.GetID()) + c3 := env.CreateOAuth2Client(t, rand, user1.GetID(), WithConfidential(true)) user1Session := env.S(t, user1.GetID()) adminSession := env.S(t, admin.GetID()) @@ -588,10 +588,10 @@ func TestHandlers_DeleteClient(t *testing.T) { user1 := env.CreateUser(t, rand) user2 := env.CreateUser(t, rand) admin := env.CreateAdmin(t, rand) - c1 := env.CreateOAuth2PublicClient(t, rand, user1.GetID()) - c2 := env.CreateOAuth2PublicClient(t, rand, user2.GetID()) - c3 := env.CreateOAuth2PublicClient(t, rand, user1.GetID()) - c4 := env.CreateOAuth2PublicClient(t, rand, user2.GetID()) + c1 := env.CreateOAuth2Client(t, rand, user1.GetID()) + c2 := env.CreateOAuth2Client(t, rand, user2.GetID()) + c3 := env.CreateOAuth2Client(t, rand, user1.GetID()) + c4 := env.CreateOAuth2Client(t, rand, user2.GetID()) user1Session := env.S(t, user1.GetID()) adminSession := env.S(t, admin.GetID()) diff --git a/router/v3/router_test.go b/router/v3/router_test.go index 018c3f5f9..9b0a95039 100644 --- a/router/v3/router_test.go +++ b/router/v3/router_test.go @@ -407,42 +407,35 @@ func (env *Env) CreateWebhook(t *testing.T, name string, creatorID, channelID uu return w } -// CreateOAuth2PublicClient OAuth2 Publicクライアントを必ず作成します -func (env *Env) CreateOAuth2PublicClient(t *testing.T, name string, creatorID uuid.UUID) *model.OAuth2Client { - t.Helper() - if name == rand { - name = random.AlphaNumeric(20) - } - client := &model.OAuth2Client{ - ID: random.SecureAlphaNumeric(36), - Name: name, - Description: "desc", - Confidential: false, - CreatorID: creatorID, - RedirectURI: "https://example.com", - Secret: random.SecureAlphaNumeric(36), - Scopes: model.AccessScopes{"read": {}}, +// OAuth2ClientOption represents a functional option for OAuth2Client +type OAuth2ClientOption func(*model.OAuth2Client) + +// WithConfidential sets the confidentiality of the OAuth2Client +func WithConfidential(confidential bool) OAuth2ClientOption { + return func(c *model.OAuth2Client) { + c.Confidential = confidential } - require.NoError(t, env.Repository.SaveClient(client)) - return client } -// CreateOAuth2ConfidentialClient OAuth2 Confidentialクライアントを必ず作成します -func (env *Env) CreateOAuth2ConfidentialClient(t *testing.T, name string, creatorID uuid.UUID) *model.OAuth2Client { +// CreateOAuth2Client OAuth2クライアントを必ず作成します +func (env *Env) CreateOAuth2Client(t *testing.T, name string, creatorID uuid.UUID, opts ...OAuth2ClientOption) *model.OAuth2Client { t.Helper() - if name == rand { + if name == "rand" { name = random.AlphaNumeric(20) } client := &model.OAuth2Client{ ID: random.SecureAlphaNumeric(36), Name: name, Description: "desc", - Confidential: true, + Confidential: false, CreatorID: creatorID, RedirectURI: "https://example.com", Secret: random.SecureAlphaNumeric(36), Scopes: model.AccessScopes{"read": {}}, } + for _, opt := range opts { + opt(client) + } require.NoError(t, env.Repository.SaveClient(client)) return client } diff --git a/router/v3/sessions_test.go b/router/v3/sessions_test.go index 116b0a162..fef820d26 100644 --- a/router/v3/sessions_test.go +++ b/router/v3/sessions_test.go @@ -333,7 +333,7 @@ func TestHandlers_GetMyTokens(t *testing.T) { path := "/api/v3/users/me/tokens" env := Setup(t, common1) user := env.CreateUser(t, rand) - client := env.CreateOAuth2PublicClient(t, rand, user.GetID()) + client := env.CreateOAuth2Client(t, rand, user.GetID()) tok := env.IssueToken(t, client, user.GetID()) require.ElementsMatch(t, tok.Scopes.StringArray(), []interface{}{"read"}) s := env.S(t, user.GetID()) @@ -374,7 +374,7 @@ func TestHandlers_RevokeMyToken(t *testing.T) { env := Setup(t, common1) user := env.CreateUser(t, rand) user2 := env.CreateUser(t, rand) - client := env.CreateOAuth2PublicClient(t, rand, user.GetID()) + client := env.CreateOAuth2Client(t, rand, user.GetID()) tok := env.IssueToken(t, client, user.GetID()) tok2 := env.IssueToken(t, client, user2.GetID()) s := env.S(t, user.GetID()) From 2e40b6b7e80d245fdacb2a0143a68037dcb045d0 Mon Sep 17 00:00:00 2001 From: kyosu-1 Date: Wed, 19 Jun 2024 21:44:55 +0900 Subject: [PATCH 5/5] fix: rand --- router/v3/router_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/router/v3/router_test.go b/router/v3/router_test.go index 9b0a95039..2a3b3d5d3 100644 --- a/router/v3/router_test.go +++ b/router/v3/router_test.go @@ -420,7 +420,7 @@ func WithConfidential(confidential bool) OAuth2ClientOption { // CreateOAuth2Client OAuth2クライアントを必ず作成します func (env *Env) CreateOAuth2Client(t *testing.T, name string, creatorID uuid.UUID, opts ...OAuth2ClientOption) *model.OAuth2Client { t.Helper() - if name == "rand" { + if name == rand { name = random.AlphaNumeric(20) } client := &model.OAuth2Client{