Add api methods for getting and updating user oauth2 applications. Signed-off-by: Dan Molik <dan@danmolik.com> Co-authored-by: techknowlogick <techknowlogick@gitea.io>tags/v1.13.0-dev
@@ -19,6 +19,8 @@ func TestOAuth2Application(t *testing.T) { | |||
defer prepareTestEnv(t)() | |||
testAPICreateOAuth2Application(t) | |||
testAPIListOAuth2Applications(t) | |||
testAPIGetOAuth2Application(t) | |||
testAPIUpdateOAuth2Application(t) | |||
testAPIDeleteOAuth2Application(t) | |||
} | |||
@@ -83,9 +85,6 @@ func testAPIDeleteOAuth2Application(t *testing.T) { | |||
oldApp := models.AssertExistsAndLoadBean(t, &models.OAuth2Application{ | |||
UID: user.ID, | |||
Name: "test-app-1", | |||
RedirectURIs: []string{ | |||
"http://www.google.com", | |||
}, | |||
}).(*models.OAuth2Application) | |||
urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2/%d?token=%s", oldApp.ID, token) | |||
@@ -94,3 +93,67 @@ func testAPIDeleteOAuth2Application(t *testing.T) { | |||
models.AssertNotExistsBean(t, &models.OAuth2Application{UID: oldApp.UID, Name: oldApp.Name}) | |||
} | |||
func testAPIGetOAuth2Application(t *testing.T) { | |||
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) | |||
session := loginUser(t, user.Name) | |||
token := getTokenForLoggedInUser(t, session) | |||
existApp := models.AssertExistsAndLoadBean(t, &models.OAuth2Application{ | |||
UID: user.ID, | |||
Name: "test-app-1", | |||
RedirectURIs: []string{ | |||
"http://www.google.com", | |||
}, | |||
}).(*models.OAuth2Application) | |||
urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2/%d?token=%s", existApp.ID, token) | |||
req := NewRequest(t, "GET", urlStr) | |||
resp := session.MakeRequest(t, req, http.StatusOK) | |||
var app api.OAuth2Application | |||
DecodeJSON(t, resp, &app) | |||
expectedApp := app | |||
assert.EqualValues(t, existApp.Name, expectedApp.Name) | |||
assert.EqualValues(t, existApp.ClientID, expectedApp.ClientID) | |||
assert.Len(t, expectedApp.ClientID, 36) | |||
assert.Empty(t, expectedApp.ClientSecret) | |||
assert.EqualValues(t, len(expectedApp.RedirectURIs), 1) | |||
assert.EqualValues(t, existApp.RedirectURIs[0], expectedApp.RedirectURIs[0]) | |||
models.AssertExistsAndLoadBean(t, &models.OAuth2Application{ID: expectedApp.ID, Name: expectedApp.Name}) | |||
} | |||
func testAPIUpdateOAuth2Application(t *testing.T) { | |||
user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) | |||
existApp := models.AssertExistsAndLoadBean(t, &models.OAuth2Application{ | |||
UID: user.ID, | |||
Name: "test-app-1", | |||
RedirectURIs: []string{ | |||
"http://www.google.com", | |||
}, | |||
}).(*models.OAuth2Application) | |||
appBody := api.CreateOAuth2ApplicationOptions{ | |||
Name: "test-app-1", | |||
RedirectURIs: []string{ | |||
"http://www.google.com/", | |||
"http://www.github.com/", | |||
}, | |||
} | |||
urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2/%d", existApp.ID) | |||
req := NewRequestWithJSON(t, "PATCH", urlStr, &appBody) | |||
req = AddBasicAuthHeader(req, user.Name) | |||
resp := MakeRequest(t, req, http.StatusOK) | |||
var app api.OAuth2Application | |||
DecodeJSON(t, resp, &app) | |||
expectedApp := app | |||
assert.EqualValues(t, len(expectedApp.RedirectURIs), 2) | |||
assert.EqualValues(t, expectedApp.RedirectURIs[0], appBody.RedirectURIs[0]) | |||
assert.EqualValues(t, expectedApp.RedirectURIs[1], appBody.RedirectURIs[1]) | |||
models.AssertExistsAndLoadBean(t, &models.OAuth2Application{ID: expectedApp.ID, Name: expectedApp.Name}) | |||
} |
@@ -580,7 +580,10 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Combo("/oauth2"). | |||
Get(user.ListOauth2Applications). | |||
Post(bind(api.CreateOAuth2ApplicationOptions{}), user.CreateOauth2Application) | |||
m.Delete("/oauth2/:id", user.DeleteOauth2Application) | |||
m.Combo("/oauth2/:id"). | |||
Delete(user.DeleteOauth2Application). | |||
Patch(bind(api.CreateOAuth2ApplicationOptions{}), user.UpdateOauth2Application). | |||
Get(user.GetOauth2Application) | |||
}, reqToken()) | |||
m.Group("/gpg_keys", func() { |
@@ -231,3 +231,89 @@ func DeleteOauth2Application(ctx *context.APIContext) { | |||
ctx.Status(http.StatusNoContent) | |||
} | |||
// GetOauth2Application get OAuth2 Application | |||
func GetOauth2Application(ctx *context.APIContext) { | |||
// swagger:operation GET /user/applications/oauth2/{id} user userGetOAuth2Application | |||
// --- | |||
// summary: get an OAuth2 Application | |||
// produces: | |||
// - application/json | |||
// parameters: | |||
// - name: id | |||
// in: path | |||
// description: Application ID to be found | |||
// type: integer | |||
// format: int64 | |||
// required: true | |||
// responses: | |||
// "200": | |||
// "$ref": "#/responses/OAuth2Application" | |||
appID := ctx.ParamsInt64(":id") | |||
app, err := models.GetOAuth2ApplicationByID(appID) | |||
if err != nil { | |||
if models.IsErrOauthClientIDInvalid(err) || models.IsErrOAuthApplicationNotFound(err) { | |||
ctx.NotFound() | |||
} else { | |||
ctx.Error(http.StatusInternalServerError, "GetOauth2ApplicationByID", err) | |||
} | |||
return | |||
} | |||
app.ClientSecret = "" | |||
ctx.JSON(http.StatusOK, convert.ToOAuth2Application(app)) | |||
} | |||
// UpdateOauth2Application update OAuth2 Application | |||
func UpdateOauth2Application(ctx *context.APIContext, data api.CreateOAuth2ApplicationOptions) { | |||
// swagger:operation PATCH /user/applications/oauth2/{id} user userUpdateOAuth2Application | |||
// --- | |||
// summary: update an OAuth2 Application, this includes regenerating the client secret | |||
// produces: | |||
// - application/json | |||
// parameters: | |||
// - name: id | |||
// in: path | |||
// description: application to be updated | |||
// type: integer | |||
// format: int64 | |||
// required: true | |||
// - name: body | |||
// in: body | |||
// required: true | |||
// schema: | |||
// "$ref": "#/definitions/CreateOAuth2ApplicationOptions" | |||
// responses: | |||
// "200": | |||
// "$ref": "#/responses/OAuth2Application" | |||
appID := ctx.ParamsInt64(":id") | |||
err := models.UpdateOAuth2Application(models.UpdateOAuth2ApplicationOptions{ | |||
Name: data.Name, | |||
UserID: ctx.User.ID, | |||
ID: appID, | |||
RedirectURIs: data.RedirectURIs, | |||
}) | |||
if err != nil { | |||
ctx.Error(http.StatusBadRequest, "", "error updating oauth2 application") | |||
return | |||
} | |||
app, err := models.GetOAuth2ApplicationByID(appID) | |||
if err != nil { | |||
if models.IsErrOauthClientIDInvalid(err) || models.IsErrOAuthApplicationNotFound(err) { | |||
ctx.NotFound() | |||
} else { | |||
ctx.Error(http.StatusInternalServerError, "UpdateOauth2ApplicationByID", err) | |||
} | |||
return | |||
} | |||
secret, err := app.GenerateClientSecret() | |||
if err != nil { | |||
ctx.Error(http.StatusBadRequest, "", "error updating application secret") | |||
return | |||
} | |||
app.ClientSecret = secret | |||
ctx.JSON(http.StatusOK, convert.ToOAuth2Application(app)) | |||
} |
@@ -8360,6 +8360,31 @@ | |||
} | |||
}, | |||
"/user/applications/oauth2/{id}": { | |||
"get": { | |||
"produces": [ | |||
"application/json" | |||
], | |||
"tags": [ | |||
"user" | |||
], | |||
"summary": "get an OAuth2 Application", | |||
"operationId": "userGetOAuth2Application", | |||
"parameters": [ | |||
{ | |||
"type": "integer", | |||
"format": "int64", | |||
"description": "Application ID to be found", | |||
"name": "id", | |||
"in": "path", | |||
"required": true | |||
} | |||
], | |||
"responses": { | |||
"200": { | |||
"$ref": "#/responses/OAuth2Application" | |||
} | |||
} | |||
}, | |||
"delete": { | |||
"produces": [ | |||
"application/json" | |||
@@ -8384,6 +8409,39 @@ | |||
"$ref": "#/responses/empty" | |||
} | |||
} | |||
}, | |||
"patch": { | |||
"produces": [ | |||
"application/json" | |||
], | |||
"tags": [ | |||
"user" | |||
], | |||
"summary": "update an OAuth2 Application, this includes regenerating the client secret", | |||
"operationId": "userUpdateOAuth2Application", | |||
"parameters": [ | |||
{ | |||
"type": "integer", | |||
"format": "int64", | |||
"description": "application to be updated", | |||
"name": "id", | |||
"in": "path", | |||
"required": true | |||
}, | |||
{ | |||
"name": "body", | |||
"in": "body", | |||
"required": true, | |||
"schema": { | |||
"$ref": "#/definitions/CreateOAuth2ApplicationOptions" | |||
} | |||
} | |||
], | |||
"responses": { | |||
"200": { | |||
"$ref": "#/responses/OAuth2Application" | |||
} | |||
} | |||
} | |||
}, | |||
"/user/emails": { |