Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions internal/api/oauthserver/authorize.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ type AuthorizationDetailsResponse struct {

// ClientDetailsResponse represents client details in authorization response
type ClientDetailsResponse struct {
ClientID string `json:"client_id"`
ClientName string `json:"client_name,omitempty"`
ClientURI string `json:"client_uri,omitempty"`
LogoURI string `json:"logo_uri,omitempty"`
ID string `json:"id"`
Name string `json:"name,omitempty"`
URI string `json:"uri,omitempty"`
LogoURI string `json:"logo_uri,omitempty"`
}

// UserDetailsResponse represents user details in authorization response
Expand Down Expand Up @@ -237,10 +237,10 @@ func (s *Server) OAuthServerGetAuthorization(w http.ResponseWriter, r *http.Requ
AuthorizationID: authorization.AuthorizationID,
RedirectURI: authorization.RedirectURI,
Client: ClientDetailsResponse{
ClientID: authorization.Client.ID.String(),
ClientName: utilities.StringValue(authorization.Client.ClientName),
ClientURI: utilities.StringValue(authorization.Client.ClientURI),
LogoURI: utilities.StringValue(authorization.Client.LogoURI),
ID: authorization.Client.ID.String(),
Name: utilities.StringValue(authorization.Client.ClientName),
URI: utilities.StringValue(authorization.Client.ClientURI),
LogoURI: utilities.StringValue(authorization.Client.LogoURI),
},
User: UserDetailsResponse{
ID: user.ID.String(),
Expand Down
34 changes: 12 additions & 22 deletions internal/api/oauthserver/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,17 +541,9 @@ func (s *Server) getTokenService() *tokens.Service {

// UserOAuthGrantResponse represents an OAuth grant that a user has authorized
type UserOAuthGrantResponse struct {
ClientID string `json:"client_id"`
ClientName string `json:"client_name,omitempty"`
ClientURI string `json:"client_uri,omitempty"`
LogoURI string `json:"logo_uri,omitempty"`
Scopes []string `json:"scopes"`
GrantedAt time.Time `json:"granted_at"`
}

// UserOAuthGrantsListResponse represents the response for listing user's OAuth grants
type UserOAuthGrantsListResponse struct {
Grants []UserOAuthGrantResponse `json:"grants"`
Client ClientDetailsResponse `json:"client"`
Scopes []string `json:"scopes"`
GrantedAt time.Time `json:"granted_at"`
}

// UserListOAuthGrants handles GET /user/oauth/grants
Expand Down Expand Up @@ -587,22 +579,20 @@ func (s *Server) UserListOAuthGrants(w http.ResponseWriter, r *http.Request) err
}

response := UserOAuthGrantResponse{
ClientID: client.ID.String(),
ClientName: utilities.StringValue(client.ClientName),
ClientURI: utilities.StringValue(client.ClientURI),
LogoURI: utilities.StringValue(client.LogoURI),
Scopes: consent.GetScopeList(),
GrantedAt: consent.GrantedAt,
Client: ClientDetailsResponse{
ID: client.ID.String(),
Name: utilities.StringValue(client.ClientName),
URI: utilities.StringValue(client.ClientURI),
LogoURI: utilities.StringValue(client.LogoURI),
},
Scopes: consent.GetScopeList(),
GrantedAt: consent.GrantedAt,
}

grants = append(grants, response)
}

response := UserOAuthGrantsListResponse{
Grants: grants,
}

return shared.SendJSON(w, http.StatusOK, response)
return shared.SendJSON(w, http.StatusOK, grants)
}

// UserRevokeOAuthGrant handles DELETE /user/oauth/grants?client_id=...
Expand Down
22 changes: 11 additions & 11 deletions internal/api/oauthserver/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -511,25 +511,25 @@ func (ts *OAuthClientTestSuite) TestUserListOAuthGrants() {
// Check response
assert.Equal(ts.T(), http.StatusOK, w.Code)

var response UserOAuthGrantsListResponse
err = json.Unmarshal(w.Body.Bytes(), &response)
var grants []UserOAuthGrantResponse
err = json.Unmarshal(w.Body.Bytes(), &grants)
require.NoError(ts.T(), err)

// Should have 2 grants
assert.Len(ts.T(), response.Grants, 2)
assert.Len(ts.T(), grants, 2)

// Verify client details are included
for _, grant := range response.Grants {
assert.NotEmpty(ts.T(), grant.ClientID)
assert.Equal(ts.T(), "Test Client", grant.ClientName)
for _, grant := range grants {
assert.NotEmpty(ts.T(), grant.Client.ID)
assert.Equal(ts.T(), "Test Client", grant.Client.Name)
assert.NotEmpty(ts.T(), grant.Scopes)
assert.NotEmpty(ts.T(), grant.GrantedAt)
}

// Check that client1 (with read and write scopes) is in the response
found := false
for _, grant := range response.Grants {
if grant.ClientID == client1.ID.String() {
for _, grant := range grants {
if grant.Client.ID == client1.ID.String() {
found = true
assert.Contains(ts.T(), grant.Scopes, "read")
assert.Contains(ts.T(), grant.Scopes, "write")
Expand All @@ -553,12 +553,12 @@ func (ts *OAuthClientTestSuite) TestUserListOAuthGrantsEmpty() {

assert.Equal(ts.T(), http.StatusOK, w.Code)

var response UserOAuthGrantsListResponse
err = json.Unmarshal(w.Body.Bytes(), &response)
var grants []UserOAuthGrantResponse
err = json.Unmarshal(w.Body.Bytes(), &grants)
require.NoError(ts.T(), err)

// Should have 0 grants
assert.Len(ts.T(), response.Grants, 0)
assert.Len(ts.T(), grants, 0)
}

func (ts *OAuthClientTestSuite) TestUserListOAuthGrantsNoAuth() {
Expand Down
41 changes: 21 additions & 20 deletions openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -837,37 +837,38 @@ paths:
content:
application/json:
schema:
type: object
properties:
grants:
type: array
items:
type: array
items:
type: object
properties:
client:
type: object
description: OAuth client details
properties:
client_id:
id:
type: string
format: uuid
description: Unique client identifier
client_name:
name:
type: string
description: Human-readable name of the client application
client_uri:
uri:
type: string
format: uri
description: URL of the client application's homepage
logo_uri:
type: string
format: uri
description: URL of the client application's logo
scopes:
type: array
items:
type: string
description: List of scopes granted to this client
granted_at:
type: string
format: date-time
description: Timestamp when grant was authorized
scopes:
type: array
items:
type: string
description: List of scopes granted to this client
granted_at:
type: string
format: date-time
description: Timestamp when grant was authorized
401:
$ref: "#/components/responses/UnauthorizedResponse"
403:
Expand Down Expand Up @@ -2479,12 +2480,12 @@ paths:
client:
type: object
properties:
client_id:
id:
type: string
format: uuid
client_name:
name:
type: string
client_uri:
uri:
type: string
format: uri
logo_uri:
Expand Down