Add Get/Update for api/v1/user/applications/oauth2 (#11008)

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>
This commit is contained in:
Dan Molik 2020-04-09 20:37:31 -04:00 committed by GitHub
parent 4ec7a659ce
commit 743022116d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 214 additions and 4 deletions

View file

@ -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})
}

View file

@ -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() {

View file

@ -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))
}

View file

@ -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": {