go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/server/auth/deprecated/settings.go (about)

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