OAuth tidy-up and refactorpull/376/head
@@ -304,32 +304,18 @@ func viewLogin(app *App, w http.ResponseWriter, r *http.Request) error { | |||
p := &struct { | |||
page.StaticPage | |||
To string | |||
Message template.HTML | |||
Flashes []template.HTML | |||
LoginUsername string | |||
OauthSlack bool | |||
OauthWriteAs bool | |||
OauthGitlab bool | |||
GitlabDisplayName string | |||
OauthGeneric bool | |||
OauthGenericDisplayName string | |||
OauthGitea bool | |||
GiteaDisplayName string | |||
*OAuthButtons | |||
To string | |||
Message template.HTML | |||
Flashes []template.HTML | |||
LoginUsername string | |||
}{ | |||
pageForReq(app, r), | |||
r.FormValue("to"), | |||
template.HTML(""), | |||
[]template.HTML{}, | |||
getTempInfo(app, "login-user", r, w), | |||
app.Config().SlackOauth.ClientID != "", | |||
app.Config().WriteAsOauth.ClientID != "", | |||
app.Config().GitlabOauth.ClientID != "", | |||
config.OrDefaultString(app.Config().GenericOauth.DisplayName, genericOauthDisplayName), | |||
app.Config().GenericOauth.ClientID != "", | |||
config.OrDefaultString(app.Config().GitlabOauth.DisplayName, gitlabDisplayName), | |||
app.Config().GiteaOauth.ClientID != "", | |||
config.OrDefaultString(app.Config().GiteaOauth.DisplayName, giteaDisplayName), | |||
StaticPage: pageForReq(app, r), | |||
OAuthButtons: NewOAuthButtons(app.Config()), | |||
To: r.FormValue("to"), | |||
Message: template.HTML(""), | |||
Flashes: []template.HTML{}, | |||
LoginUsername: getTempInfo(app, "login-user", r, w), | |||
} | |||
if earlyError != "" { | |||
@@ -494,7 +494,7 @@ func makeActivityPost(hostName string, p *activitystreams.Person, url string, m | |||
r, _ := http.NewRequest("POST", url, bytes.NewBuffer(b)) | |||
r.Header.Add("Content-Type", "application/activity+json") | |||
r.Header.Set("User-Agent", "Go ("+serverSoftware+"/"+softwareVer+"; +"+hostName+")") | |||
r.Header.Set("User-Agent", ServerUserAgent(hostName)) | |||
h := sha256.New() | |||
h.Write(b) | |||
r.Header.Add("Digest", "SHA-256="+base64.StdEncoding.EncodeToString(h.Sum(nil))) | |||
@@ -544,7 +544,7 @@ func resolveIRI(hostName, url string) ([]byte, error) { | |||
r, _ := http.NewRequest("GET", url, nil) | |||
r.Header.Add("Accept", "application/activity+json") | |||
r.Header.Set("User-Agent", "Go ("+serverSoftware+"/"+softwareVer+"; +"+hostName+")") | |||
r.Header.Set("User-Agent", ServerUserAgent(hostName)) | |||
if debugging { | |||
dump, err := httputil.DumpRequestOut(r, true) | |||
@@ -238,27 +238,16 @@ func handleViewLanding(app *App, w http.ResponseWriter, r *http.Request) error { | |||
p := struct { | |||
page.StaticPage | |||
*OAuthButtons | |||
Flashes []template.HTML | |||
Banner template.HTML | |||
Content template.HTML | |||
ForcedLanding bool | |||
OauthSlack bool | |||
OauthWriteAs bool | |||
OauthGitlab bool | |||
OauthGeneric bool | |||
OauthGenericDisplayName string | |||
GitlabDisplayName string | |||
}{ | |||
StaticPage: pageForReq(app, r), | |||
ForcedLanding: forceLanding, | |||
OauthSlack: app.Config().SlackOauth.ClientID != "", | |||
OauthWriteAs: app.Config().WriteAsOauth.ClientID != "", | |||
OauthGitlab: app.Config().GitlabOauth.ClientID != "", | |||
OauthGeneric: app.Config().GenericOauth.ClientID != "", | |||
OauthGenericDisplayName: config.OrDefaultString(app.Config().GenericOauth.DisplayName, genericOauthDisplayName), | |||
GitlabDisplayName: config.OrDefaultString(app.Config().GitlabOauth.DisplayName, gitlabDisplayName), | |||
StaticPage: pageForReq(app, r), | |||
OAuthButtons: NewOAuthButtons(app.Config()), | |||
ForcedLanding: forceLanding, | |||
} | |||
banner, err := getLandingBanner(app) | |||
@@ -903,3 +892,13 @@ func adminInitDatabase(app *App) error { | |||
log.Info("Done.") | |||
return nil | |||
} | |||
// ServerUserAgent returns a User-Agent string to use in external requests. The | |||
// hostName parameter may be left empty. | |||
func ServerUserAgent(hostName string) string { | |||
hostUAStr := "" | |||
if hostName != "" { | |||
hostUAStr = "; +" + hostName | |||
} | |||
return "Go (" + serverSoftware + "/" + softwareVer + hostUAStr + ")" | |||
} |
@@ -81,6 +81,15 @@ type ( | |||
CallbackProxyAPI string `ini:"callback_proxy_api"` | |||
} | |||
GiteaOauthCfg struct { | |||
ClientID string `ini:"client_id"` | |||
ClientSecret string `ini:"client_secret"` | |||
Host string `ini:"host"` | |||
DisplayName string `ini:"display_name"` | |||
CallbackProxy string `ini:"callback_proxy"` | |||
CallbackProxyAPI string `ini:"callback_proxy_api"` | |||
} | |||
SlackOauthCfg struct { | |||
ClientID string `ini:"client_id"` | |||
ClientSecret string `ini:"client_secret"` | |||
@@ -101,14 +110,6 @@ type ( | |||
AuthEndpoint string `ini:"auth_endpoint"` | |||
AllowDisconnect bool `ini:"allow_disconnect"` | |||
} | |||
GiteaOauthCfg struct { | |||
ClientID string `ini:"client_id"` | |||
ClientSecret string `ini:"client_secret"` | |||
Host string `ini:"host"` | |||
DisplayName string `ini:"display_name"` | |||
CallbackProxy string `ini:"callback_proxy"` | |||
CallbackProxyAPI string `ini:"callback_proxy_api"` | |||
} | |||
// AppCfg holds values that affect how the application functions | |||
AppCfg struct { | |||
@@ -165,8 +166,8 @@ type ( | |||
SlackOauth SlackOauthCfg `ini:"oauth.slack"` | |||
WriteAsOauth WriteAsOauthCfg `ini:"oauth.writeas"` | |||
GitlabOauth GitlabOauthCfg `ini:"oauth.gitlab"` | |||
GenericOauth GenericOauthCfg `ini:"oauth.generic"` | |||
GiteaOauth GiteaOauthCfg `ini:"oauth.gitea"` | |||
GenericOauth GenericOauthCfg `ini:"oauth.generic"` | |||
} | |||
) | |||
@@ -2627,11 +2627,11 @@ func (db *datastore) GetIDForRemoteUser(ctx context.Context, remoteUserID, provi | |||
} | |||
type oauthAccountInfo struct { | |||
Provider string | |||
ClientID string | |||
RemoteUserID string | |||
DisplayName string | |||
AllowDisconnect bool | |||
Provider string | |||
ClientID string | |||
RemoteUserID string | |||
DisplayName string | |||
AllowDisconnect bool | |||
} | |||
func (db *datastore) GetOauthAccounts(ctx context.Context, userID int64) ([]oauthAccountInfo, error) { | |||
@@ -170,14 +170,14 @@ func handleViewInvite(app *App, w http.ResponseWriter, r *http.Request) error { | |||
p := struct { | |||
page.StaticPage | |||
*OAuthButtons | |||
Error string | |||
Flashes []template.HTML | |||
Invite string | |||
OAuth *OAuthButtons | |||
}{ | |||
StaticPage: pageForReq(app, r), | |||
Invite: inviteCode, | |||
OAuth: NewOAuthButtons(app.cfg), | |||
StaticPage: pageForReq(app, r), | |||
OAuthButtons: NewOAuthButtons(app.cfg), | |||
Invite: inviteCode, | |||
} | |||
if expired { | |||
@@ -9,18 +9,64 @@ | |||
*/ | |||
.row.signinbtns { | |||
justify-content: space-evenly; | |||
justify-content: center; | |||
font-size: 1em; | |||
margin-top: 2em; | |||
margin-bottom: 1em; | |||
flex-wrap: wrap; | |||
.loginbtn { | |||
height: 40px; | |||
} | |||
margin: 0.5em; | |||
&.btn { | |||
box-sizing: border-box; | |||
font-size: 17px; | |||
white-space: nowrap; | |||
img { | |||
height: 1.5em; | |||
vertical-align: middle; | |||
} | |||
} | |||
&#writeas-login, &#slack-login { | |||
img { | |||
margin-top: -0.2em; | |||
} | |||
} | |||
&#gitlab-login { | |||
background-color: #fc6d26; | |||
border-color: #fc6d26; | |||
&:hover { | |||
background-color: darken(#fc6d26, 5%); | |||
border-color: darken(#fc6d26, 5%); | |||
} | |||
} | |||
&#gitea-login { | |||
background-color: #2ecc71; | |||
border-color: #2ecc71; | |||
&:hover { | |||
background-color: #2cc26b; | |||
border-color: #2cc26b; | |||
} | |||
} | |||
&#slack-login, &#gitlab-login, &#gitea-login, &#generic-oauth-login { | |||
font-size: 0.86em; | |||
font-family: @sansFont; | |||
} | |||
#writeas-login, #gitlab-login { | |||
box-sizing: border-box; | |||
font-size: 17px; | |||
&#slack-login, &#generic-oauth-login { | |||
color: @lightTextColor; | |||
background-color: @lightNavBG; | |||
border-color: @lightNavBorder; | |||
&:hover { | |||
background-color: @lightNavHoverBG; | |||
} | |||
} | |||
} | |||
} | |||
@@ -30,19 +30,27 @@ import ( | |||
// OAuthButtons holds display information for different OAuth providers we support. | |||
type OAuthButtons struct { | |||
SlackEnabled bool | |||
WriteAsEnabled bool | |||
GitLabEnabled bool | |||
GitLabDisplayName string | |||
SlackEnabled bool | |||
WriteAsEnabled bool | |||
GitLabEnabled bool | |||
GitLabDisplayName string | |||
GiteaEnabled bool | |||
GiteaDisplayName string | |||
GenericEnabled bool | |||
GenericDisplayName string | |||
} | |||
// NewOAuthButtons creates a new OAuthButtons struct based on our app configuration. | |||
func NewOAuthButtons(cfg *config.Config) *OAuthButtons { | |||
return &OAuthButtons{ | |||
SlackEnabled: cfg.SlackOauth.ClientID != "", | |||
WriteAsEnabled: cfg.WriteAsOauth.ClientID != "", | |||
GitLabEnabled: cfg.GitlabOauth.ClientID != "", | |||
GitLabDisplayName: config.OrDefaultString(cfg.GitlabOauth.DisplayName, gitlabDisplayName), | |||
SlackEnabled: cfg.SlackOauth.ClientID != "", | |||
WriteAsEnabled: cfg.WriteAsOauth.ClientID != "", | |||
GitLabEnabled: cfg.GitlabOauth.ClientID != "", | |||
GitLabDisplayName: config.OrDefaultString(cfg.GitlabOauth.DisplayName, gitlabDisplayName), | |||
GiteaEnabled: cfg.GiteaOauth.ClientID != "", | |||
GiteaDisplayName: config.OrDefaultString(cfg.GiteaOauth.DisplayName, giteaDisplayName), | |||
GenericEnabled: cfg.GenericOauth.ClientID != "", | |||
GenericDisplayName: config.OrDefaultString(cfg.GenericOauth.DisplayName, genericOauthDisplayName), | |||
} | |||
} | |||
@@ -318,6 +326,12 @@ func (h oauthHandler) viewOauthCallback(app *App, w http.ResponseWriter, r *http | |||
tokenResponse, err := h.oauthClient.exchangeOauthCode(ctx, code) | |||
if err != nil { | |||
log.Error("Unable to exchangeOauthCode: %s", err) | |||
// TODO: show user friendly message if needed | |||
// TODO: show NO message for cases like user pressing "Cancel" on authorize step | |||
addSessionFlash(app, w, r, err.Error(), nil) | |||
if attachUserID > 0 { | |||
return impart.HTTPError{http.StatusFound, "/me/settings"} | |||
} | |||
return impart.HTTPError{http.StatusInternalServerError, err.Error()} | |||
} | |||
@@ -408,7 +422,7 @@ func (r *callbackProxyClient) register(ctx context.Context, state string) error | |||
if err != nil { | |||
return err | |||
} | |||
req.Header.Set("User-Agent", "writefreely") | |||
req.Header.Set("User-Agent", ServerUserAgent("")) | |||
req.Header.Set("Accept", "application/json") | |||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded") | |||
@@ -62,7 +62,7 @@ func (c genericOauthClient) exchangeOauthCode(ctx context.Context, code string) | |||
return nil, err | |||
} | |||
req.WithContext(ctx) | |||
req.Header.Set("User-Agent", "writefreely") | |||
req.Header.Set("User-Agent", ServerUserAgent("")) | |||
req.Header.Set("Accept", "application/json") | |||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded") | |||
req.SetBasicAuth(c.ClientID, c.ClientSecret) | |||
@@ -91,7 +91,7 @@ func (c genericOauthClient) inspectOauthAccessToken(ctx context.Context, accessT | |||
return nil, err | |||
} | |||
req.WithContext(ctx) | |||
req.Header.Set("User-Agent", "writefreely") | |||
req.Header.Set("User-Agent", ServerUserAgent("")) | |||
req.Header.Set("Accept", "application/json") | |||
req.Header.Set("Authorization", "Bearer "+accessToken) | |||
@@ -62,7 +62,7 @@ func (c giteaOauthClient) exchangeOauthCode(ctx context.Context, code string) (* | |||
return nil, err | |||
} | |||
req.WithContext(ctx) | |||
req.Header.Set("User-Agent", "writefreely") | |||
req.Header.Set("User-Agent", ServerUserAgent("")) | |||
req.Header.Set("Accept", "application/json") | |||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded") | |||
req.SetBasicAuth(c.ClientID, c.ClientSecret) | |||
@@ -91,7 +91,7 @@ func (c giteaOauthClient) inspectOauthAccessToken(ctx context.Context, accessTok | |||
return nil, err | |||
} | |||
req.WithContext(ctx) | |||
req.Header.Set("User-Agent", "writefreely") | |||
req.Header.Set("User-Agent", ServerUserAgent("")) | |||
req.Header.Set("Accept", "application/json") | |||
req.Header.Set("Authorization", "Bearer "+accessToken) | |||
@@ -63,7 +63,7 @@ func (c gitlabOauthClient) exchangeOauthCode(ctx context.Context, code string) ( | |||
return nil, err | |||
} | |||
req.WithContext(ctx) | |||
req.Header.Set("User-Agent", "writefreely") | |||
req.Header.Set("User-Agent", ServerUserAgent("")) | |||
req.Header.Set("Accept", "application/json") | |||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded") | |||
req.SetBasicAuth(c.ClientID, c.ClientSecret) | |||
@@ -92,7 +92,7 @@ func (c gitlabOauthClient) inspectOauthAccessToken(ctx context.Context, accessTo | |||
return nil, err | |||
} | |||
req.WithContext(ctx) | |||
req.Header.Set("User-Agent", "writefreely") | |||
req.Header.Set("User-Agent", ServerUserAgent("")) | |||
req.Header.Set("Accept", "application/json") | |||
req.Header.Set("Authorization", "Bearer "+accessToken) | |||
@@ -111,7 +111,7 @@ func (c slackOauthClient) exchangeOauthCode(ctx context.Context, code string) (* | |||
return nil, err | |||
} | |||
req.WithContext(ctx) | |||
req.Header.Set("User-Agent", "writefreely") | |||
req.Header.Set("User-Agent", ServerUserAgent("")) | |||
req.Header.Set("Accept", "application/json") | |||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded") | |||
req.SetBasicAuth(c.ClientID, c.ClientSecret) | |||
@@ -140,7 +140,7 @@ func (c slackOauthClient) inspectOauthAccessToken(ctx context.Context, accessTok | |||
return nil, err | |||
} | |||
req.WithContext(ctx) | |||
req.Header.Set("User-Agent", "writefreely") | |||
req.Header.Set("User-Agent", ServerUserAgent("")) | |||
req.Header.Set("Accept", "application/json") | |||
req.Header.Set("Authorization", "Bearer "+accessToken) | |||
@@ -62,7 +62,7 @@ func (c writeAsOauthClient) exchangeOauthCode(ctx context.Context, code string) | |||
return nil, err | |||
} | |||
req.WithContext(ctx) | |||
req.Header.Set("User-Agent", "writefreely") | |||
req.Header.Set("User-Agent", ServerUserAgent("")) | |||
req.Header.Set("Accept", "application/json") | |||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded") | |||
req.SetBasicAuth(c.ClientID, c.ClientSecret) | |||
@@ -91,7 +91,7 @@ func (c writeAsOauthClient) inspectOauthAccessToken(ctx context.Context, accessT | |||
return nil, err | |||
} | |||
req.WithContext(ctx) | |||
req.Header.Set("User-Agent", "writefreely") | |||
req.Header.Set("User-Agent", ServerUserAgent("")) | |||
req.Header.Set("Accept", "application/json") | |||
req.Header.Set("Authorization", "Bearer "+accessToken) | |||
@@ -60,10 +60,8 @@ form dd { | |||
margin-top: 0; | |||
max-width: 8em; | |||
} | |||
#generic-oauth-login { | |||
box-sizing: border-box; | |||
font-size: 17px; | |||
white-space:nowrap; | |||
.or { | |||
margin-bottom: 2.5em !important; | |||
} | |||
</style> | |||
{{end}} | |||
@@ -78,20 +76,7 @@ form dd { | |||
<div{{if not .OpenRegistration}} style="padding: 2em 0;"{{end}}> | |||
{{ if .OpenRegistration }} | |||
{{ if or .OauthSlack .OauthWriteAs .OauthGitlab .OauthGeneric }} | |||
{{ if .OauthSlack }} | |||
<div class="row content-container signinbtns signinoauthbtns"><a class="loginbtn" href="/oauth/slack"><img alt="Sign in with Slack" height="40" width="172" src="/img/sign_in_with_slack.png" srcset="/img/sign_in_with_slack.png 1x, /img/sign_in_with_slack@2x.png 2x" /></a></div> | |||
{{ end }} | |||
{{ if .OauthWriteAs }} | |||
<div class="row content-container signinbtns signinoauthbtns"><a class="btn cta loginbtn" id="writeas-login" href="/oauth/write.as">Sign in with <strong>Write.as</strong></a></div> | |||
{{ end }} | |||
{{ if .OauthGitlab }} | |||
<div class="row content-container signinbtns signinoauthbtns"><a class="btn cta loginbtn" id="gitlab-login" href="/oauth/gitlab">Sign in with <strong>{{.GitlabDisplayName}}</strong></a></div> | |||
{{ end }} | |||
{{ if .OauthGeneric }} | |||
<div class="row content-container signinbtns signinoauthbtns"><a class="btn cta loginbtn" id="generic-oauth-login" href="/oauth/generic">Sign in with <strong>{{ .OauthGenericDisplayName }}</strong></a></div> | |||
{{ end }} | |||
{{ end }} | |||
{{template "oauth-buttons" .}} | |||
{{if not .DisablePasswordAuth}} | |||
{{if .Flashes}}<ul class="errors"> | |||
{{range .Flashes}}<li class="urgent">{{.}}</li>{{end}} | |||
@@ -3,10 +3,6 @@ | |||
<meta itemprop="description" content="Log in to {{.SiteName}}."> | |||
<style> | |||
input{margin-bottom:0.5em;} | |||
#generic-oauth-login { | |||
box-sizing: border-box; | |||
font-size: 17px; | |||
} | |||
</style> | |||
{{end}} | |||
{{define "content"}} | |||
@@ -17,32 +13,7 @@ input{margin-bottom:0.5em;} | |||
{{range .Flashes}}<li class="urgent">{{.}}</li>{{end}} | |||
</ul>{{end}} | |||
{{ if or .OauthSlack .OauthWriteAs .OauthGitlab .OauthGeneric .OauthGitea }} | |||
<div class="row content-container signinbtns"> | |||
{{ if .OauthSlack }} | |||
<a class="loginbtn" href="/oauth/slack"><img alt="Sign in with Slack" height="40" width="172" src="/img/sign_in_with_slack.png" srcset="/img/sign_in_with_slack.png 1x, /img/sign_in_with_slack@2x.png 2x" /></a> | |||
{{ end }} | |||
{{ if .OauthWriteAs }} | |||
<a class="btn cta loginbtn" id="writeas-login" href="/oauth/write.as">Sign in with <strong>Write.as</strong></a> | |||
{{ end }} | |||
{{ if .OauthGitlab }} | |||
<a class="btn cta loginbtn" id="gitlab-login" href="/oauth/gitlab">Sign in with <strong>{{.GitlabDisplayName}}</strong></a> | |||
{{ end }} | |||
{{ if .OauthGeneric }} | |||
<a class="btn cta loginbtn" id="generic-oauth-login" href="/oauth/generic">Sign in with <strong>{{ .OauthGenericDisplayName }}</strong></a> | |||
{{ end }} | |||
{{ if .OauthGitea }} | |||
<a class="btn cta loginbtn" id="gitea-login" href="/oauth/gitea">Sign in with <strong>{{.GiteaDisplayName}}</strong></a> | |||
{{ end }} | |||
</div> | |||
{{if not .DisablePasswordAuth}} | |||
<div class="or"> | |||
<p>or</p> | |||
<hr class="short" /> | |||
</div> | |||
{{end}} | |||
{{ end }} | |||
{{template "oauth-buttons" .}} | |||
{{if not .DisablePasswordAuth}} | |||
<form action="/auth/login" method="post" style="text-align: center;margin-top:1em;" onsubmit="disableSubmit()"> | |||
@@ -70,25 +70,9 @@ form dd { | |||
</ul>{{end}} | |||
<div id="billing"> | |||
{{ if or .OAuth.SlackEnabled .OAuth.WriteAsEnabled .OAuth.GitLabEnabled }} | |||
<div class="row content-container signinbtns"> | |||
{{ if .OAuth.SlackEnabled }} | |||
<a class="loginbtn" href="/oauth/slack{{if .Invite}}?invite_code={{.Invite}}{{end}}"><img alt="Sign in with Slack" height="40" width="172" src="/img/sign_in_with_slack.png" srcset="/img/sign_in_with_slack.png 1x, /img/sign_in_with_slack@2x.png 2x" /></a> | |||
{{ end }} | |||
{{ if .OAuth.WriteAsEnabled }} | |||
<a class="btn cta loginbtn" id="writeas-login" href="/oauth/write.as{{if .Invite}}?invite_code={{.Invite}}{{end}}">Sign in with <strong>Write.as</strong></a> | |||
{{ end }} | |||
{{ if .OAuth.GitLabEnabled }} | |||
<a class="btn cta loginbtn" id="gitlab-login" href="/oauth/gitlab{{if .Invite}}?invite_code={{.Invite}}{{end}}">Sign in with <strong>{{.OAuth.GitLabDisplayName}}</strong></a> | |||
{{ end }} | |||
</div> | |||
<div class="or"> | |||
<p>or</p> | |||
<hr class="short" /> | |||
</div> | |||
{{ end }} | |||
{{template "oauth-buttons" .}} | |||
{{if not .DisablePasswordAuth}} | |||
<form action="/auth/signup" method="POST" id="signup-form" onsubmit="return signup()"> | |||
<input type="hidden" name="invite_code" value="{{.Invite}}" /> | |||
<dl class="billing"> | |||
@@ -112,6 +96,7 @@ form dd { | |||
</dt> | |||
</dl> | |||
</form> | |||
{{end}} | |||
</div> | |||
{{ end }} | |||
</div> | |||
@@ -85,12 +85,18 @@ func initPage(parentDir, path, key string) { | |||
log.Info(" [%s] %s", key, path) | |||
} | |||
pages[key] = template.Must(template.New("").Funcs(funcMap).ParseFiles( | |||
files := []string{ | |||
path, | |||
filepath.Join(parentDir, templatesDir, "include", "footer.tmpl"), | |||
filepath.Join(parentDir, templatesDir, "base.tmpl"), | |||
filepath.Join(parentDir, templatesDir, "user", "include", "silenced.tmpl"), | |||
)) | |||
} | |||
if key == "login.tmpl" || key == "landing.tmpl" || key == "signup.tmpl" { | |||
files = append(files, filepath.Join(parentDir, templatesDir, "include", "oauth.tmpl")) | |||
} | |||
pages[key] = template.Must(template.New("").Funcs(funcMap).ParseFiles(files...)) | |||
} | |||
func initUserPage(parentDir, path, key string) { | |||
@@ -0,0 +1,37 @@ | |||
{{define "oauth-buttons"}} | |||
{{ if or .SlackEnabled .WriteAsEnabled .GitLabEnabled .GiteaEnabled .GenericEnabled }} | |||
<div class="row content-container signinbtns"> | |||
{{ if .SlackEnabled }} | |||
<a class="loginbtn" href="/oauth/slack"><img alt="Sign in with Slack" height="40" width="172" src="/img/sign_in_with_slack.png" srcset="/img/sign_in_with_slack.png 1x, /img/sign_in_with_slack@2x.png 2x" /></a> | |||
{{ end }} | |||
{{ if .WriteAsEnabled }} | |||
<a class="btn cta loginbtn" id="writeas-login" href="/oauth/write.as"> | |||
<img src="/img/mark/writeas-white.png" /> | |||
Sign in with <strong>Write.as</strong> | |||
</a> | |||
{{ end }} | |||
{{ if .GitLabEnabled }} | |||
<a class="btn cta loginbtn" id="gitlab-login" href="/oauth/gitlab"> | |||
<img src="/img/mark/gitlab.png" /> | |||
Sign in with <strong>{{.GitLabDisplayName}}</strong> | |||
</a> | |||
{{ end }} | |||
{{ if .GiteaEnabled }} | |||
<a class="btn cta loginbtn" id="gitea-login" href="/oauth/gitea"> | |||
<img src="/img/mark/gitea.png" /> | |||
Sign in with <strong>{{.GiteaDisplayName}}</strong> | |||
</a> | |||
{{ end }} | |||
{{ if .GenericEnabled }} | |||
<a class="btn cta loginbtn" id="generic-oauth-login" href="/oauth/generic">Sign in with <strong>{{.GenericDisplayName}}</strong></a> | |||
{{ end }} | |||
</div> | |||
{{if not .DisablePasswordAuth}} | |||
<div class="or"> | |||
<p>or</p> | |||
<hr class="short" /> | |||
</div> | |||
{{end}} | |||
{{ end }} | |||
{{end}} |
@@ -75,18 +75,18 @@ h3 { font-weight: normal; } | |||
</form> | |||
{{end}} | |||
{{ if .OauthSection }} | |||
{{ if .OauthSection }} | |||
<hr /> | |||
{{ if .OauthAccounts }} | |||
{{ if .OauthAccounts }} | |||
<div class="option"> | |||
<h2>Linked Accounts</h2> | |||
<p>These are your linked external accounts.</p> | |||
{{ range $oauth_account := .OauthAccounts }} | |||
<form method="post" action="/api/me/oauth/remove" autocomplete="false"> | |||
<input type="hidden" name="provider" value="{{ $oauth_account.Provider }}" /> | |||
<input type="hidden" name="client_id" value="{{ $oauth_account.ClientID }}" /> | |||
<input type="hidden" name="remote_user_id" value="{{ $oauth_account.RemoteUserID }}" /> | |||
{{ range $oauth_account := .OauthAccounts }} | |||
<form method="post" action="/api/me/oauth/remove" autocomplete="false"> | |||
<input type="hidden" name="provider" value="{{ $oauth_account.Provider }}" /> | |||
<input type="hidden" name="client_id" value="{{ $oauth_account.ClientID }}" /> | |||
<input type="hidden" name="remote_user_id" value="{{ $oauth_account.RemoteUserID }}" /> | |||
<div class="section oauth-provider"> | |||
{{ if $oauth_account.DisplayName}} | |||
{{ if $oauth_account.AllowDisconnect}} | |||
@@ -99,58 +99,58 @@ h3 { font-weight: normal; } | |||
<input type="submit" value="Remove {{ $oauth_account.Provider | title }}" /> | |||
{{end}} | |||
</div> | |||
</form> | |||
{{ end }} | |||
</form> | |||
{{ end }} | |||
</div> | |||
{{ end }} | |||
{{ if or .OauthSlack .OauthWriteAs .OauthGitLab .OauthGeneric .OauthGitea }} | |||
<div class="option"> | |||
<h2>Link External Accounts</h2> | |||
<p>Connect additional accounts to enable logging in with those providers, instead of using your username and password.</p> | |||
<div class="row"> | |||
<div class="row signinbtns"> | |||
{{ if .OauthWriteAs }} | |||
<div class="section oauth-provider"> | |||
<img src="/img/mark/writeas.png" alt="Write.as" /> | |||
<a class="btn cta loginbtn" id="writeas-login" href="/oauth/write.as?attach=t"> | |||
<img src="/img/mark/writeas-white.png" alt="Write.as" /> | |||
Link <strong>Write.as</strong> | |||
</a> | |||
</div> | |||
{{ end }} | |||
{{ if .OauthSlack }} | |||
{{ if .OauthSlack }} | |||
<div class="section oauth-provider"> | |||
<img src="/img/mark/slack.png" alt="Slack" /> | |||
<a class="btn cta loginbtn" href="/oauth/slack?attach=t"> | |||
<a class="btn cta loginbtn" id="slack-login" href="/oauth/slack?attach=t"> | |||
<img src="/img/mark/slack.png" alt="Slack" /> | |||
Link <strong>Slack</strong> | |||
</a> | |||
</div> | |||
{{ end }} | |||
{{ if .OauthGitLab }} | |||
{{ end }} | |||
{{ if .OauthGitLab }} | |||
<div class="section oauth-provider"> | |||
<img src="/img/mark/gitlab.png" alt="GitLab" /> | |||
<a class="btn cta loginbtn" id="gitlab-login" href="/oauth/gitlab?attach=t"> | |||
<img src="/img/mark/gitlab.png" alt="GitLab" /> | |||
Link <strong>{{.GitLabDisplayName}}</strong> | |||
</a> | |||
</div> | |||
{{ end }} | |||
{{ if .OauthGitea }} | |||
{{ end }} | |||
{{ if .OauthGitea }} | |||
<div class="section oauth-provider"> | |||
<img src="/img/mark/gitea.png" alt="Gitea" /> | |||
<a class="btn cta loginbtn" id="gitea-login" href="/oauth/gitea?attach=t"> | |||
<img src="/img/mark/gitea.png" alt="Gitea" /> | |||
Link <strong>{{.GiteaDisplayName}}</strong> | |||
</a> | |||
</div> | |||
{{ end }} | |||
</div> | |||
{{ if .OauthGeneric }} | |||
<div class="row"> | |||
<div class="section oauth-provider"> | |||
<p><a class="btn cta loginbtn" id="generic-oauth-login" href="/oauth/generic?attach=t">Link <strong>{{ .OauthGenericDisplayName }}</strong></a></p> | |||
</div> | |||
{{ end }} | |||
{{ if .OauthGeneric }} | |||
<div class="section oauth-provider"> | |||
<a class="btn cta loginbtn" id="generic-oauth-login" href="/oauth/generic?attach=t"> | |||
Link <strong>{{ .OauthGenericDisplayName }}</strong> | |||
</a> | |||
</div> | |||
{{ end }} | |||
{{ end }} | |||
</div> | |||
</div> | |||
{{ end }} | |||
{{ end }} | |||
{{ end }} | |||
</div> | |||
<script> | |||