diff options
author | qwerty287 <80460567+qwerty287@users.noreply.github.com> | 2022-10-09 14:07:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-09 20:07:41 +0800 |
commit | a813c9d8f3862fec934ff657fb4e490530167183 (patch) | |
tree | 877ca996565a94fa0f22d53e9e737dfd47ba8077 /routers/web/user | |
parent | 97f3f1988b2b544350f58aa8b49cb958bb4da5b5 (diff) | |
download | gitea-a813c9d8f3862fec934ff657fb4e490530167183.tar.gz gitea-a813c9d8f3862fec934ff657fb4e490530167183.zip |
Allow creation of OAuth2 applications for orgs (#18084)
Adds the settings pages to create OAuth2 apps also to the org settings
and allows to create apps for orgs.
Refactoring: the oauth2 related templates are shared for
instance-wide/org/user, and the backend code uses `OAuth2CommonHandlers`
to share code for instance-wide/org/user.
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Diffstat (limited to 'routers/web/user')
-rw-r--r-- | routers/web/user/setting/oauth2.go | 134 | ||||
-rw-r--r-- | routers/web/user/setting/oauth2_common.go | 150 |
2 files changed, 172 insertions, 112 deletions
diff --git a/routers/web/user/setting/oauth2.go b/routers/web/user/setting/oauth2.go index db76a12f18..0cc05dd040 100644 --- a/routers/web/user/setting/oauth2.go +++ b/routers/web/user/setting/oauth2.go @@ -5,79 +5,40 @@ package setting import ( - "fmt" - "net/http" - - "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/web" - "code.gitea.io/gitea/services/forms" ) const ( - tplSettingsOAuthApplications base.TplName = "user/settings/applications_oauth2_edit" + tplSettingsOAuthApplicationEdit base.TplName = "user/settings/applications_oauth2_edit" ) +func newOAuth2CommonHandlers(userID int64) *OAuth2CommonHandlers { + return &OAuth2CommonHandlers{ + OwnerID: userID, + BasePathList: setting.AppSubURL + "/user/settings/applications", + BasePathEditPrefix: setting.AppSubURL + "/user/settings/applications/oauth2", + TplAppEdit: tplSettingsOAuthApplicationEdit, + } +} + // OAuthApplicationsPost response for adding a oauth2 application func OAuthApplicationsPost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.EditOAuth2ApplicationForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsApplications"] = true - if ctx.HasError() { - loadApplicationsData(ctx) - - ctx.HTML(http.StatusOK, tplSettingsApplications) - return - } - // TODO validate redirect URI - app, err := auth.CreateOAuth2Application(ctx, auth.CreateOAuth2ApplicationOptions{ - Name: form.Name, - RedirectURIs: []string{form.RedirectURI}, - UserID: ctx.Doer.ID, - }) - if err != nil { - ctx.ServerError("CreateOAuth2Application", err) - return - } - ctx.Flash.Success(ctx.Tr("settings.create_oauth2_application_success")) - ctx.Data["App"] = app - ctx.Data["ClientSecret"], err = app.GenerateClientSecret() - if err != nil { - ctx.ServerError("GenerateClientSecret", err) - return - } - ctx.HTML(http.StatusOK, tplSettingsOAuthApplications) + oa := newOAuth2CommonHandlers(ctx.Doer.ID) + oa.AddApp(ctx) } // OAuthApplicationsEdit response for editing oauth2 application func OAuthApplicationsEdit(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.EditOAuth2ApplicationForm) ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsApplications"] = true - if ctx.HasError() { - loadApplicationsData(ctx) - - ctx.HTML(http.StatusOK, tplSettingsApplications) - return - } - // TODO validate redirect URI - var err error - if ctx.Data["App"], err = auth.UpdateOAuth2Application(auth.UpdateOAuth2ApplicationOptions{ - ID: ctx.ParamsInt64("id"), - Name: form.Name, - RedirectURIs: []string{form.RedirectURI}, - UserID: ctx.Doer.ID, - }); err != nil { - ctx.ServerError("UpdateOAuth2Application", err) - return - } - ctx.Flash.Success(ctx.Tr("settings.update_oauth2_application_success")) - ctx.HTML(http.StatusOK, tplSettingsOAuthApplications) + oa := newOAuth2CommonHandlers(ctx.Doer.ID) + oa.EditSave(ctx) } // OAuthApplicationsRegenerateSecret handles the post request for regenerating the secret @@ -85,75 +46,24 @@ func OAuthApplicationsRegenerateSecret(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsApplications"] = true - app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.ParamsInt64("id")) - if err != nil { - if auth.IsErrOAuthApplicationNotFound(err) { - ctx.NotFound("Application not found", err) - return - } - ctx.ServerError("GetOAuth2ApplicationByID", err) - return - } - if app.UID != ctx.Doer.ID { - ctx.NotFound("Application not found", nil) - return - } - ctx.Data["App"] = app - ctx.Data["ClientSecret"], err = app.GenerateClientSecret() - if err != nil { - ctx.ServerError("GenerateClientSecret", err) - return - } - ctx.Flash.Success(ctx.Tr("settings.update_oauth2_application_success")) - ctx.HTML(http.StatusOK, tplSettingsOAuthApplications) + oa := newOAuth2CommonHandlers(ctx.Doer.ID) + oa.RegenerateSecret(ctx) } // OAuth2ApplicationShow displays the given application func OAuth2ApplicationShow(ctx *context.Context) { - app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.ParamsInt64("id")) - if err != nil { - if auth.IsErrOAuthApplicationNotFound(err) { - ctx.NotFound("Application not found", err) - return - } - ctx.ServerError("GetOAuth2ApplicationByID", err) - return - } - if app.UID != ctx.Doer.ID { - ctx.NotFound("Application not found", nil) - return - } - ctx.Data["App"] = app - ctx.HTML(http.StatusOK, tplSettingsOAuthApplications) + oa := newOAuth2CommonHandlers(ctx.Doer.ID) + oa.EditShow(ctx) } // DeleteOAuth2Application deletes the given oauth2 application func DeleteOAuth2Application(ctx *context.Context) { - if err := auth.DeleteOAuth2Application(ctx.FormInt64("id"), ctx.Doer.ID); err != nil { - ctx.ServerError("DeleteOAuth2Application", err) - return - } - log.Trace("OAuth2 Application deleted: %s", ctx.Doer.Name) - - ctx.Flash.Success(ctx.Tr("settings.remove_oauth2_application_success")) - ctx.JSON(http.StatusOK, map[string]interface{}{ - "redirect": setting.AppSubURL + "/user/settings/applications", - }) + oa := newOAuth2CommonHandlers(ctx.Doer.ID) + oa.DeleteApp(ctx) } // RevokeOAuth2Grant revokes the grant with the given id func RevokeOAuth2Grant(ctx *context.Context) { - if ctx.Doer.ID == 0 || ctx.FormInt64("id") == 0 { - ctx.ServerError("RevokeOAuth2Grant", fmt.Errorf("user id or grant id is zero")) - return - } - if err := auth.RevokeOAuth2Grant(ctx, ctx.FormInt64("id"), ctx.Doer.ID); err != nil { - ctx.ServerError("RevokeOAuth2Grant", err) - return - } - - ctx.Flash.Success(ctx.Tr("settings.revoke_oauth2_grant_success")) - ctx.JSON(http.StatusOK, map[string]interface{}{ - "redirect": setting.AppSubURL + "/user/settings/applications", - }) + oa := newOAuth2CommonHandlers(ctx.Doer.ID) + oa.RevokeGrant(ctx) } diff --git a/routers/web/user/setting/oauth2_common.go b/routers/web/user/setting/oauth2_common.go new file mode 100644 index 0000000000..f02f6ab041 --- /dev/null +++ b/routers/web/user/setting/oauth2_common.go @@ -0,0 +1,150 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package setting + +import ( + "fmt" + "net/http" + + "code.gitea.io/gitea/models/auth" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/forms" +) + +type OAuth2CommonHandlers struct { + OwnerID int64 // 0 for instance-wide, otherwise OrgID or UserID + BasePathList string // the base URL for the application list page, eg: "/user/setting/applications" + BasePathEditPrefix string // the base URL for the application edit page, will be appended with app id, eg: "/user/setting/applications/oauth2" + TplAppEdit base.TplName // the template for the application edit page +} + +func (oa *OAuth2CommonHandlers) renderEditPage(ctx *context.Context) { + app := ctx.Data["App"].(*auth.OAuth2Application) + ctx.Data["FormActionPath"] = fmt.Sprintf("%s/%d", oa.BasePathEditPrefix, app.ID) + ctx.HTML(http.StatusOK, oa.TplAppEdit) +} + +// AddApp adds an oauth2 application +func (oa *OAuth2CommonHandlers) AddApp(ctx *context.Context) { + form := web.GetForm(ctx).(*forms.EditOAuth2ApplicationForm) + if ctx.HasError() { + // go to the application list page + ctx.Redirect(oa.BasePathList) + return + } + + // TODO validate redirect URI + app, err := auth.CreateOAuth2Application(ctx, auth.CreateOAuth2ApplicationOptions{ + Name: form.Name, + RedirectURIs: []string{form.RedirectURI}, + UserID: oa.OwnerID, + }) + if err != nil { + ctx.ServerError("CreateOAuth2Application", err) + return + } + + // render the edit page with secret + ctx.Flash.Success(ctx.Tr("settings.create_oauth2_application_success"), true) + ctx.Data["App"] = app + ctx.Data["ClientSecret"], err = app.GenerateClientSecret() + if err != nil { + ctx.ServerError("GenerateClientSecret", err) + return + } + oa.renderEditPage(ctx) +} + +// EditShow displays the given application +func (oa *OAuth2CommonHandlers) EditShow(ctx *context.Context) { + app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.ParamsInt64("id")) + if err != nil { + if auth.IsErrOAuthApplicationNotFound(err) { + ctx.NotFound("Application not found", err) + return + } + ctx.ServerError("GetOAuth2ApplicationByID", err) + return + } + if app.UID != oa.OwnerID { + ctx.NotFound("Application not found", nil) + return + } + ctx.Data["App"] = app + oa.renderEditPage(ctx) +} + +// EditSave saves the oauth2 application +func (oa *OAuth2CommonHandlers) EditSave(ctx *context.Context) { + form := web.GetForm(ctx).(*forms.EditOAuth2ApplicationForm) + + if ctx.HasError() { + oa.renderEditPage(ctx) + return + } + + // TODO validate redirect URI + var err error + if ctx.Data["App"], err = auth.UpdateOAuth2Application(auth.UpdateOAuth2ApplicationOptions{ + ID: ctx.ParamsInt64("id"), + Name: form.Name, + RedirectURIs: []string{form.RedirectURI}, + UserID: oa.OwnerID, + }); err != nil { + ctx.ServerError("UpdateOAuth2Application", err) + return + } + ctx.Flash.Success(ctx.Tr("settings.update_oauth2_application_success")) + ctx.Redirect(oa.BasePathList) +} + +// RegenerateSecret regenerates the secret +func (oa *OAuth2CommonHandlers) RegenerateSecret(ctx *context.Context) { + app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.ParamsInt64("id")) + if err != nil { + if auth.IsErrOAuthApplicationNotFound(err) { + ctx.NotFound("Application not found", err) + return + } + ctx.ServerError("GetOAuth2ApplicationByID", err) + return + } + if app.UID != oa.OwnerID { + ctx.NotFound("Application not found", nil) + return + } + ctx.Data["App"] = app + ctx.Data["ClientSecret"], err = app.GenerateClientSecret() + if err != nil { + ctx.ServerError("GenerateClientSecret", err) + return + } + ctx.Flash.Success(ctx.Tr("settings.update_oauth2_application_success"), true) + oa.renderEditPage(ctx) +} + +// DeleteApp deletes the given oauth2 application +func (oa *OAuth2CommonHandlers) DeleteApp(ctx *context.Context) { + if err := auth.DeleteOAuth2Application(ctx.ParamsInt64("id"), oa.OwnerID); err != nil { + ctx.ServerError("DeleteOAuth2Application", err) + return + } + + ctx.Flash.Success(ctx.Tr("settings.remove_oauth2_application_success")) + ctx.JSON(http.StatusOK, map[string]interface{}{"redirect": oa.BasePathList}) +} + +// RevokeGrant revokes the grant +func (oa *OAuth2CommonHandlers) RevokeGrant(ctx *context.Context) { + if err := auth.RevokeOAuth2Grant(ctx, ctx.ParamsInt64("grantId"), oa.OwnerID); err != nil { + ctx.ServerError("RevokeOAuth2Grant", err) + return + } + + ctx.Flash.Success(ctx.Tr("settings.revoke_oauth2_grant_success")) + ctx.JSON(http.StatusOK, map[string]interface{}{"redirect": oa.BasePathList}) +} |