Merge pull request #1837 from flant/bump-golangci-lint-and-fix-some-linters

fix: Bump golangci-lint version and fix some linter's problems
This commit is contained in:
Márk Sági-Kazár 2020-10-18 16:05:57 +02:00 committed by GitHub
commit c82d21b155
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 195 additions and 175 deletions

View file

@ -1,34 +1,45 @@
run: run:
timeout: 2m timeout: 2m
linters-settings: linters-settings:
golint: golint:
min-confidence: 0.1 min-confidence: 0.1
goimports: goimports:
local-prefixes: github.com/dexidp/dex local-prefixes: github.com/dexidp/dex
linters: linters:
enable-all: true disable-all: true
disable: enable:
- funlen - bodyclose
- maligned - deadcode
- wsl - depguard
- dogsled
- gochecknoinits
- gofmt
- goimports
- golint
- gosimple
- gocritic
- govet
- ineffassign
- interfacer
- misspell
- nakedret
- staticcheck
- structcheck
- stylecheck
- typecheck
- unconvert
- unused
- varcheck
- whitespace
# TODO: fix me # TODO: fix linter errors before enabling
- unparam # - unparam
- golint # - scopelint
- goconst # - gosec
- staticcheck # - gocyclo
- nakedret # - lll
- errcheck # - goconst
- gosec # - errcheck
- gochecknoinits # - dupl
- gochecknoglobals
- prealloc
- scopelint
- lll
- dupl
- gocritic
- gocyclo
- gocognit
- godox

View file

@ -18,7 +18,7 @@ export GOBIN=$(PWD)/bin
LD_FLAGS="-w -X $(REPO_PATH)/version.Version=$(VERSION)" LD_FLAGS="-w -X $(REPO_PATH)/version.Version=$(VERSION)"
# Dependency versions # Dependency versions
GOLANGCI_VERSION = 1.21.0 GOLANGCI_VERSION = 1.31.0
build: bin/dex build: bin/dex

View file

@ -49,7 +49,7 @@ type Config struct {
StaticPasswords []password `json:"staticPasswords"` StaticPasswords []password `json:"staticPasswords"`
} }
//Validate the configuration // Validate the configuration
func (c Config) Validate() error { func (c Config) Validate() error {
// Fast checks. Perform these first for a more responsive CLI. // Fast checks. Perform these first for a more responsive CLI.
checks := []struct { checks := []struct {

View file

@ -111,7 +111,7 @@ func (c *crowdConnector) Login(ctx context.Context, s connector.Scopes, username
// We want to return a different error if the user's password is incorrect vs // We want to return a different error if the user's password is incorrect vs
// if there was an error. // if there was an error.
incorrectPass := false var incorrectPass bool
var user crowdUser var user crowdUser
client := c.crowdAPIClient() client := c.crowdAPIClient()

View file

@ -34,7 +34,7 @@ func (m *callback) LoginURL(s connector.Scopes, callbackURL, state string) (stri
if err != nil { if err != nil {
return "", fmt.Errorf("failed to parse callbackURL %q: %v", callbackURL, err) return "", fmt.Errorf("failed to parse callbackURL %q: %v", callbackURL, err)
} }
u.Path = u.Path + m.pathSuffix u.Path += m.pathSuffix
v := u.Query() v := u.Query()
v.Set("state", state) v.Set("state", state)
u.RawQuery = v.Encode() u.RawQuery = v.Encode()

View file

@ -334,11 +334,12 @@ func (c *githubConnector) Refresh(ctx context.Context, s connector.Scopes, ident
// getGroups retrieves GitHub orgs and teams a user is in, if any. // getGroups retrieves GitHub orgs and teams a user is in, if any.
func (c *githubConnector) getGroups(ctx context.Context, client *http.Client, groupScope bool, userLogin string) ([]string, error) { func (c *githubConnector) getGroups(ctx context.Context, client *http.Client, groupScope bool, userLogin string) ([]string, error) {
if len(c.orgs) > 0 { switch {
case len(c.orgs) > 0:
return c.groupsForOrgs(ctx, client, userLogin) return c.groupsForOrgs(ctx, client, userLogin)
} else if c.org != "" { case c.org != "":
return c.teamsForOrg(ctx, client, c.org) return c.teamsForOrg(ctx, client, c.org)
} else if groupScope && c.loadAllGroups { case groupScope && c.loadAllGroups:
return c.userGroups(ctx, client) return c.userGroups(ctx, client)
} }
return nil, nil return nil, nil

View file

@ -13,6 +13,7 @@ import (
"golang.org/x/oauth2" "golang.org/x/oauth2"
"golang.org/x/oauth2/google" "golang.org/x/oauth2/google"
admin "google.golang.org/api/admin/directory/v1" admin "google.golang.org/api/admin/directory/v1"
"google.golang.org/api/option"
"github.com/dexidp/dex/connector" "github.com/dexidp/dex/connector"
pkg_groups "github.com/dexidp/dex/pkg/groups" pkg_groups "github.com/dexidp/dex/pkg/groups"
@ -289,7 +290,7 @@ func createDirectoryService(serviceAccountFilePath string, email string) (*admin
ctx := context.Background() ctx := context.Background()
client := config.Client(ctx) client := config.Client(ctx)
srv, err := admin.New(client) srv, err := admin.NewService(ctx, option.WithHTTPClient(client))
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to create directory service %v", err) return nil, fmt.Errorf("unable to create directory service %v", err)
} }

View file

@ -56,6 +56,7 @@ import (
// nameAttr: name // nameAttr: name
// //
// UserMatcher holds information about user and group matching.
type UserMatcher struct { type UserMatcher struct {
UserAttr string `json:"userAttr"` UserAttr string `json:"userAttr"`
GroupAttr string `json:"groupAttr"` GroupAttr string `json:"groupAttr"`
@ -187,9 +188,9 @@ func parseScope(s string) (int, bool) {
// See "Config.GroupSearch.UserMatchers" comments for the details // See "Config.GroupSearch.UserMatchers" comments for the details
func (c *ldapConnector) userMatchers() []UserMatcher { func (c *ldapConnector) userMatchers() []UserMatcher {
if len(c.GroupSearch.UserMatchers) > 0 && c.GroupSearch.UserMatchers[0].UserAttr != "" { if len(c.GroupSearch.UserMatchers) > 0 && c.GroupSearch.UserMatchers[0].UserAttr != "" {
return c.GroupSearch.UserMatchers[:] return c.GroupSearch.UserMatchers
} }
return []UserMatcher{ return []UserMatcher{
{ {
UserAttr: c.GroupSearch.UserAttr, UserAttr: c.GroupSearch.UserAttr,
@ -244,9 +245,9 @@ func (c *Config) openConnector(logger log.Logger) (*ldapConnector, error) {
if host, _, err = net.SplitHostPort(c.Host); err != nil { if host, _, err = net.SplitHostPort(c.Host); err != nil {
host = c.Host host = c.Host
if c.InsecureNoSSL { if c.InsecureNoSSL {
c.Host = c.Host + ":389" c.Host += ":389"
} else { } else {
c.Host = c.Host + ":636" c.Host += ":636"
} }
} }
@ -303,7 +304,7 @@ var (
// do initializes a connection to the LDAP directory and passes it to the // do initializes a connection to the LDAP directory and passes it to the
// provided function. It then performs appropriate teardown or reuse before // provided function. It then performs appropriate teardown or reuse before
// returning. // returning.
func (c *ldapConnector) do(ctx context.Context, f func(c *ldap.Conn) error) error { func (c *ldapConnector) do(_ context.Context, f func(c *ldap.Conn) error) error {
// TODO(ericchiang): support context here // TODO(ericchiang): support context here
var ( var (
conn *ldap.Conn conn *ldap.Conn

View file

@ -11,6 +11,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"strings" "strings"
"sync"
"time" "time"
"github.com/beevik/etree" "github.com/beevik/etree"
@ -60,20 +61,9 @@ var (
nameIDformatTransient, nameIDformatTransient,
} }
nameIDFormatLookup = make(map[string]string) nameIDFormatLookup = make(map[string]string)
)
func init() { lookupOnce sync.Once
suffix := func(s, sep string) string { )
if i := strings.LastIndex(s, sep); i > 0 {
return s[i+1:]
}
return s
}
for _, format := range nameIDFormats {
nameIDFormatLookup[suffix(format, ":")] = format
nameIDFormatLookup[format] = format
}
}
// Config represents configuration options for the SAML provider. // Config represents configuration options for the SAML provider.
type Config struct { type Config struct {
@ -176,6 +166,19 @@ func (c *Config) openConnector(logger log.Logger) (*provider, error) {
if p.nameIDPolicyFormat == "" { if p.nameIDPolicyFormat == "" {
p.nameIDPolicyFormat = nameIDFormatPersistent p.nameIDPolicyFormat = nameIDFormatPersistent
} else { } else {
lookupOnce.Do(func() {
suffix := func(s, sep string) string {
if i := strings.LastIndex(s, sep); i > 0 {
return s[i+1:]
}
return s
}
for _, format := range nameIDFormats {
nameIDFormatLookup[suffix(format, ":")] = format
nameIDFormatLookup[format] = format
}
})
if format, ok := nameIDFormatLookup[p.nameIDPolicyFormat]; ok { if format, ok := nameIDFormatLookup[p.nameIDPolicyFormat]; ok {
p.nameIDPolicyFormat = format p.nameIDPolicyFormat = format
} else { } else {
@ -364,7 +367,7 @@ func (p *provider) HandlePOST(s connector.Scopes, samlResponse, inResponseTo str
switch { switch {
case subject.NameID != nil: case subject.NameID != nil:
if ident.UserID = subject.NameID.Value; ident.UserID == "" { if ident.UserID = subject.NameID.Value; ident.UserID == "" {
return ident, fmt.Errorf("NameID element does not contain a value") return ident, fmt.Errorf("element NameID does not contain a value")
} }
default: default:
return ident, fmt.Errorf("subject does not contain an NameID element") return ident, fmt.Errorf("subject does not contain an NameID element")
@ -488,7 +491,7 @@ func (p *provider) validateSubject(subject *subject, inResponseTo string) error
data := c.SubjectConfirmationData data := c.SubjectConfirmationData
if data == nil { if data == nil {
return fmt.Errorf("SubjectConfirmation contained no SubjectConfirmationData") return fmt.Errorf("no SubjectConfirmationData field found in SubjectConfirmation")
} }
if data.InResponseTo != inResponseTo { if data.InResponseTo != inResponseTo {
return fmt.Errorf("expected SubjectConfirmationData InResponseTo value %q, got %q", inResponseTo, data.InResponseTo) return fmt.Errorf("expected SubjectConfirmationData InResponseTo value %q, got %q", inResponseTo, data.InResponseTo)

View file

@ -291,7 +291,7 @@ func TestRefreshToken(t *testing.T) {
t.Errorf("failed to marshal offline session ID: %v", err) t.Errorf("failed to marshal offline session ID: %v", err)
} }
//Testing the api. // Testing the api.
listReq := api.ListRefreshReq{ listReq := api.ListRefreshReq{
UserId: subjectString, UserId: subjectString,
} }

View file

@ -15,17 +15,17 @@ import (
) )
type deviceCodeResponse struct { type deviceCodeResponse struct {
//The unique device code for device authentication // The unique device code for device authentication
DeviceCode string `json:"device_code"` DeviceCode string `json:"device_code"`
//The code the user will exchange via a browser and log in // The code the user will exchange via a browser and log in
UserCode string `json:"user_code"` UserCode string `json:"user_code"`
//The url to verify the user code. // The url to verify the user code.
VerificationURI string `json:"verification_uri"` VerificationURI string `json:"verification_uri"`
//The verification uri with the user code appended for pre-filling form // The verification uri with the user code appended for pre-filling form
VerificationURIComplete string `json:"verification_uri_complete"` VerificationURIComplete string `json:"verification_uri_complete"`
//The lifetime of the device code // The lifetime of the device code
ExpireTime int `json:"expires_in"` ExpireTime int `json:"expires_in"`
//How often the device is allowed to poll to verify that the user login occurred // How often the device is allowed to poll to verify that the user login occurred
PollInterval int `json:"interval"` PollInterval int `json:"interval"`
} }
@ -66,27 +66,27 @@ func (s *Server) handleDeviceCode(w http.ResponseWriter, r *http.Request) {
return return
} }
//Get the client id and scopes from the post // Get the client id and scopes from the post
clientID := r.Form.Get("client_id") clientID := r.Form.Get("client_id")
clientSecret := r.Form.Get("client_secret") clientSecret := r.Form.Get("client_secret")
scopes := strings.Fields(r.Form.Get("scope")) scopes := strings.Fields(r.Form.Get("scope"))
s.logger.Infof("Received device request for client %v with scopes %v", clientID, scopes) s.logger.Infof("Received device request for client %v with scopes %v", clientID, scopes)
//Make device code // Make device code
deviceCode := storage.NewDeviceCode() deviceCode := storage.NewDeviceCode()
//make user code // make user code
userCode, err := storage.NewUserCode() userCode, err := storage.NewUserCode()
if err != nil { if err != nil {
s.logger.Errorf("Error generating user code: %v", err) s.logger.Errorf("Error generating user code: %v", err)
s.tokenErrHelper(w, errInvalidRequest, "", http.StatusInternalServerError) s.tokenErrHelper(w, errInvalidRequest, "", http.StatusInternalServerError)
} }
//Generate the expire time // Generate the expire time
expireTime := time.Now().Add(s.deviceRequestsValidFor) expireTime := time.Now().Add(s.deviceRequestsValidFor)
//Store the Device Request // Store the Device Request
deviceReq := storage.DeviceRequest{ deviceReq := storage.DeviceRequest{
UserCode: userCode, UserCode: userCode,
DeviceCode: deviceCode, DeviceCode: deviceCode,
@ -102,7 +102,7 @@ func (s *Server) handleDeviceCode(w http.ResponseWriter, r *http.Request) {
return return
} }
//Store the device token // Store the device token
deviceToken := storage.DeviceToken{ deviceToken := storage.DeviceToken{
DeviceCode: deviceCode, DeviceCode: deviceCode,
Status: deviceTokenPending, Status: deviceTokenPending,
@ -176,7 +176,7 @@ func (s *Server) handleDeviceToken(w http.ResponseWriter, r *http.Request) {
now := s.now() now := s.now()
//Grab the device token, check validity // Grab the device token, check validity
deviceToken, err := s.storage.GetDeviceToken(deviceCode) deviceToken, err := s.storage.GetDeviceToken(deviceCode)
if err != nil { if err != nil {
if err != storage.ErrNotFound { if err != storage.ErrNotFound {
@ -189,13 +189,13 @@ func (s *Server) handleDeviceToken(w http.ResponseWriter, r *http.Request) {
return return
} }
//Rate Limiting check // Rate Limiting check
slowDown := false slowDown := false
pollInterval := deviceToken.PollIntervalSeconds pollInterval := deviceToken.PollIntervalSeconds
minRequestTime := deviceToken.LastRequestTime.Add(time.Second * time.Duration(pollInterval)) minRequestTime := deviceToken.LastRequestTime.Add(time.Second * time.Duration(pollInterval))
if now.Before(minRequestTime) { if now.Before(minRequestTime) {
slowDown = true slowDown = true
//Continually increase the poll interval until the user waits the proper time // Continually increase the poll interval until the user waits the proper time
pollInterval += 5 pollInterval += 5
} else { } else {
pollInterval = 5 pollInterval = 5
@ -255,7 +255,7 @@ func (s *Server) handleDeviceCallback(w http.ResponseWriter, r *http.Request) {
return return
} }
//Grab the device request from storage // Grab the device request from storage
deviceReq, err := s.storage.GetDeviceRequest(userCode) deviceReq, err := s.storage.GetDeviceRequest(userCode)
if err != nil || s.now().After(deviceReq.Expiry) { if err != nil || s.now().After(deviceReq.Expiry) {
errCode := http.StatusBadRequest errCode := http.StatusBadRequest
@ -289,7 +289,7 @@ func (s *Server) handleDeviceCallback(w http.ResponseWriter, r *http.Request) {
return return
} }
//Grab the device token from storage // Grab the device token from storage
old, err := s.storage.GetDeviceToken(deviceReq.DeviceCode) old, err := s.storage.GetDeviceToken(deviceReq.DeviceCode)
if err != nil || s.now().After(old.Expiry) { if err != nil || s.now().After(old.Expiry) {
errCode := http.StatusBadRequest errCode := http.StatusBadRequest
@ -353,7 +353,7 @@ func (s *Server) verifyUserCode(w http.ResponseWriter, r *http.Request) {
userCode = strings.ToUpper(userCode) userCode = strings.ToUpper(userCode)
//Find the user code in the available requests // Find the user code in the available requests
deviceRequest, err := s.storage.GetDeviceRequest(userCode) deviceRequest, err := s.storage.GetDeviceRequest(userCode)
if err != nil || s.now().After(deviceRequest.Expiry) { if err != nil || s.now().After(deviceRequest.Expiry) {
if err != nil && err != storage.ErrNotFound { if err != nil && err != storage.ErrNotFound {
@ -366,7 +366,7 @@ func (s *Server) verifyUserCode(w http.ResponseWriter, r *http.Request) {
return return
} }
//Redirect to Dex Auth Endpoint // Redirect to Dex Auth Endpoint
authURL := path.Join(s.issuerURL.Path, "/auth") authURL := path.Join(s.issuerURL.Path, "/auth")
u, err := url.Parse(authURL) u, err := url.Parse(authURL)
if err != nil { if err != nil {

View file

@ -24,7 +24,7 @@ func TestDeviceVerificationURI(t *testing.T) {
defer cancel() defer cancel()
// Setup a dex server. // Setup a dex server.
httpServer, s := newTestServer(ctx, t, func(c *Config) { httpServer, s := newTestServer(ctx, t, func(c *Config) {
c.Issuer = c.Issuer + "/non-root-path" c.Issuer += "/non-root-path"
c.Now = now c.Now = now
}) })
defer httpServer.Close() defer httpServer.Close()
@ -76,7 +76,7 @@ func TestHandleDeviceCode(t *testing.T) {
// Setup a dex server. // Setup a dex server.
httpServer, s := newTestServer(ctx, t, func(c *Config) { httpServer, s := newTestServer(ctx, t, func(c *Config) {
c.Issuer = c.Issuer + "/non-root-path" c.Issuer += "/non-root-path"
c.Now = now c.Now = now
}) })
defer httpServer.Close() defer httpServer.Close()
@ -322,7 +322,7 @@ func TestDeviceCallback(t *testing.T) {
// Setup a dex server. // Setup a dex server.
httpServer, s := newTestServer(ctx, t, func(c *Config) { httpServer, s := newTestServer(ctx, t, func(c *Config) {
//c.Issuer = c.Issuer + "/non-root-path" // c.Issuer = c.Issuer + "/non-root-path"
c.Now = now c.Now = now
}) })
defer httpServer.Close() defer httpServer.Close()
@ -506,7 +506,7 @@ func TestDeviceTokenResponse(t *testing.T) {
// Setup a dex server. // Setup a dex server.
httpServer, s := newTestServer(ctx, t, func(c *Config) { httpServer, s := newTestServer(ctx, t, func(c *Config) {
c.Issuer = c.Issuer + "/non-root-path" c.Issuer += "/non-root-path"
c.Now = now c.Now = now
}) })
defer httpServer.Close() defer httpServer.Close()
@ -546,7 +546,7 @@ func TestDeviceTokenResponse(t *testing.T) {
t.Errorf("Could read token response %v", err) t.Errorf("Could read token response %v", err)
} }
if tc.expectedResponseCode == http.StatusBadRequest || tc.expectedResponseCode == http.StatusUnauthorized { if tc.expectedResponseCode == http.StatusBadRequest || tc.expectedResponseCode == http.StatusUnauthorized {
expectJsonErrorResponse(tc.testName, body, tc.expectedServerResponse, t) expectJSONErrorResponse(tc.testName, body, tc.expectedServerResponse, t)
} else if string(body) != tc.expectedServerResponse { } else if string(body) != tc.expectedServerResponse {
t.Errorf("Unexpected Server Response. Expected %v got %v", tc.expectedServerResponse, string(body)) t.Errorf("Unexpected Server Response. Expected %v got %v", tc.expectedServerResponse, string(body))
} }
@ -554,7 +554,7 @@ func TestDeviceTokenResponse(t *testing.T) {
} }
} }
func expectJsonErrorResponse(testCase string, body []byte, expectedError string, t *testing.T) { func expectJSONErrorResponse(testCase string, body []byte, expectedError string, t *testing.T) {
jsonMap := make(map[string]interface{}) jsonMap := make(map[string]interface{})
err := json.Unmarshal(body, &jsonMap) err := json.Unmarshal(body, &jsonMap)
if err != nil { if err != nil {
@ -637,7 +637,7 @@ func TestVerifyCodeResponse(t *testing.T) {
// Setup a dex server. // Setup a dex server.
httpServer, s := newTestServer(ctx, t, func(c *Config) { httpServer, s := newTestServer(ctx, t, func(c *Config) {
c.Issuer = c.Issuer + "/non-root-path" c.Issuer += "/non-root-path"
c.Now = now c.Now = now
}) })
defer httpServer.Close() defer httpServer.Close()

View file

@ -274,7 +274,7 @@ func (s *Server) handleAuthorization(w http.ResponseWriter, r *http.Request) {
} }
} }
if err := s.templates.login(r, w, connectorInfos, r.URL.Path); err != nil { if err := s.templates.login(r, w, connectorInfos); err != nil {
s.logger.Errorf("Server template error: %v", err) s.logger.Errorf("Server template error: %v", err)
} }
} }
@ -335,7 +335,7 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) {
} }
http.Redirect(w, r, callbackURL, http.StatusFound) http.Redirect(w, r, callbackURL, http.StatusFound)
case connector.PasswordConnector: case connector.PasswordConnector:
if err := s.templates.password(r, w, r.URL.String(), "", usernamePrompt(conn), false, showBacklink, r.URL.Path); err != nil { if err := s.templates.password(r, w, r.URL.String(), "", usernamePrompt(conn), false, showBacklink); err != nil {
s.logger.Errorf("Server template error: %v", err) s.logger.Errorf("Server template error: %v", err)
} }
case connector.SAMLConnector: case connector.SAMLConnector:
@ -383,7 +383,7 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) {
return return
} }
if !ok { if !ok {
if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(passwordConnector), true, showBacklink, r.URL.Path); err != nil { if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(passwordConnector), true, showBacklink); err != nil {
s.logger.Errorf("Server template error: %v", err) s.logger.Errorf("Server template error: %v", err)
} }
return return
@ -505,7 +505,7 @@ func (s *Server) finalizeLogin(identity connector.Identity, authReq storage.Auth
email := claims.Email email := claims.Email
if !claims.EmailVerified { if !claims.EmailVerified {
email = email + " (unverified)" email += " (unverified)"
} }
s.logger.Infof("login successful: connector %q, username=%q, preferred_username=%q, email=%q, groups=%q", s.logger.Infof("login successful: connector %q, username=%q, preferred_username=%q, email=%q, groups=%q",
@ -518,7 +518,8 @@ func (s *Server) finalizeLogin(identity connector.Identity, authReq storage.Auth
} }
// Try to retrieve an existing OfflineSession object for the corresponding user. // Try to retrieve an existing OfflineSession object for the corresponding user.
if session, err := s.storage.GetOfflineSessions(identity.UserID, authReq.ConnectorID); err != nil { session, err := s.storage.GetOfflineSessions(identity.UserID, authReq.ConnectorID)
if err != nil {
if err != storage.ErrNotFound { if err != storage.ErrNotFound {
s.logger.Errorf("failed to get offline session: %v", err) s.logger.Errorf("failed to get offline session: %v", err)
return "", err return "", err
@ -536,17 +537,19 @@ func (s *Server) finalizeLogin(identity connector.Identity, authReq storage.Auth
s.logger.Errorf("failed to create offline session: %v", err) s.logger.Errorf("failed to create offline session: %v", err)
return "", err return "", err
} }
} else {
// Update existing OfflineSession obj with new RefreshTokenRef. return returnURL, nil
if err := s.storage.UpdateOfflineSessions(session.UserID, session.ConnID, func(old storage.OfflineSessions) (storage.OfflineSessions, error) { }
if len(identity.ConnectorData) > 0 {
old.ConnectorData = identity.ConnectorData // Update existing OfflineSession obj with new RefreshTokenRef.
} if err := s.storage.UpdateOfflineSessions(session.UserID, session.ConnID, func(old storage.OfflineSessions) (storage.OfflineSessions, error) {
return old, nil if len(identity.ConnectorData) > 0 {
}); err != nil { old.ConnectorData = identity.ConnectorData
s.logger.Errorf("failed to update offline session: %v", err)
return "", err
} }
return old, nil
}); err != nil {
s.logger.Errorf("failed to update offline session: %v", err)
return "", err
} }
return returnURL, nil return returnURL, nil
@ -577,7 +580,7 @@ func (s *Server) handleApproval(w http.ResponseWriter, r *http.Request) {
s.renderError(r, w, http.StatusInternalServerError, "Failed to retrieve client.") s.renderError(r, w, http.StatusInternalServerError, "Failed to retrieve client.")
return return
} }
if err := s.templates.approval(r, w, authReq.ID, authReq.Claims.Username, client.Name, authReq.Scopes, r.URL.Path); err != nil { if err := s.templates.approval(r, w, authReq.ID, authReq.Claims.Username, client.Name, authReq.Scopes); err != nil {
s.logger.Errorf("Server template error: %v", err) s.logger.Errorf("Server template error: %v", err)
} }
case http.MethodPost: case http.MethodPost:
@ -650,7 +653,7 @@ func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authRe
// Implicit and hybrid flows that try to use the OOB redirect URI are // Implicit and hybrid flows that try to use the OOB redirect URI are
// rejected earlier. If we got here we're using the code flow. // rejected earlier. If we got here we're using the code flow.
if authReq.RedirectURI == redirectURIOOB { if authReq.RedirectURI == redirectURIOOB {
if err := s.templates.oob(r, w, code.ID, r.URL.Path); err != nil { if err := s.templates.oob(r, w, code.ID); err != nil {
s.logger.Errorf("Server template error: %v", err) s.logger.Errorf("Server template error: %v", err)
} }
return return
@ -1017,15 +1020,18 @@ func (s *Server) handleRefreshToken(w http.ResponseWriter, r *http.Request, clie
} }
var connectorData []byte var connectorData []byte
if session, err := s.storage.GetOfflineSessions(refresh.Claims.UserID, refresh.ConnectorID); err != nil {
session, err := s.storage.GetOfflineSessions(refresh.Claims.UserID, refresh.ConnectorID)
switch {
case err != nil:
if err != storage.ErrNotFound { if err != storage.ErrNotFound {
s.logger.Errorf("failed to get offline session: %v", err) s.logger.Errorf("failed to get offline session: %v", err)
return return
} }
} else if len(refresh.ConnectorData) > 0 { case len(refresh.ConnectorData) > 0:
// Use the old connector data if it exists, should be deleted once used // Use the old connector data if it exists, should be deleted once used
connectorData = refresh.ConnectorData connectorData = refresh.ConnectorData
} else { default:
connectorData = session.ConnectorData connectorData = session.ConnectorData
} }

View file

@ -305,7 +305,7 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy)
} }
r.Handle(path.Join(issuerURL.Path, p), instrumentHandlerCounter(p, handler)) r.Handle(path.Join(issuerURL.Path, p), instrumentHandlerCounter(p, handler))
} }
r.NotFoundHandler = http.HandlerFunc(http.NotFound) r.NotFoundHandler = http.NotFoundHandler()
discoveryHandler, err := s.discoveryHandler() discoveryHandler, err := s.discoveryHandler()
if err != nil { if err != nil {

View file

@ -177,7 +177,7 @@ func TestDiscovery(t *testing.T) {
defer cancel() defer cancel()
httpServer, _ := newTestServer(ctx, t, func(c *Config) { httpServer, _ := newTestServer(ctx, t, func(c *Config) {
c.Issuer = c.Issuer + "/non-root-path" c.Issuer += "/non-root-path"
}) })
defer httpServer.Close() defer httpServer.Close()
@ -504,7 +504,7 @@ func TestOAuth2CodeFlow(t *testing.T) {
// Setup a dex server. // Setup a dex server.
httpServer, s := newTestServer(ctx, t, func(c *Config) { httpServer, s := newTestServer(ctx, t, func(c *Config) {
c.Issuer = c.Issuer + "/non-root-path" c.Issuer += "/non-root-path"
c.Now = now c.Now = now
c.IDTokensValidFor = idTokensValidFor c.IDTokensValidFor = idTokensValidFor
}) })
@ -766,7 +766,7 @@ func TestCrossClientScopes(t *testing.T) {
defer cancel() defer cancel()
httpServer, s := newTestServer(ctx, t, func(c *Config) { httpServer, s := newTestServer(ctx, t, func(c *Config) {
c.Issuer = c.Issuer + "/non-root-path" c.Issuer += "/non-root-path"
}) })
defer httpServer.Close() defer httpServer.Close()
@ -889,7 +889,7 @@ func TestCrossClientScopesWithAzpInAudienceByDefault(t *testing.T) {
defer cancel() defer cancel()
httpServer, s := newTestServer(ctx, t, func(c *Config) { httpServer, s := newTestServer(ctx, t, func(c *Config) {
c.Issuer = c.Issuer + "/non-root-path" c.Issuer += "/non-root-path"
}) })
defer httpServer.Close() defer httpServer.Close()
@ -1180,7 +1180,7 @@ type oauth2Client struct {
// that only valid refresh tokens can be used to refresh an expired token. // that only valid refresh tokens can be used to refresh an expired token.
func TestRefreshTokenFlow(t *testing.T) { func TestRefreshTokenFlow(t *testing.T) {
state := "state" state := "state"
now := func() time.Time { return time.Now() } now := time.Now
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
@ -1300,7 +1300,7 @@ func TestOAuth2DeviceFlow(t *testing.T) {
// Setup a dex server. // Setup a dex server.
httpServer, s := newTestServer(ctx, t, func(c *Config) { httpServer, s := newTestServer(ctx, t, func(c *Config) {
c.Issuer = c.Issuer + "/non-root-path" c.Issuer += "/non-root-path"
c.Now = now c.Now = now
c.IDTokensValidFor = idTokensValidFor c.IDTokensValidFor = idTokensValidFor
}) })
@ -1314,7 +1314,7 @@ func TestOAuth2DeviceFlow(t *testing.T) {
t.Fatalf("failed to get provider: %v", err) t.Fatalf("failed to get provider: %v", err)
} }
//Add the Clients to the test server // Add the Clients to the test server
client := storage.Client{ client := storage.Client{
ID: clientID, ID: clientID,
RedirectURIs: []string{deviceCallbackURI}, RedirectURIs: []string{deviceCallbackURI},
@ -1324,13 +1324,13 @@ func TestOAuth2DeviceFlow(t *testing.T) {
t.Fatalf("failed to create client: %v", err) t.Fatalf("failed to create client: %v", err)
} }
//Grab the issuer that we'll reuse for the different endpoints to hit // Grab the issuer that we'll reuse for the different endpoints to hit
issuer, err := url.Parse(s.issuerURL.String()) issuer, err := url.Parse(s.issuerURL.String())
if err != nil { if err != nil {
t.Errorf("Could not parse issuer URL %v", err) t.Errorf("Could not parse issuer URL %v", err)
} }
//Send a new Device Request // Send a new Device Request
codeURL, _ := url.Parse(issuer.String()) codeURL, _ := url.Parse(issuer.String())
codeURL.Path = path.Join(codeURL.Path, "device/code") codeURL.Path = path.Join(codeURL.Path, "device/code")
@ -1350,13 +1350,13 @@ func TestOAuth2DeviceFlow(t *testing.T) {
t.Errorf("%v - Unexpected Response Type. Expected 200 got %v. Response: %v", tc.name, resp.StatusCode, string(responseBody)) t.Errorf("%v - Unexpected Response Type. Expected 200 got %v. Response: %v", tc.name, resp.StatusCode, string(responseBody))
} }
//Parse the code response // Parse the code response
var deviceCode deviceCodeResponse var deviceCode deviceCodeResponse
if err := json.Unmarshal(responseBody, &deviceCode); err != nil { if err := json.Unmarshal(responseBody, &deviceCode); err != nil {
t.Errorf("Unexpected Device Code Response Format %v", string(responseBody)) t.Errorf("Unexpected Device Code Response Format %v", string(responseBody))
} }
//Mock the user hitting the verification URI and posting the form // Mock the user hitting the verification URI and posting the form
verifyURL, _ := url.Parse(issuer.String()) verifyURL, _ := url.Parse(issuer.String())
verifyURL.Path = path.Join(verifyURL.Path, "/device/auth/verify_code") verifyURL.Path = path.Join(verifyURL.Path, "/device/auth/verify_code")
urlData := url.Values{} urlData := url.Values{}
@ -1374,7 +1374,7 @@ func TestOAuth2DeviceFlow(t *testing.T) {
t.Errorf("%v - Unexpected Response Type. Expected 200 got %v. Response: %v", tc.name, resp.StatusCode, string(responseBody)) t.Errorf("%v - Unexpected Response Type. Expected 200 got %v. Response: %v", tc.name, resp.StatusCode, string(responseBody))
} }
//Hit the Token Endpoint, and try and get an access token // Hit the Token Endpoint, and try and get an access token
tokenURL, _ := url.Parse(issuer.String()) tokenURL, _ := url.Parse(issuer.String())
tokenURL.Path = path.Join(tokenURL.Path, "/device/token") tokenURL.Path = path.Join(tokenURL.Path, "/device/token")
v := url.Values{} v := url.Values{}
@ -1393,7 +1393,7 @@ func TestOAuth2DeviceFlow(t *testing.T) {
t.Errorf("%v - Unexpected Token Response Type. Expected 200 got %v. Response: %v", tc.name, resp.StatusCode, string(responseBody)) t.Errorf("%v - Unexpected Token Response Type. Expected 200 got %v. Response: %v", tc.name, resp.StatusCode, string(responseBody))
} }
//Parse the response // Parse the response
var tokenRes accessTokenReponse var tokenRes accessTokenReponse
if err := json.Unmarshal(responseBody, &tokenRes); err != nil { if err := json.Unmarshal(responseBody, &tokenRes); err != nil {
t.Errorf("Unexpected Device Access Token Response Format %v", string(responseBody)) t.Errorf("Unexpected Device Access Token Response Format %v", string(responseBody))
@ -1411,7 +1411,7 @@ func TestOAuth2DeviceFlow(t *testing.T) {
token.Expiry = time.Now().Add(time.Duration(secs) * time.Second) token.Expiry = time.Now().Add(time.Duration(secs) * time.Second)
} }
//Run token tests to validate info is correct // Run token tests to validate info is correct
// Create the OAuth2 config. // Create the OAuth2 config.
oauth2Config := &oauth2.Config{ oauth2Config := &oauth2.Config{
ClientID: client.ID, ClientID: client.ID,

View file

@ -78,7 +78,7 @@ func dirExists(dir string) error {
// | |- (theme name) // | |- (theme name)
// |- templates // |- templates
// //
func loadWebConfig(c webConfig) (static, theme http.Handler, templates *templates, err error) { func loadWebConfig(c webConfig) (http.Handler, http.Handler, *templates, error) {
if c.theme == "" { if c.theme == "" {
c.theme = "coreos" c.theme = "coreos"
} }
@ -106,11 +106,11 @@ func loadWebConfig(c webConfig) (static, theme http.Handler, templates *template
} }
} }
static = http.FileServer(http.Dir(staticDir)) static := http.FileServer(http.Dir(staticDir))
theme = http.FileServer(http.Dir(themeDir)) theme := http.FileServer(http.Dir(themeDir))
templates, err = loadTemplates(c, templatesDir) templates, err := loadTemplates(c, templatesDir)
return return static, theme, templates, err
} }
// loadTemplates parses the expected templates from the provided directory. // loadTemplates parses the expected templates from the provided directory.
@ -178,11 +178,11 @@ func loadTemplates(c webConfig, templatesDir string) (*templates, error) {
// 3. For each part of reqPath remaining(minus one), go up one level (..) // 3. For each part of reqPath remaining(minus one), go up one level (..)
// 4. For each part of assetPath remaining, append it to result // 4. For each part of assetPath remaining, append it to result
// //
//eg // eg
//server listens at localhost/dex so serverPath is dex // server listens at localhost/dex so serverPath is dex
//reqPath is /dex/auth // reqPath is /dex/auth
//assetPath is static/main.css // assetPath is static/main.css
//relativeURL("/dex", "/dex/auth", "static/main.css") = "../static/main.css" // relativeURL("/dex", "/dex/auth", "static/main.css") = "../static/main.css"
func relativeURL(serverPath, reqPath, assetPath string) string { func relativeURL(serverPath, reqPath, assetPath string) string {
if u, err := url.ParseRequestURI(assetPath); err == nil && u.Scheme != "" { if u, err := url.ParseRequestURI(assetPath); err == nil && u.Scheme != "" {
// assetPath points to the external URL, no changes needed // assetPath points to the external URL, no changes needed
@ -219,8 +219,7 @@ func relativeURL(serverPath, reqPath, assetPath string) string {
server, req, asset := splitPath(serverPath), splitPath(reqPath), splitPath(assetPath) server, req, asset := splitPath(serverPath), splitPath(reqPath), splitPath(assetPath)
// Remove common prefix of request path with server path // Remove common prefix of request path with server path
// nolint: ineffassign _, req = stripCommonParts(server, req)
server, req = stripCommonParts(server, req)
// Remove common prefix of request path with asset path // Remove common prefix of request path with asset path
asset, req = stripCommonParts(asset, req) asset, req = stripCommonParts(asset, req)
@ -276,7 +275,7 @@ func (t *templates) deviceSuccess(r *http.Request, w http.ResponseWriter, client
return renderTemplate(w, t.deviceSuccessTmpl, data) return renderTemplate(w, t.deviceSuccessTmpl, data)
} }
func (t *templates) login(r *http.Request, w http.ResponseWriter, connectors []connectorInfo, reqPath string) error { func (t *templates) login(r *http.Request, w http.ResponseWriter, connectors []connectorInfo) error {
sort.Sort(byName(connectors)) sort.Sort(byName(connectors))
data := struct { data := struct {
Connectors []connectorInfo Connectors []connectorInfo
@ -285,7 +284,7 @@ func (t *templates) login(r *http.Request, w http.ResponseWriter, connectors []c
return renderTemplate(w, t.loginTmpl, data) return renderTemplate(w, t.loginTmpl, data)
} }
func (t *templates) password(r *http.Request, w http.ResponseWriter, postURL, lastUsername, usernamePrompt string, lastWasInvalid, showBacklink bool, reqPath string) error { func (t *templates) password(r *http.Request, w http.ResponseWriter, postURL, lastUsername, usernamePrompt string, lastWasInvalid, showBacklink bool) error {
data := struct { data := struct {
PostURL string PostURL string
BackLink bool BackLink bool
@ -297,7 +296,7 @@ func (t *templates) password(r *http.Request, w http.ResponseWriter, postURL, la
return renderTemplate(w, t.passwordTmpl, data) return renderTemplate(w, t.passwordTmpl, data)
} }
func (t *templates) approval(r *http.Request, w http.ResponseWriter, authReqID, username, clientName string, scopes []string, reqPath string) error { func (t *templates) approval(r *http.Request, w http.ResponseWriter, authReqID, username, clientName string, scopes []string) error {
accesses := []string{} accesses := []string{}
for _, scope := range scopes { for _, scope := range scopes {
access, ok := scopeDescriptions[scope] access, ok := scopeDescriptions[scope]
@ -316,7 +315,7 @@ func (t *templates) approval(r *http.Request, w http.ResponseWriter, authReqID,
return renderTemplate(w, t.approvalTmpl, data) return renderTemplate(w, t.approvalTmpl, data)
} }
func (t *templates) oob(r *http.Request, w http.ResponseWriter, code string, reqPath string) error { func (t *templates) oob(r *http.Request, w http.ResponseWriter, code string) error {
data := struct { data := struct {
Code string Code string
ReqPath string ReqPath string
@ -332,7 +331,7 @@ func (t *templates) err(r *http.Request, w http.ResponseWriter, errCode int, err
ReqPath string ReqPath string
}{http.StatusText(errCode), errMsg, r.URL.Path} }{http.StatusText(errCode), errMsg, r.URL.Path}
if err := t.errorTmpl.Execute(w, data); err != nil { if err := t.errorTmpl.Execute(w, data); err != nil {
return fmt.Errorf("Error rendering template %s: %s", t.errorTmpl.Name(), err) return fmt.Errorf("rendering template %s failed: %s", t.errorTmpl.Name(), err)
} }
return nil return nil
} }
@ -355,7 +354,7 @@ func renderTemplate(w http.ResponseWriter, tmpl *template.Template, data interfa
// TODO(ericchiang): replace with better internal server error. // TODO(ericchiang): replace with better internal server error.
http.Error(w, "Internal server error", http.StatusInternalServerError) http.Error(w, "Internal server error", http.StatusInternalServerError)
} }
return fmt.Errorf("Error rendering template %s: %s", tmpl.Name(), err) return fmt.Errorf("rendering template %s failed: %s", tmpl.Name(), err)
} }
return nil return nil
} }

View file

@ -763,10 +763,8 @@ func testGC(t *testing.T, s storage.Storage) {
result, err := s.GarbageCollect(expiry.Add(-time.Hour).In(tz)) result, err := s.GarbageCollect(expiry.Add(-time.Hour).In(tz))
if err != nil { if err != nil {
t.Errorf("garbage collection failed: %v", err) t.Errorf("garbage collection failed: %v", err)
} else { } else if result.AuthCodes != 0 || result.AuthRequests != 0 {
if result.AuthCodes != 0 || result.AuthRequests != 0 { t.Errorf("expected no garbage collection results, got %#v", result)
t.Errorf("expected no garbage collection results, got %#v", result)
}
} }
if _, err := s.GetAuthCode(c.ID); err != nil { if _, err := s.GetAuthCode(c.ID); err != nil {
t.Errorf("expected to be able to get auth code after GC: %v", err) t.Errorf("expected to be able to get auth code after GC: %v", err)
@ -815,10 +813,8 @@ func testGC(t *testing.T, s storage.Storage) {
result, err := s.GarbageCollect(expiry.Add(-time.Hour).In(tz)) result, err := s.GarbageCollect(expiry.Add(-time.Hour).In(tz))
if err != nil { if err != nil {
t.Errorf("garbage collection failed: %v", err) t.Errorf("garbage collection failed: %v", err)
} else { } else if result.AuthCodes != 0 || result.AuthRequests != 0 {
if result.AuthCodes != 0 || result.AuthRequests != 0 { t.Errorf("expected no garbage collection results, got %#v", result)
t.Errorf("expected no garbage collection results, got %#v", result)
}
} }
if _, err := s.GetAuthRequest(a.ID); err != nil { if _, err := s.GetAuthRequest(a.ID); err != nil {
t.Errorf("expected to be able to get auth request after GC: %v", err) t.Errorf("expected to be able to get auth request after GC: %v", err)
@ -859,10 +855,8 @@ func testGC(t *testing.T, s storage.Storage) {
result, err := s.GarbageCollect(expiry.Add(-time.Hour).In(tz)) result, err := s.GarbageCollect(expiry.Add(-time.Hour).In(tz))
if err != nil { if err != nil {
t.Errorf("garbage collection failed: %v", err) t.Errorf("garbage collection failed: %v", err)
} else { } else if result.DeviceRequests != 0 {
if result.DeviceRequests != 0 { t.Errorf("expected no device garbage collection results, got %#v", result)
t.Errorf("expected no device garbage collection results, got %#v", result)
}
} }
if _, err := s.GetDeviceRequest(d.UserCode); err != nil { if _, err := s.GetDeviceRequest(d.UserCode); err != nil {
t.Errorf("expected to be able to get auth request after GC: %v", err) t.Errorf("expected to be able to get auth request after GC: %v", err)
@ -897,10 +891,8 @@ func testGC(t *testing.T, s storage.Storage) {
result, err := s.GarbageCollect(expiry.Add(-time.Hour).In(tz)) result, err := s.GarbageCollect(expiry.Add(-time.Hour).In(tz))
if err != nil { if err != nil {
t.Errorf("garbage collection failed: %v", err) t.Errorf("garbage collection failed: %v", err)
} else { } else if result.DeviceTokens != 0 {
if result.DeviceTokens != 0 { t.Errorf("expected no device token garbage collection results, got %#v", result)
t.Errorf("expected no device token garbage collection results, got %#v", result)
}
} }
if _, err := s.GetDeviceToken(dt.DeviceCode); err != nil { if _, err := s.GetDeviceToken(dt.DeviceCode); err != nil {
t.Errorf("expected to be able to get device token after GC: %v", err) t.Errorf("expected to be able to get device token after GC: %v", err)
@ -987,12 +979,12 @@ func testDeviceRequestCRUD(t *testing.T, s storage.Storage) {
err = s.CreateDeviceRequest(d1) err = s.CreateDeviceRequest(d1)
mustBeErrAlreadyExists(t, "device request", err) mustBeErrAlreadyExists(t, "device request", err)
//No manual deletes for device requests, will be handled by garbage collection routines // No manual deletes for device requests, will be handled by garbage collection routines
//see testGC // see testGC
} }
func testDeviceTokenCRUD(t *testing.T, s storage.Storage) { func testDeviceTokenCRUD(t *testing.T, s storage.Storage) {
//Create a Token // Create a Token
d1 := storage.DeviceToken{ d1 := storage.DeviceToken{
DeviceCode: storage.NewID(), DeviceCode: storage.NewID(),
Status: "pending", Status: "pending",
@ -1010,7 +1002,7 @@ func testDeviceTokenCRUD(t *testing.T, s storage.Storage) {
err := s.CreateDeviceToken(d1) err := s.CreateDeviceToken(d1)
mustBeErrAlreadyExists(t, "device token", err) mustBeErrAlreadyExists(t, "device token", err)
//Update the device token, simulate a redemption // Update the device token, simulate a redemption
if err := s.UpdateDeviceToken(d1.DeviceCode, func(old storage.DeviceToken) (storage.DeviceToken, error) { if err := s.UpdateDeviceToken(d1.DeviceCode, func(old storage.DeviceToken) (storage.DeviceToken, error) {
old.Token = "token data" old.Token = "token data"
old.Status = "complete" old.Status = "complete"
@ -1019,13 +1011,13 @@ func testDeviceTokenCRUD(t *testing.T, s storage.Storage) {
t.Fatalf("failed to update device token: %v", err) t.Fatalf("failed to update device token: %v", err)
} }
//Retrieve the device token // Retrieve the device token
got, err := s.GetDeviceToken(d1.DeviceCode) got, err := s.GetDeviceToken(d1.DeviceCode)
if err != nil { if err != nil {
t.Fatalf("failed to get device token: %v", err) t.Fatalf("failed to get device token: %v", err)
} }
//Validate expected result set // Validate expected result set
if got.Status != "complete" { if got.Status != "complete" {
t.Fatalf("update failed, wanted token status=%v got %v", "complete", got.Status) t.Fatalf("update failed, wanted token status=%v got %v", "complete", got.Status)
} }

View file

@ -24,7 +24,7 @@ type Config struct {
// Legacy field from pkg/api/types.go TypeMeta. // Legacy field from pkg/api/types.go TypeMeta.
// TODO(jlowdermilk): remove this after eliminating downstream dependencies. // TODO(jlowdermilk): remove this after eliminating downstream dependencies.
Kind string `json:"kind,omitempty"` Kind string `json:"kind,omitempty"`
// DEPRECATED: APIVersion is the preferred api version for communicating with the kubernetes cluster (v1, v2, etc). // Deprecated: APIVersion is the preferred api version for communicating with the kubernetes cluster (v1, v2, etc).
// Because a cluster can run multiple API groups and potentially multiple versions of each, it no longer makes sense to specify // Because a cluster can run multiple API groups and potentially multiple versions of each, it no longer makes sense to specify
// a single value for the cluster version. // a single value for the cluster version.
// This field isn't really needed anyway, so we are deprecating it without replacement. // This field isn't really needed anyway, so we are deprecating it without replacement.

View file

@ -679,7 +679,7 @@ type DeviceRequest struct {
Expiry time.Time `json:"expiry"` Expiry time.Time `json:"expiry"`
} }
// AuthRequestList is a list of AuthRequests. // DeviceRequestList is a list of DeviceRequests.
type DeviceRequestList struct { type DeviceRequestList struct {
k8sapi.TypeMeta `json:",inline"` k8sapi.TypeMeta `json:",inline"`
k8sapi.ListMeta `json:"metadata,omitempty"` k8sapi.ListMeta `json:"metadata,omitempty"`

View file

@ -289,16 +289,19 @@ func (s *MySQL) open(logger log.Logger) (*conn, error) {
cfg.Addr = s.Host cfg.Addr = s.Host
} }
} }
if s.SSL.CAFile != "" || s.SSL.CertFile != "" || s.SSL.KeyFile != "" {
switch {
case s.SSL.CAFile != "" || s.SSL.CertFile != "" || s.SSL.KeyFile != "":
if err := s.makeTLSConfig(); err != nil { if err := s.makeTLSConfig(); err != nil {
return nil, fmt.Errorf("failed to make TLS config: %v", err) return nil, fmt.Errorf("failed to make TLS config: %v", err)
} }
cfg.TLSConfig = mysqlSSLCustom cfg.TLSConfig = mysqlSSLCustom
} else if s.SSL.Mode == "" { case s.SSL.Mode == "":
cfg.TLSConfig = mysqlSSLTrue cfg.TLSConfig = mysqlSSLTrue
} else { default:
cfg.TLSConfig = s.SSL.Mode cfg.TLSConfig = s.SSL.Mode
} }
for k, v := range s.params { for k, v := range s.params {
cfg.Params[k] = v cfg.Params[k] = v
} }

View file

@ -84,7 +84,9 @@ type scanner interface {
Scan(dest ...interface{}) error Scan(dest ...interface{}) error
} }
func (c *conn) GarbageCollect(now time.Time) (result storage.GCResult, err error) { func (c *conn) GarbageCollect(now time.Time) (storage.GCResult, error) {
result := storage.GCResult{}
r, err := c.Exec(`delete from auth_request where expiry < $1`, now) r, err := c.Exec(`delete from auth_request where expiry < $1`, now)
if err != nil { if err != nil {
return result, fmt.Errorf("gc auth_request: %v", err) return result, fmt.Errorf("gc auth_request: %v", err)
@ -117,7 +119,7 @@ func (c *conn) GarbageCollect(now time.Time) (result storage.GCResult, err error
result.DeviceTokens = n result.DeviceTokens = n
} }
return return result, err
} }
func (c *conn) CreateAuthRequest(a storage.AuthRequest) error { func (c *conn) CreateAuthRequest(a storage.AuthRequest) error {

View file

@ -96,7 +96,7 @@ type staticPasswordsStorage struct {
func WithStaticPasswords(s Storage, staticPasswords []Password, logger log.Logger) Storage { func WithStaticPasswords(s Storage, staticPasswords []Password, logger log.Logger) Storage {
passwordsByEmail := make(map[string]Password, len(staticPasswords)) passwordsByEmail := make(map[string]Password, len(staticPasswords))
for _, p := range staticPasswords { for _, p := range staticPasswords {
//Enable case insensitive email comparison. // Enable case insensitive email comparison.
lowerEmail := strings.ToLower(p.Email) lowerEmail := strings.ToLower(p.Email)
if _, ok := passwordsByEmail[lowerEmail]; ok { if _, ok := passwordsByEmail[lowerEmail]; ok {
logger.Errorf("Attempting to create StaticPasswords with the same email id: %s", p.Email) logger.Errorf("Attempting to create StaticPasswords with the same email id: %s", p.Email)

View file

@ -25,7 +25,7 @@ var (
// TODO(ericchiang): refactor ID creation onto the storage. // TODO(ericchiang): refactor ID creation onto the storage.
var encoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567") var encoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567")
//Valid characters for user codes // Valid characters for user codes
const validUserCharacters = "BCDFGHJKLMNPQRSTVWXZ" const validUserCharacters = "BCDFGHJKLMNPQRSTVWXZ"
// NewDeviceCode returns a 32 char alphanumeric cryptographically secure string // NewDeviceCode returns a 32 char alphanumeric cryptographically secure string
@ -384,23 +384,24 @@ func randomString(n int) (string, error) {
return string(bytes), nil return string(bytes), nil
} }
//DeviceRequest represents an OIDC device authorization request. It holds the state of a device request until the user // DeviceRequest represents an OIDC device authorization request. It holds the state of a device request until the user
//authenticates using their user code or the expiry time passes. // authenticates using their user code or the expiry time passes.
type DeviceRequest struct { type DeviceRequest struct {
//The code the user will enter in a browser // The code the user will enter in a browser
UserCode string UserCode string
//The unique device code for device authentication // The unique device code for device authentication
DeviceCode string DeviceCode string
//The client ID the code is for // The client ID the code is for
ClientID string ClientID string
//The Client Secret // The Client Secret
ClientSecret string ClientSecret string
//The scopes the device requests // The scopes the device requests
Scopes []string Scopes []string
//The expire time // The expire time
Expiry time.Time Expiry time.Time
} }
// DeviceToken is a structure which represents the actual token of an authorized device and its rotation parameters
type DeviceToken struct { type DeviceToken struct {
DeviceCode string DeviceCode string
Status string Status string