Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support instance-wide OAuth2 applications #21335

Merged
merged 10 commits into from
Oct 12, 2022
93 changes: 93 additions & 0 deletions routers/web/admin/applications.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright 2022 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 admin

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/setting"
user_setting "code.gitea.io/gitea/routers/web/user/setting"
)

var (
tplSettingsApplications base.TplName = "admin/applications/list"
tplSettingsOauth2ApplicationEdit base.TplName = "admin/applications/oauth2_edit"
)

func newOAuth2CommonHandlers() *user_setting.OAuth2CommonHandlers {
return &user_setting.OAuth2CommonHandlers{
OwnerID: 0,
BasePathList: fmt.Sprintf("%s/admin/applications", setting.AppSubURL),
BasePathEditPrefix: fmt.Sprintf("%s/admin/applications/oauth2", setting.AppSubURL),
TplAppEdit: tplSettingsOauth2ApplicationEdit,
}
}

// Applications render org applications page (for org, at the moment, there are only OAuth2 applications)
func Applications(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("settings.applications")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminApplications"] = true

apps, err := auth.GetOAuth2ApplicationsByUserID(ctx, 0)
if err != nil {
ctx.ServerError("GetOAuth2ApplicationsByUserID", err)
return
}
ctx.Data["Applications"] = apps

ctx.HTML(http.StatusOK, tplSettingsApplications)
}

// ApplicationsPost response for adding an oauth2 application
func ApplicationsPost(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("settings.applications")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminApplications"] = true

oa := newOAuth2CommonHandlers()
oa.AddApp(ctx)
}

// EditApplication displays the given application
func EditApplication(ctx *context.Context) {
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminApplications"] = true

oa := newOAuth2CommonHandlers()
oa.EditShow(ctx)
}

// EditApplicationPost response for editing oauth2 application
func EditApplicationPost(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("settings.applications")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminApplications"] = true

oa := newOAuth2CommonHandlers()
oa.EditSave(ctx)
}

// ApplicationsRegenerateSecret handles the post request for regenerating the secret
func ApplicationsRegenerateSecret(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("settings")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminApplications"] = true

oa := newOAuth2CommonHandlers()
oa.RegenerateSecret(ctx)
}

// DeleteApplication deletes the given oauth2 application
func DeleteApplication(ctx *context.Context) {
oa := newOAuth2CommonHandlers()
oa.DeleteApp(ctx)
}

// TODO: revokes the grant with the given id
17 changes: 12 additions & 5 deletions routers/web/auth/oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,10 +380,13 @@ func AuthorizeOAuth(ctx *context.Context) {
return
}

user, err := user_model.GetUserByID(app.UID)
if err != nil {
ctx.ServerError("GetUserByID", err)
return
var user *user_model.User
if app.UID != 0 {
user, err = user_model.GetUserByID(app.UID)
if err != nil {
ctx.ServerError("GetUserByID", err)
return
}
}

if !app.ContainsRedirectURI(form.RedirectURI) {
Expand Down Expand Up @@ -475,7 +478,11 @@ func AuthorizeOAuth(ctx *context.Context) {
ctx.Data["State"] = form.State
ctx.Data["Scope"] = form.Scope
ctx.Data["Nonce"] = form.Nonce
ctx.Data["ApplicationUserLinkHTML"] = "<a href=\"" + html.EscapeString(user.HTMLURL()) + "\">@" + html.EscapeString(user.Name) + "</a>"
if user != nil {
ctx.Data["ApplicationCreatorLinkHTML"] = fmt.Sprintf(`<a href="%s">@%s</a>`, html.EscapeString(user.HomeLink()), html.EscapeString(user.Name))
} else {
ctx.Data["ApplicationCreatorLinkHTML"] = fmt.Sprintf(`<a href="%s">%s</a>`, html.EscapeString(setting.AppSubURL+"/"), html.EscapeString(setting.AppName))
}
ctx.Data["ApplicationRedirectDomainHTML"] = "<strong>" + html.EscapeString(form.RedirectURI) + "</strong>"
// TODO document SESSION <=> FORM
err = ctx.Session.Set("client_id", app.ClientID)
Expand Down
17 changes: 17 additions & 0 deletions routers/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,23 @@ func RegisterRoutes(m *web.Route) {
m.Post("/delete", admin.DeleteNotices)
m.Post("/empty", admin.EmptyNotices)
})

m.Group("/applications", func() {
m.Get("", admin.Applications)
m.Post("/oauth2", bindIgnErr(forms.EditOAuth2ApplicationForm{}), admin.ApplicationsPost)
m.Group("/oauth2/{id}", func() {
m.Combo("").Get(admin.EditApplication).Post(bindIgnErr(forms.EditOAuth2ApplicationForm{}), admin.EditApplicationPost)
m.Post("/regenerate_secret", admin.ApplicationsRegenerateSecret)
m.Post("/delete", admin.DeleteApplication)
})
}, func(ctx *context.Context) {
if !setting.OAuth2.Enable {
ctx.Error(http.StatusForbidden)
return
}
})
}, func(ctx *context.Context) {
ctx.Data["EnableOAuth2"] = setting.OAuth2.Enable
}, adminReq)
// ***** END: Admin *****

Expand Down
14 changes: 14 additions & 0 deletions templates/admin/applications/list.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{{template "base/head" .}}
<div class="page-content admin config">
{{template "admin/navbar" .}}
<div class="ui container">
<div class="twelve wide column content">
{{template "base/alert" .}}
<h4 class="ui top attached header">
{{.locale.Tr "settings.applications"}}
</h4>
{{template "user/settings/applications_oauth2_list" .}}
</div>
</div>
</div>
{{template "base/footer" .}}
7 changes: 7 additions & 0 deletions templates/admin/applications/oauth2_edit.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{{template "base/head" .}}
<div class="page-content admin config">
{{template "admin/navbar" .}}

{{template "user/settings/applications_oauth2_edit_form" .}}
</div>
{{template "base/footer" .}}
5 changes: 5 additions & 0 deletions templates/admin/navbar.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
<a class="{{if .PageIsAdminEmails}}active{{end}} item" href="{{AppSubUrl}}/admin/emails">
{{.locale.Tr "admin.emails"}}
</a>
{{if .EnableOAuth2}}
<a class="{{if .PageIsAdminApplications}}active{{end}} item" href="{{AppSubUrl}}/admin/applications">
{{.locale.Tr "settings.applications"}}
</a>
{{end}}
<a class="{{if .PageIsAdminConfig}}active{{end}} item" href="{{AppSubUrl}}/admin/config">
{{.locale.Tr "admin.config"}}
</a>
Expand Down
2 changes: 1 addition & 1 deletion templates/user/auth/grant.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
{{template "base/alert" .}}
<p>
<b>{{.locale.Tr "auth.authorize_application_description"}}</b><br/>
{{.locale.Tr "auth.authorize_application_created_by" .ApplicationUserLinkHTML | Str2html}}
{{.locale.Tr "auth.authorize_application_created_by" .ApplicationCreatorLinkHTML | Str2html}}
</p>
</div>
<div class="ui attached segment">
Expand Down