-
Notifications
You must be signed in to change notification settings - Fork 0
/
settings.go
148 lines (129 loc) · 4.9 KB
/
settings.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright 2015 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package openid
import (
"context"
"errors"
"html/template"
"github.com/TriggerMail/luci-go/server/portal"
"github.com/TriggerMail/luci-go/server/settings"
)
// SettingsKey is key for OpenID settings (described by Settings struct) in
// settings store. See go.chromium.org/luci/server/settings.
const SettingsKey = "openid_auth"
var (
// ErrNotConfigured is returned by various functions if OpenID settings are
// not properly configured.
ErrNotConfigured = errors.New("openid: not configured")
)
// Settings contain parameters of OpenID protocol. They are stored in app
// settings store under SettingsKey key.
type Settings struct {
// DiscoveryURL is where to grab discovery document with provider's config.
// Use `https://accounts.google.com/.well-known/openid-configuration` for
// Google OpenID Connect provider.
DiscoveryURL string `json:"discovery_url"`
// ClientID identifies OAuth2 Web client representing the application. Create
// one in Cloud Console if using Google OpenID Connect provider.
ClientID string `json:"client_id"`
// ClientSecret is a secret associated with ClientID.
ClientSecret string `json:"client_secret"`
// RedirectURI must be `https://<apphost>/auth/openid/callback`. It is stored
// in config explicitly to remind admin that OAuth2 client in Cloud Console
// must be configured accordingly.
RedirectURI string `json:"redirect_uri"`
}
// fetchCachedSettings fetches OpenID configuration from the settings store.
func fetchCachedSettings(c context.Context) (*Settings, error) {
cfg := &Settings{}
if err := settings.Get(c, SettingsKey, cfg); err != settings.ErrNoSettings {
return cfg, err
}
return cfg, nil
}
////////////////////////////////////////////////////////////////////////////////
// UI for configuring OpenID.
type settingsPage struct {
portal.BasePage
}
func (settingsPage) Title(c context.Context) (string, error) {
return "OpenID authentication settings", nil
}
func (settingsPage) Overview(c context.Context) (template.HTML, error) {
return `<p>OpenID Connect is the primary authentication protocol used by
luci services to authenticate web users. It is triggered whenever incoming HTTP
request doesn't have a session cookie set or the session has expired.</p>
<p>It needs to be configured with details of what OpenID provider to use and how
to authenticate calls to it.</p>`, nil
}
func (settingsPage) Fields(c context.Context) ([]portal.Field, error) {
return []portal.Field{
{
ID: "DiscoveryURL",
Title: "Discovery URL",
Type: portal.FieldText,
Help: `Where to grab OpenID Connect discovery document with provider's
config. Use <b>https://accounts.google.com/.well-known/openid-configuration</b>
for Google OpenID Connect provider.`,
},
{
ID: "ClientID",
Title: "OAuth client ID",
Type: portal.FieldText,
Help: `Identifies OAuth2 Web Client representing the application.
Create one in <a href="https://console.developers.google.com">Cloud Console</a>
if using Google OpenID Connect provider. It is fine to reuse an existing OAuth2
client as long as you register additional redirect URI in its configuration.`,
},
{
ID: "ClientSecret",
Title: "OAuth client secret",
Type: portal.FieldText,
Help: `Secret associated with OAuth2 Web Client. Grab it from
<a href="https://console.developers.google.com">Cloud Console</a>.`,
},
{
ID: "RedirectURI",
Title: "Redirect URI",
Type: portal.FieldText,
Help: `OpenID callback URI that must be set to
<b>https://<i>your-host</i>/auth/openid/callback</b>. Configure OAuth2 Web
Client with exact same value.`,
},
}, nil
}
func (settingsPage) ReadSettings(c context.Context) (map[string]string, error) {
s := Settings{}
err := settings.GetUncached(c, SettingsKey, &s)
if err != nil && err != settings.ErrNoSettings {
return nil, err
}
return map[string]string{
"DiscoveryURL": s.DiscoveryURL,
"ClientID": s.ClientID,
"ClientSecret": s.ClientSecret,
"RedirectURI": s.RedirectURI,
}, nil
}
func (settingsPage) WriteSettings(c context.Context, values map[string]string, who, why string) error {
return settings.SetIfChanged(c, SettingsKey, &Settings{
DiscoveryURL: values["DiscoveryURL"],
ClientID: values["ClientID"],
ClientSecret: values["ClientSecret"],
RedirectURI: values["RedirectURI"],
}, who, why)
}
func init() {
portal.RegisterPage(SettingsKey, settingsPage{})
}