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