mirror of
https://github.com/netbirdio/dex.git
synced 2026-05-22 18:43:53 -07:00
feat: Create AuthSessions and set cookies (#4650)
Signed-off-by: maksim.nabokikh <max.nabokih@gmail.com>
This commit is contained in:
@@ -65,6 +65,10 @@ type Config struct {
|
||||
// querying the storage. Cannot be specified without enabling a passwords
|
||||
// database.
|
||||
StaticPasswords []password `json:"staticPasswords"`
|
||||
|
||||
// Sessions holds authentication session configuration.
|
||||
// Requires DEX_SESSIONS_ENABLED=true feature flag.
|
||||
Sessions *Sessions `json:"sessions"`
|
||||
}
|
||||
|
||||
// Validate the configuration
|
||||
@@ -103,6 +107,11 @@ func (c Config) Validate() error {
|
||||
if len(checkErrors) != 0 {
|
||||
return fmt.Errorf("invalid Config:\n\t-\t%s", strings.Join(checkErrors, "\n\t-\t"))
|
||||
}
|
||||
|
||||
if c.Sessions != nil && !featureflags.SessionsEnabled.Enabled() {
|
||||
return fmt.Errorf("sessions config requires sessions to be enabled (DEX_SESSIONS_ENABLED=true)")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -585,3 +594,15 @@ type RefreshToken struct {
|
||||
AbsoluteLifetime string `json:"absoluteLifetime"`
|
||||
ValidIfNotUsedFor string `json:"validIfNotUsedFor"`
|
||||
}
|
||||
|
||||
// Sessions holds authentication session configuration.
|
||||
type Sessions struct {
|
||||
// CookieName is the name of the session cookie. Defaults to "dex_session".
|
||||
CookieName string `json:"cookieName"`
|
||||
// AbsoluteLifetime is the maximum session lifetime from creation. Defaults to "24h".
|
||||
AbsoluteLifetime string `json:"absoluteLifetime"`
|
||||
// ValidIfNotUsedFor is the idle timeout. Defaults to "1h".
|
||||
ValidIfNotUsedFor string `json:"validIfNotUsedFor"`
|
||||
// RememberMeCheckedByDefault controls the default state of the "remember me" checkbox.
|
||||
RememberMeCheckedByDefault *bool `json:"rememberMeCheckedByDefault"`
|
||||
}
|
||||
|
||||
@@ -415,6 +415,19 @@ func runServe(options serveOptions) error {
|
||||
|
||||
serverConfig.RefreshTokenPolicy = refreshTokenPolicy
|
||||
|
||||
if featureflags.SessionsEnabled.Enabled() {
|
||||
sessionConfig, err := parseSessionConfig(c.Sessions)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid session config: %v", err)
|
||||
}
|
||||
serverConfig.SessionConfig = sessionConfig
|
||||
logger.Info("config sessions",
|
||||
"cookie_name", sessionConfig.CookieName,
|
||||
"absolute_lifetime", sessionConfig.AbsoluteLifetime,
|
||||
"valid_if_not_used_for", sessionConfig.ValidIfNotUsedFor,
|
||||
)
|
||||
}
|
||||
|
||||
serverConfig.RealIPHeader = c.Web.ClientRemoteIP.Header
|
||||
serverConfig.TrustedRealIPCIDRs, err = c.Web.ClientRemoteIP.ParseTrustedProxies()
|
||||
if err != nil {
|
||||
@@ -759,3 +772,44 @@ func loadTLSConfig(certFile, keyFile, caFile string, baseConfig *tls.Config) (*t
|
||||
func recordBuildInfo() {
|
||||
buildInfo.WithLabelValues(version, runtime.Version(), fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)).Set(1)
|
||||
}
|
||||
|
||||
func parseSessionConfig(s *Sessions) (*server.SessionConfig, error) {
|
||||
sc := &server.SessionConfig{
|
||||
CookieName: "dex_session",
|
||||
AbsoluteLifetime: 24 * time.Hour,
|
||||
ValidIfNotUsedFor: 1 * time.Hour,
|
||||
RememberMeCheckedByDefault: true,
|
||||
}
|
||||
if s != nil {
|
||||
if s.CookieName != "" {
|
||||
sc.CookieName = s.CookieName
|
||||
}
|
||||
if s.AbsoluteLifetime != "" {
|
||||
d, err := time.ParseDuration(s.AbsoluteLifetime)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid absoluteLifetime %q: %v", s.AbsoluteLifetime, err)
|
||||
}
|
||||
sc.AbsoluteLifetime = d
|
||||
}
|
||||
if s.ValidIfNotUsedFor != "" {
|
||||
d, err := time.ParseDuration(s.ValidIfNotUsedFor)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid validIfNotUsedFor %q: %v", s.ValidIfNotUsedFor, err)
|
||||
}
|
||||
sc.ValidIfNotUsedFor = d
|
||||
}
|
||||
if s.RememberMeCheckedByDefault != nil {
|
||||
sc.RememberMeCheckedByDefault = *s.RememberMeCheckedByDefault
|
||||
}
|
||||
}
|
||||
if sc.AbsoluteLifetime <= 0 {
|
||||
return nil, fmt.Errorf("absoluteLifetime must be positive, got %v", sc.AbsoluteLifetime)
|
||||
}
|
||||
if sc.ValidIfNotUsedFor <= 0 {
|
||||
return nil, fmt.Errorf("validIfNotUsedFor must be positive, got %v", sc.ValidIfNotUsedFor)
|
||||
}
|
||||
if sc.ValidIfNotUsedFor > sc.AbsoluteLifetime {
|
||||
return nil, fmt.Errorf("validIfNotUsedFor (%v) must not exceed absoluteLifetime (%v)", sc.ValidIfNotUsedFor, sc.AbsoluteLifetime)
|
||||
}
|
||||
return sc, nil
|
||||
}
|
||||
|
||||
@@ -95,6 +95,14 @@ telemetry:
|
||||
# validIfNotUsedFor: "2160h" # 90 days
|
||||
# absoluteLifetime: "3960h" # 165 days
|
||||
|
||||
# Authentication sessions configuration.
|
||||
# Requires DEX_SESSIONS_ENABLED=true feature flag.
|
||||
# sessions:
|
||||
# cookieName: "dex_session"
|
||||
# absoluteLifetime: "24h"
|
||||
# validIfNotUsedFor: "1h"
|
||||
# rememberMeCheckedByDefault: false
|
||||
|
||||
# Options for controlling the logger.
|
||||
# logger:
|
||||
# level: "debug"
|
||||
|
||||
+45
-14
@@ -365,6 +365,16 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Check if there's a valid session that can skip login for this client.
|
||||
if s.sessionConfig != nil {
|
||||
if redirectURL, ok := s.trySessionLogin(ctx, r, w, authReq); ok {
|
||||
if redirectURL != "" {
|
||||
http.Redirect(w, r, redirectURL, http.StatusSeeOther)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
scopes := parseScopes(authReq.Scopes)
|
||||
|
||||
// Work out where the "Select another login method" link should go.
|
||||
@@ -493,9 +503,11 @@ func (s *Server) handlePasswordLogin(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
rememberMe := s.rememberMeDefault()
|
||||
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
if err := s.templates.password(r, w, r.URL.String(), "", usernamePrompt(pwConn), false, backLink); err != nil {
|
||||
if err := s.templates.password(r, w, r.URL.String(), "", usernamePrompt(pwConn), false, backLink, rememberMe); err != nil {
|
||||
s.logger.ErrorContext(r.Context(), "server template error", "err", err)
|
||||
}
|
||||
case http.MethodPost:
|
||||
@@ -510,7 +522,7 @@ func (s *Server) handlePasswordLogin(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
if !ok {
|
||||
if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(pwConn), true, backLink); err != nil {
|
||||
if err := s.templates.password(r, w, r.URL.String(), username, usernamePrompt(pwConn), true, backLink, rememberMe); err != nil {
|
||||
s.logger.ErrorContext(r.Context(), "server template error", "err", err)
|
||||
}
|
||||
s.logger.ErrorContext(r.Context(), "failed login attempt: Invalid credentials.", "user", username)
|
||||
@@ -523,13 +535,21 @@ func (s *Server) handlePasswordLogin(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Re-read auth request after finalizeLogin populated Claims.
|
||||
authReq, err = s.storage.GetAuthRequest(ctx, authReq.ID)
|
||||
if err != nil {
|
||||
s.logger.ErrorContext(r.Context(), "failed to get finalized auth request", "err", err)
|
||||
s.renderError(r, w, http.StatusInternalServerError, "Login error.")
|
||||
return
|
||||
}
|
||||
|
||||
rememberMe := r.FormValue("remember_me") == "on"
|
||||
if err := s.createOrUpdateAuthSession(ctx, r, w, authReq, rememberMe); err != nil {
|
||||
s.logger.ErrorContext(ctx, "failed to create/update auth session", "err", err)
|
||||
}
|
||||
|
||||
if canSkipApproval {
|
||||
authReq, err = s.storage.GetAuthRequest(ctx, authReq.ID)
|
||||
if err != nil {
|
||||
s.logger.ErrorContext(r.Context(), "failed to get finalized auth request", "err", err)
|
||||
s.renderError(r, w, http.StatusInternalServerError, "Login error.")
|
||||
return
|
||||
}
|
||||
// authReq was already re-read after finalizeLogin above.
|
||||
s.sendCodeResponse(w, r, authReq)
|
||||
return
|
||||
}
|
||||
@@ -628,13 +648,22 @@ func (s *Server) handleConnectorCallback(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
// Re-read auth request after finalizeLogin populated Claims.
|
||||
authReq, err = s.storage.GetAuthRequest(ctx, authReq.ID)
|
||||
if err != nil {
|
||||
s.logger.ErrorContext(r.Context(), "failed to get finalized auth request", "err", err)
|
||||
s.renderError(r, w, http.StatusInternalServerError, "Login error.")
|
||||
return
|
||||
}
|
||||
|
||||
// Connector callbacks don't render the remember_me checkbox, so we use the server default.
|
||||
// The password login handler reads r.FormValue("remember_me") from the submitted form instead.
|
||||
if err := s.createOrUpdateAuthSession(ctx, r, w, authReq, s.sessionConfig != nil && s.sessionConfig.RememberMeCheckedByDefault); err != nil {
|
||||
s.logger.ErrorContext(ctx, "failed to create/update auth session", "err", err)
|
||||
}
|
||||
|
||||
if canSkipApproval {
|
||||
authReq, err = s.storage.GetAuthRequest(ctx, authReq.ID)
|
||||
if err != nil {
|
||||
s.logger.ErrorContext(r.Context(), "failed to get finalized auth request", "err", err)
|
||||
s.renderError(r, w, http.StatusInternalServerError, "Login error.")
|
||||
return
|
||||
}
|
||||
// authReq was already re-read after finalizeLogin above.
|
||||
s.sendCodeResponse(w, r, authReq)
|
||||
return
|
||||
}
|
||||
@@ -854,6 +883,8 @@ func (s *Server) handleApproval(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *Server) sendCodeResponse(w http.ResponseWriter, r *http.Request, authReq storage.AuthRequest) {
|
||||
s.updateSessionTokenIssuedAt(r, authReq.ClientID)
|
||||
|
||||
ctx := r.Context()
|
||||
if s.now().After(authReq.Expiry) {
|
||||
s.renderError(r, w, http.StatusBadRequest, "User session has expired.")
|
||||
|
||||
@@ -137,6 +137,17 @@ type Config struct {
|
||||
// If enabled, the server will continue starting even if some connectors fail to initialize.
|
||||
// This allows the server to operate with a subset of connectors if some are misconfigured.
|
||||
ContinueOnConnectorFailure bool
|
||||
|
||||
// SessionConfig holds session settings. Nil when sessions are disabled.
|
||||
SessionConfig *SessionConfig
|
||||
}
|
||||
|
||||
// SessionConfig holds resolved session configuration.
|
||||
type SessionConfig struct {
|
||||
CookieName string
|
||||
AbsoluteLifetime time.Duration
|
||||
ValidIfNotUsedFor time.Duration
|
||||
RememberMeCheckedByDefault bool
|
||||
}
|
||||
|
||||
// WebConfig holds the server's frontend templates and asset configuration.
|
||||
@@ -226,6 +237,8 @@ type Server struct {
|
||||
logger *slog.Logger
|
||||
|
||||
signer signer.Signer
|
||||
|
||||
sessionConfig *SessionConfig
|
||||
}
|
||||
|
||||
// NewServer constructs a server from the provided config.
|
||||
@@ -349,6 +362,7 @@ func newServer(ctx context.Context, c Config) (*Server, error) {
|
||||
passwordConnector: c.PasswordConnector,
|
||||
logger: c.Logger,
|
||||
signer: c.Signer,
|
||||
sessionConfig: c.SessionConfig,
|
||||
}
|
||||
|
||||
// Retrieves connector objects in backend storage. This list includes the static connectors
|
||||
|
||||
@@ -0,0 +1,339 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/dexidp/dex/storage"
|
||||
)
|
||||
|
||||
// rememberMeDefault returns a pointer to the default remember-me value if sessions are enabled, nil otherwise.
|
||||
func (s *Server) rememberMeDefault() *bool {
|
||||
if s.sessionConfig == nil {
|
||||
return nil
|
||||
}
|
||||
v := s.sessionConfig.RememberMeCheckedByDefault
|
||||
return &v
|
||||
}
|
||||
|
||||
// remoteIP returns the real IP from context (set by parseRealIP middleware) or falls back to r.RemoteAddr.
|
||||
func remoteIP(r *http.Request) string {
|
||||
if ip, ok := r.Context().Value(RequestKeyRemoteIP).(string); ok && ip != "" {
|
||||
return ip
|
||||
}
|
||||
return r.RemoteAddr
|
||||
}
|
||||
|
||||
// sessionCookieValue encodes session identity into a cookie value.
|
||||
// Format: base64url(userID) + "." + base64url(connectorID) + "." + nonce
|
||||
// TODO(nabokihms): consider cookie encoding
|
||||
func sessionCookieValue(userID, connectorID, nonce string) string {
|
||||
return base64.RawURLEncoding.EncodeToString([]byte(userID)) +
|
||||
"." + base64.RawURLEncoding.EncodeToString([]byte(connectorID)) +
|
||||
"." + nonce
|
||||
}
|
||||
|
||||
// parseSessionCookie decodes a session cookie value into its components.
|
||||
func parseSessionCookie(value string) (userID, connectorID, nonce string, err error) {
|
||||
parts := strings.SplitN(value, ".", 3)
|
||||
if len(parts) != 3 {
|
||||
return "", "", "", fmt.Errorf("invalid session cookie format")
|
||||
}
|
||||
|
||||
userIDBytes, err := base64.RawURLEncoding.DecodeString(parts[0])
|
||||
if err != nil {
|
||||
return "", "", "", fmt.Errorf("decode userID: %w", err)
|
||||
}
|
||||
|
||||
connectorIDBytes, err := base64.RawURLEncoding.DecodeString(parts[1])
|
||||
if err != nil {
|
||||
return "", "", "", fmt.Errorf("decode connectorID: %w", err)
|
||||
}
|
||||
|
||||
return string(userIDBytes), string(connectorIDBytes), parts[2], nil
|
||||
}
|
||||
|
||||
func (s *Server) sessionCookiePath() string {
|
||||
if s.issuerURL.Path == "" {
|
||||
return "/"
|
||||
}
|
||||
return s.issuerURL.Path
|
||||
}
|
||||
|
||||
func (s *Server) setSessionCookie(w http.ResponseWriter, userID, connectorID, nonce string, rememberMe bool) {
|
||||
cookie := &http.Cookie{
|
||||
Name: s.sessionConfig.CookieName,
|
||||
Value: sessionCookieValue(userID, connectorID, nonce),
|
||||
Path: s.sessionCookiePath(),
|
||||
HttpOnly: true,
|
||||
Secure: s.issuerURL.Scheme == "https",
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
}
|
||||
if rememberMe {
|
||||
cookie.MaxAge = int(s.sessionConfig.AbsoluteLifetime.Seconds())
|
||||
}
|
||||
http.SetCookie(w, cookie)
|
||||
}
|
||||
|
||||
func (s *Server) clearSessionCookie(w http.ResponseWriter) {
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: s.sessionConfig.CookieName,
|
||||
Value: "",
|
||||
Path: s.sessionCookiePath(),
|
||||
HttpOnly: true,
|
||||
Secure: s.issuerURL.Scheme == "https",
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
MaxAge: -1,
|
||||
})
|
||||
}
|
||||
|
||||
// getValidAuthSession returns a valid, non-expired session or nil.
|
||||
// It parses the session cookie to extract (userID, connectorID, nonce),
|
||||
// looks up the session by composite key, and verifies the nonce.
|
||||
// Invalid or expired session cookies are cleared automatically.
|
||||
func (s *Server) getValidAuthSession(ctx context.Context, w http.ResponseWriter, r *http.Request, authReq *storage.AuthRequest) *storage.AuthSession {
|
||||
if s.sessionConfig == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
cookie, err := r.Cookie(s.sessionConfig.CookieName)
|
||||
if err != nil || cookie.Value == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
userID, connectorID, nonce, err := parseSessionCookie(cookie.Value)
|
||||
if err != nil {
|
||||
s.logger.DebugContext(ctx, "invalid session cookie format", "err", err)
|
||||
s.clearSessionCookie(w)
|
||||
return nil
|
||||
}
|
||||
|
||||
session, err := s.storage.GetAuthSession(ctx, userID, connectorID)
|
||||
if err != nil {
|
||||
if !errors.Is(err, storage.ErrNotFound) {
|
||||
s.logger.ErrorContext(ctx, "failed to get auth session", "err", err)
|
||||
}
|
||||
s.clearSessionCookie(w)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Verify nonce to prevent cookie forgery.
|
||||
if session.Nonce != nonce {
|
||||
s.logger.DebugContext(ctx, "auth session nonce mismatch")
|
||||
s.clearSessionCookie(w)
|
||||
return nil
|
||||
}
|
||||
|
||||
now := s.now()
|
||||
|
||||
// Check absolute lifetime.
|
||||
if now.After(session.CreatedAt.Add(s.sessionConfig.AbsoluteLifetime)) {
|
||||
s.logger.InfoContext(ctx, "auth session expired (absolute lifetime)",
|
||||
"user_id", session.UserID, "connector_id", session.ConnectorID)
|
||||
if err := s.storage.DeleteAuthSession(ctx, session.UserID, session.ConnectorID); err != nil {
|
||||
s.logger.DebugContext(ctx, "failed to delete expired auth session", "err", err)
|
||||
}
|
||||
s.clearSessionCookie(w)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check idle timeout.
|
||||
if now.After(session.LastActivity.Add(s.sessionConfig.ValidIfNotUsedFor)) {
|
||||
s.logger.InfoContext(ctx, "auth session expired (idle timeout)",
|
||||
"user_id", session.UserID, "connector_id", session.ConnectorID)
|
||||
if err := s.storage.DeleteAuthSession(ctx, session.UserID, session.ConnectorID); err != nil {
|
||||
s.logger.DebugContext(ctx, "failed to delete expired auth session", "err", err)
|
||||
}
|
||||
s.clearSessionCookie(w)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Only reuse sessions from the same connector.
|
||||
if session.ConnectorID != authReq.ConnectorID {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &session
|
||||
}
|
||||
|
||||
// createOrUpdateAuthSession creates a new session or updates an existing one
|
||||
// after a successful login, and sets the session cookie.
|
||||
// rememberMe controls whether the cookie is persistent (survives browser close).
|
||||
func (s *Server) createOrUpdateAuthSession(ctx context.Context, r *http.Request, w http.ResponseWriter, authReq storage.AuthRequest, rememberMe bool) error {
|
||||
if s.sessionConfig == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
now := s.now()
|
||||
userID := authReq.Claims.UserID
|
||||
connectorID := authReq.ConnectorID
|
||||
|
||||
clientState := &storage.ClientAuthState{
|
||||
Active: true,
|
||||
ExpiresAt: now.Add(s.sessionConfig.AbsoluteLifetime),
|
||||
LastActivity: now,
|
||||
}
|
||||
|
||||
// Try to reuse existing session for this (userID, connectorID).
|
||||
session, err := s.storage.GetAuthSession(ctx, userID, connectorID)
|
||||
if err == nil {
|
||||
// Session exists, update it.
|
||||
s.logger.DebugContext(ctx, "updating existing auth session",
|
||||
"user_id", userID, "connector_id", connectorID, "client_id", authReq.ClientID)
|
||||
|
||||
if err := s.storage.UpdateAuthSession(ctx, userID, connectorID, func(old storage.AuthSession) (storage.AuthSession, error) {
|
||||
old.LastActivity = now
|
||||
if old.ClientStates == nil {
|
||||
old.ClientStates = make(map[string]*storage.ClientAuthState)
|
||||
}
|
||||
old.ClientStates[authReq.ClientID] = clientState
|
||||
return old, nil
|
||||
}); err != nil {
|
||||
return fmt.Errorf("update auth session: %w", err)
|
||||
}
|
||||
|
||||
s.setSessionCookie(w, userID, connectorID, session.Nonce, rememberMe)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unexpected error, exit the method.
|
||||
if !errors.Is(err, storage.ErrNotFound) {
|
||||
return fmt.Errorf("get auth session: %w", err)
|
||||
}
|
||||
|
||||
nonce := storage.NewID()
|
||||
newSession := storage.AuthSession{
|
||||
UserID: userID,
|
||||
ConnectorID: connectorID,
|
||||
Nonce: nonce,
|
||||
ClientStates: map[string]*storage.ClientAuthState{
|
||||
authReq.ClientID: clientState,
|
||||
},
|
||||
CreatedAt: now,
|
||||
LastActivity: now,
|
||||
IPAddress: remoteIP(r),
|
||||
UserAgent: r.UserAgent(),
|
||||
}
|
||||
|
||||
if err := s.storage.CreateAuthSession(ctx, newSession); err != nil {
|
||||
return fmt.Errorf("create auth session: %w", err)
|
||||
}
|
||||
|
||||
s.logger.DebugContext(ctx, "created new auth session",
|
||||
"user_id", userID, "connector_id", connectorID, "client_id", authReq.ClientID)
|
||||
s.setSessionCookie(w, userID, connectorID, nonce, rememberMe)
|
||||
return nil
|
||||
}
|
||||
|
||||
// trySessionLogin checks if the user has a valid session for the same connector.
|
||||
// If so, it finalizes login from the stored identity and returns a redirect URL.
|
||||
// Returns ("", false) if session-based login is not possible.
|
||||
func (s *Server) trySessionLogin(ctx context.Context, r *http.Request, w http.ResponseWriter, authReq *storage.AuthRequest) (string, bool) {
|
||||
session := s.getValidAuthSession(ctx, w, r, authReq)
|
||||
if session == nil {
|
||||
return "", false
|
||||
}
|
||||
|
||||
clientState, ok := session.ClientStates[authReq.ClientID]
|
||||
if !ok || !clientState.Active {
|
||||
return "", false
|
||||
}
|
||||
|
||||
now := s.now()
|
||||
if now.After(clientState.ExpiresAt) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Load identity from storage.
|
||||
ui, err := s.storage.GetUserIdentity(ctx, session.UserID, session.ConnectorID)
|
||||
if err != nil {
|
||||
s.logger.ErrorContext(ctx, "session: failed to get user identity", "err", err)
|
||||
return "", false
|
||||
}
|
||||
|
||||
claims := storage.Claims{
|
||||
UserID: ui.Claims.UserID,
|
||||
Username: ui.Claims.Username,
|
||||
PreferredUsername: ui.Claims.PreferredUsername,
|
||||
Email: ui.Claims.Email,
|
||||
EmailVerified: ui.Claims.EmailVerified,
|
||||
Groups: ui.Claims.Groups,
|
||||
}
|
||||
|
||||
// Update AuthRequest with stored identity (without logging "login successful").
|
||||
if err := s.storage.UpdateAuthRequest(ctx, authReq.ID, func(a storage.AuthRequest) (storage.AuthRequest, error) {
|
||||
a.LoggedIn = true
|
||||
a.Claims = claims
|
||||
a.ConnectorID = session.ConnectorID
|
||||
return a, nil
|
||||
}); err != nil {
|
||||
s.logger.ErrorContext(ctx, "session: failed to update auth request", "err", err)
|
||||
return "", false
|
||||
}
|
||||
|
||||
s.logger.DebugContext(ctx, "session: re-authenticated from session",
|
||||
"user_id", session.UserID, "connector_id", session.ConnectorID)
|
||||
|
||||
// Update session activity.
|
||||
_ = s.storage.UpdateAuthSession(ctx, session.UserID, session.ConnectorID, func(old storage.AuthSession) (storage.AuthSession, error) {
|
||||
old.LastActivity = now
|
||||
if cs, ok := old.ClientStates[authReq.ClientID]; ok {
|
||||
cs.LastActivity = now
|
||||
}
|
||||
return old, nil
|
||||
})
|
||||
|
||||
// Build HMAC for approval URL.
|
||||
h := hmac.New(sha256.New, authReq.HMACKey)
|
||||
h.Write([]byte(authReq.ID))
|
||||
mac := base64.RawURLEncoding.EncodeToString(h.Sum(nil))
|
||||
|
||||
// Skip approval if globally configured or user already consented to the requested scopes.
|
||||
if !authReq.ForceApprovalPrompt && (s.skipApproval || scopesCoveredByConsent(ui.Consents[authReq.ClientID], authReq.Scopes)) {
|
||||
// Re-read to get the updated AuthRequest (LoggedIn, Claims, ConnectorID set above).
|
||||
updated, err := s.storage.GetAuthRequest(ctx, authReq.ID)
|
||||
if err != nil {
|
||||
s.logger.ErrorContext(ctx, "session: failed to get auth request", "err", err)
|
||||
return "", false
|
||||
}
|
||||
s.sendCodeResponse(w, r, updated)
|
||||
return "", true
|
||||
}
|
||||
|
||||
returnURL := path.Join(s.issuerURL.Path, "/approval") + "?req=" + authReq.ID + "&hmac=" + mac
|
||||
return returnURL, true
|
||||
}
|
||||
|
||||
// updateSessionTokenIssuedAt updates the session's LastTokenIssuedAt for the given client.
|
||||
func (s *Server) updateSessionTokenIssuedAt(r *http.Request, clientID string) {
|
||||
if s.sessionConfig == nil {
|
||||
return
|
||||
}
|
||||
|
||||
cookie, err := r.Cookie(s.sessionConfig.CookieName)
|
||||
if err != nil || cookie.Value == "" {
|
||||
return
|
||||
}
|
||||
|
||||
userID, connectorID, _, err := parseSessionCookie(cookie.Value)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
now := s.now()
|
||||
_ = s.storage.UpdateAuthSession(r.Context(), userID, connectorID, func(old storage.AuthSession) (storage.AuthSession, error) {
|
||||
old.LastActivity = now
|
||||
if cs, ok := old.ClientStates[clientID]; ok {
|
||||
cs.LastTokenIssuedAt = now
|
||||
cs.LastActivity = now
|
||||
}
|
||||
return old, nil
|
||||
})
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+21
-8
@@ -291,18 +291,31 @@ func (t *templates) login(r *http.Request, w http.ResponseWriter, connectors []c
|
||||
return renderTemplate(w, t.loginTmpl, data)
|
||||
}
|
||||
|
||||
func (t *templates) password(r *http.Request, w http.ResponseWriter, postURL, lastUsername, usernamePrompt string, lastWasInvalid bool, backLink string) error {
|
||||
func (t *templates) password(r *http.Request, w http.ResponseWriter, postURL, lastUsername, usernamePrompt string, lastWasInvalid bool, backLink string, rememberMe *bool) error {
|
||||
if lastWasInvalid {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
}
|
||||
data := struct {
|
||||
PostURL string
|
||||
BackLink string
|
||||
Username string
|
||||
UsernamePrompt string
|
||||
Invalid bool
|
||||
ReqPath string
|
||||
}{postURL, backLink, lastUsername, usernamePrompt, lastWasInvalid, r.URL.Path}
|
||||
PostURL string
|
||||
BackLink string
|
||||
Username string
|
||||
UsernamePrompt string
|
||||
Invalid bool
|
||||
ReqPath string
|
||||
ShowRememberMe bool
|
||||
RememberMeChecked bool
|
||||
}{
|
||||
PostURL: postURL,
|
||||
BackLink: backLink,
|
||||
Username: lastUsername,
|
||||
UsernamePrompt: usernamePrompt,
|
||||
Invalid: lastWasInvalid,
|
||||
ReqPath: r.URL.Path,
|
||||
ShowRememberMe: rememberMe != nil,
|
||||
}
|
||||
if rememberMe != nil {
|
||||
data.RememberMeChecked = *rememberMe
|
||||
}
|
||||
return renderTemplate(w, t.passwordTmpl, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -1174,11 +1174,11 @@ func testAuthSessionCRUD(t *testing.T, s storage.Storage) {
|
||||
now := time.Now().UTC().Round(time.Millisecond)
|
||||
|
||||
session := storage.AuthSession{
|
||||
ID: storage.NewID(),
|
||||
UserID: "user1",
|
||||
ConnectorID: "conn1",
|
||||
Nonce: storage.NewID(),
|
||||
ClientStates: map[string]*storage.ClientAuthState{
|
||||
"client1": {
|
||||
UserID: "user1",
|
||||
ConnectorID: "conn1",
|
||||
Active: true,
|
||||
ExpiresAt: now.Add(24 * time.Hour),
|
||||
LastActivity: now,
|
||||
@@ -1201,7 +1201,7 @@ func testAuthSessionCRUD(t *testing.T, s storage.Storage) {
|
||||
mustBeErrAlreadyExists(t, "auth session", err)
|
||||
|
||||
// Get and compare.
|
||||
got, err := s.GetAuthSession(ctx, session.ID)
|
||||
got, err := s.GetAuthSession(ctx, session.UserID, session.ConnectorID)
|
||||
if err != nil {
|
||||
t.Fatalf("get auth session: %v", err)
|
||||
}
|
||||
@@ -1219,10 +1219,8 @@ func testAuthSessionCRUD(t *testing.T, s storage.Storage) {
|
||||
|
||||
// Update: add a new client state.
|
||||
newNow := now.Add(time.Minute)
|
||||
if err := s.UpdateAuthSession(ctx, session.ID, func(old storage.AuthSession) (storage.AuthSession, error) {
|
||||
if err := s.UpdateAuthSession(ctx, session.UserID, session.ConnectorID, func(old storage.AuthSession) (storage.AuthSession, error) {
|
||||
old.ClientStates["client2"] = &storage.ClientAuthState{
|
||||
UserID: "user2",
|
||||
ConnectorID: "conn2",
|
||||
Active: true,
|
||||
ExpiresAt: newNow.Add(24 * time.Hour),
|
||||
LastActivity: newNow,
|
||||
@@ -1234,7 +1232,7 @@ func testAuthSessionCRUD(t *testing.T, s storage.Storage) {
|
||||
}
|
||||
|
||||
// Get and verify update.
|
||||
got, err = s.GetAuthSession(ctx, session.ID)
|
||||
got, err = s.GetAuthSession(ctx, session.UserID, session.ConnectorID)
|
||||
if err != nil {
|
||||
t.Fatalf("get auth session after update: %v", err)
|
||||
}
|
||||
@@ -1244,9 +1242,6 @@ func testAuthSessionCRUD(t *testing.T, s storage.Storage) {
|
||||
if got.ClientStates["client2"] == nil {
|
||||
t.Fatal("expected client2 state to exist")
|
||||
}
|
||||
if got.ClientStates["client2"].UserID != "user2" {
|
||||
t.Errorf("expected client2 user_id to be user2, got %s", got.ClientStates["client2"].UserID)
|
||||
}
|
||||
|
||||
// List and verify.
|
||||
sessions, err := s.ListAuthSessions(ctx)
|
||||
@@ -1258,11 +1253,11 @@ func testAuthSessionCRUD(t *testing.T, s storage.Storage) {
|
||||
}
|
||||
|
||||
// Delete.
|
||||
if err := s.DeleteAuthSession(ctx, session.ID); err != nil {
|
||||
if err := s.DeleteAuthSession(ctx, session.UserID, session.ConnectorID); err != nil {
|
||||
t.Fatalf("delete auth session: %v", err)
|
||||
}
|
||||
|
||||
// Get deleted should return ErrNotFound.
|
||||
_, err = s.GetAuthSession(ctx, session.ID)
|
||||
_, err = s.GetAuthSession(ctx, session.UserID, session.ConnectorID)
|
||||
mustBeErrNotFound(t, "auth session", err)
|
||||
}
|
||||
|
||||
@@ -18,8 +18,12 @@ func (d *Database) CreateAuthSession(ctx context.Context, session storage.AuthSe
|
||||
return fmt.Errorf("encode client states auth session: %w", err)
|
||||
}
|
||||
|
||||
id := compositeKeyID(session.UserID, session.ConnectorID, d.hasher)
|
||||
_, err = d.client.AuthSession.Create().
|
||||
SetID(session.ID).
|
||||
SetID(id).
|
||||
SetUserID(session.UserID).
|
||||
SetConnectorID(session.ConnectorID).
|
||||
SetNonce(session.Nonce).
|
||||
SetClientStates(encodedStates).
|
||||
SetCreatedAt(session.CreatedAt).
|
||||
SetLastActivity(session.LastActivity).
|
||||
@@ -32,9 +36,10 @@ func (d *Database) CreateAuthSession(ctx context.Context, session storage.AuthSe
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAuthSession extracts an auth session from the database by session ID.
|
||||
func (d *Database) GetAuthSession(ctx context.Context, sessionID string) (storage.AuthSession, error) {
|
||||
authSession, err := d.client.AuthSession.Get(ctx, sessionID)
|
||||
// GetAuthSession extracts an auth session from the database by user ID and connector ID.
|
||||
func (d *Database) GetAuthSession(ctx context.Context, userID, connectorID string) (storage.AuthSession, error) {
|
||||
id := compositeKeyID(userID, connectorID, d.hasher)
|
||||
authSession, err := d.client.AuthSession.Get(ctx, id)
|
||||
if err != nil {
|
||||
return storage.AuthSession{}, convertDBError("get auth session: %w", err)
|
||||
}
|
||||
@@ -55,9 +60,10 @@ func (d *Database) ListAuthSessions(ctx context.Context) ([]storage.AuthSession,
|
||||
return storageAuthSessions, nil
|
||||
}
|
||||
|
||||
// DeleteAuthSession deletes an auth session from the database by session ID.
|
||||
func (d *Database) DeleteAuthSession(ctx context.Context, sessionID string) error {
|
||||
err := d.client.AuthSession.DeleteOneID(sessionID).Exec(ctx)
|
||||
// DeleteAuthSession deletes an auth session from the database by user ID and connector ID.
|
||||
func (d *Database) DeleteAuthSession(ctx context.Context, userID, connectorID string) error {
|
||||
id := compositeKeyID(userID, connectorID, d.hasher)
|
||||
err := d.client.AuthSession.DeleteOneID(id).Exec(ctx)
|
||||
if err != nil {
|
||||
return convertDBError("delete auth session: %w", err)
|
||||
}
|
||||
@@ -65,13 +71,14 @@ func (d *Database) DeleteAuthSession(ctx context.Context, sessionID string) erro
|
||||
}
|
||||
|
||||
// UpdateAuthSession changes an auth session using an updater function.
|
||||
func (d *Database) UpdateAuthSession(ctx context.Context, sessionID string, updater func(s storage.AuthSession) (storage.AuthSession, error)) error {
|
||||
func (d *Database) UpdateAuthSession(ctx context.Context, userID, connectorID string, updater func(s storage.AuthSession) (storage.AuthSession, error)) error {
|
||||
id := compositeKeyID(userID, connectorID, d.hasher)
|
||||
tx, err := d.BeginTx(ctx)
|
||||
if err != nil {
|
||||
return convertDBError("update auth session tx: %w", err)
|
||||
}
|
||||
|
||||
authSession, err := tx.AuthSession.Get(ctx, sessionID)
|
||||
authSession, err := tx.AuthSession.Get(ctx, id)
|
||||
if err != nil {
|
||||
return rollback(tx, "update auth session database: %w", err)
|
||||
}
|
||||
@@ -90,7 +97,7 @@ func (d *Database) UpdateAuthSession(ctx context.Context, sessionID string, upda
|
||||
return rollback(tx, "encode client states auth session: %w", err)
|
||||
}
|
||||
|
||||
_, err = tx.AuthSession.UpdateOneID(sessionID).
|
||||
_, err = tx.AuthSession.UpdateOneID(id).
|
||||
SetClientStates(encodedStates).
|
||||
SetLastActivity(newSession.LastActivity).
|
||||
SetIPAddress(newSession.IPAddress).
|
||||
|
||||
@@ -198,7 +198,9 @@ func toStorageUserIdentity(u *db.UserIdentity) storage.UserIdentity {
|
||||
|
||||
func toStorageAuthSession(s *db.AuthSession) storage.AuthSession {
|
||||
result := storage.AuthSession{
|
||||
ID: s.ID,
|
||||
UserID: s.UserID,
|
||||
ConnectorID: s.ConnectorID,
|
||||
Nonce: s.Nonce,
|
||||
CreatedAt: s.CreatedAt,
|
||||
LastActivity: s.LastActivity,
|
||||
IPAddress: s.IPAddress,
|
||||
|
||||
@@ -17,6 +17,12 @@ type AuthSession struct {
|
||||
config `json:"-"`
|
||||
// ID of the ent.
|
||||
ID string `json:"id,omitempty"`
|
||||
// UserID holds the value of the "user_id" field.
|
||||
UserID string `json:"user_id,omitempty"`
|
||||
// ConnectorID holds the value of the "connector_id" field.
|
||||
ConnectorID string `json:"connector_id,omitempty"`
|
||||
// Nonce holds the value of the "nonce" field.
|
||||
Nonce string `json:"nonce,omitempty"`
|
||||
// ClientStates holds the value of the "client_states" field.
|
||||
ClientStates []byte `json:"client_states,omitempty"`
|
||||
// CreatedAt holds the value of the "created_at" field.
|
||||
@@ -37,7 +43,7 @@ func (*AuthSession) scanValues(columns []string) ([]any, error) {
|
||||
switch columns[i] {
|
||||
case authsession.FieldClientStates:
|
||||
values[i] = new([]byte)
|
||||
case authsession.FieldID, authsession.FieldIPAddress, authsession.FieldUserAgent:
|
||||
case authsession.FieldID, authsession.FieldUserID, authsession.FieldConnectorID, authsession.FieldNonce, authsession.FieldIPAddress, authsession.FieldUserAgent:
|
||||
values[i] = new(sql.NullString)
|
||||
case authsession.FieldCreatedAt, authsession.FieldLastActivity:
|
||||
values[i] = new(sql.NullTime)
|
||||
@@ -62,6 +68,24 @@ func (_m *AuthSession) assignValues(columns []string, values []any) error {
|
||||
} else if value.Valid {
|
||||
_m.ID = value.String
|
||||
}
|
||||
case authsession.FieldUserID:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field user_id", values[i])
|
||||
} else if value.Valid {
|
||||
_m.UserID = value.String
|
||||
}
|
||||
case authsession.FieldConnectorID:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field connector_id", values[i])
|
||||
} else if value.Valid {
|
||||
_m.ConnectorID = value.String
|
||||
}
|
||||
case authsession.FieldNonce:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field nonce", values[i])
|
||||
} else if value.Valid {
|
||||
_m.Nonce = value.String
|
||||
}
|
||||
case authsession.FieldClientStates:
|
||||
if value, ok := values[i].(*[]byte); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field client_states", values[i])
|
||||
@@ -128,6 +152,15 @@ func (_m *AuthSession) String() string {
|
||||
var builder strings.Builder
|
||||
builder.WriteString("AuthSession(")
|
||||
builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID))
|
||||
builder.WriteString("user_id=")
|
||||
builder.WriteString(_m.UserID)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("connector_id=")
|
||||
builder.WriteString(_m.ConnectorID)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("nonce=")
|
||||
builder.WriteString(_m.Nonce)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("client_states=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.ClientStates))
|
||||
builder.WriteString(", ")
|
||||
|
||||
@@ -11,6 +11,12 @@ const (
|
||||
Label = "auth_session"
|
||||
// FieldID holds the string denoting the id field in the database.
|
||||
FieldID = "id"
|
||||
// FieldUserID holds the string denoting the user_id field in the database.
|
||||
FieldUserID = "user_id"
|
||||
// FieldConnectorID holds the string denoting the connector_id field in the database.
|
||||
FieldConnectorID = "connector_id"
|
||||
// FieldNonce holds the string denoting the nonce field in the database.
|
||||
FieldNonce = "nonce"
|
||||
// FieldClientStates holds the string denoting the client_states field in the database.
|
||||
FieldClientStates = "client_states"
|
||||
// FieldCreatedAt holds the string denoting the created_at field in the database.
|
||||
@@ -28,6 +34,9 @@ const (
|
||||
// Columns holds all SQL columns for authsession fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldUserID,
|
||||
FieldConnectorID,
|
||||
FieldNonce,
|
||||
FieldClientStates,
|
||||
FieldCreatedAt,
|
||||
FieldLastActivity,
|
||||
@@ -46,6 +55,12 @@ func ValidColumn(column string) bool {
|
||||
}
|
||||
|
||||
var (
|
||||
// UserIDValidator is a validator for the "user_id" field. It is called by the builders before save.
|
||||
UserIDValidator func(string) error
|
||||
// ConnectorIDValidator is a validator for the "connector_id" field. It is called by the builders before save.
|
||||
ConnectorIDValidator func(string) error
|
||||
// NonceValidator is a validator for the "nonce" field. It is called by the builders before save.
|
||||
NonceValidator func(string) error
|
||||
// DefaultIPAddress holds the default value on creation for the "ip_address" field.
|
||||
DefaultIPAddress string
|
||||
// DefaultUserAgent holds the default value on creation for the "user_agent" field.
|
||||
@@ -62,6 +77,21 @@ func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByUserID orders the results by the user_id field.
|
||||
func ByUserID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldUserID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByConnectorID orders the results by the connector_id field.
|
||||
func ByConnectorID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldConnectorID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByNonce orders the results by the nonce field.
|
||||
func ByNonce(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldNonce, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByCreatedAt orders the results by the created_at field.
|
||||
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||
|
||||
@@ -64,6 +64,21 @@ func IDContainsFold(id string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldContainsFold(FieldID, id))
|
||||
}
|
||||
|
||||
// UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ.
|
||||
func UserID(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldEQ(FieldUserID, v))
|
||||
}
|
||||
|
||||
// ConnectorID applies equality check predicate on the "connector_id" field. It's identical to ConnectorIDEQ.
|
||||
func ConnectorID(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldEQ(FieldConnectorID, v))
|
||||
}
|
||||
|
||||
// Nonce applies equality check predicate on the "nonce" field. It's identical to NonceEQ.
|
||||
func Nonce(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldEQ(FieldNonce, v))
|
||||
}
|
||||
|
||||
// ClientStates applies equality check predicate on the "client_states" field. It's identical to ClientStatesEQ.
|
||||
func ClientStates(v []byte) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldEQ(FieldClientStates, v))
|
||||
@@ -89,6 +104,201 @@ func UserAgent(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldEQ(FieldUserAgent, v))
|
||||
}
|
||||
|
||||
// UserIDEQ applies the EQ predicate on the "user_id" field.
|
||||
func UserIDEQ(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldEQ(FieldUserID, v))
|
||||
}
|
||||
|
||||
// UserIDNEQ applies the NEQ predicate on the "user_id" field.
|
||||
func UserIDNEQ(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldNEQ(FieldUserID, v))
|
||||
}
|
||||
|
||||
// UserIDIn applies the In predicate on the "user_id" field.
|
||||
func UserIDIn(vs ...string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldIn(FieldUserID, vs...))
|
||||
}
|
||||
|
||||
// UserIDNotIn applies the NotIn predicate on the "user_id" field.
|
||||
func UserIDNotIn(vs ...string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldNotIn(FieldUserID, vs...))
|
||||
}
|
||||
|
||||
// UserIDGT applies the GT predicate on the "user_id" field.
|
||||
func UserIDGT(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldGT(FieldUserID, v))
|
||||
}
|
||||
|
||||
// UserIDGTE applies the GTE predicate on the "user_id" field.
|
||||
func UserIDGTE(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldGTE(FieldUserID, v))
|
||||
}
|
||||
|
||||
// UserIDLT applies the LT predicate on the "user_id" field.
|
||||
func UserIDLT(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldLT(FieldUserID, v))
|
||||
}
|
||||
|
||||
// UserIDLTE applies the LTE predicate on the "user_id" field.
|
||||
func UserIDLTE(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldLTE(FieldUserID, v))
|
||||
}
|
||||
|
||||
// UserIDContains applies the Contains predicate on the "user_id" field.
|
||||
func UserIDContains(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldContains(FieldUserID, v))
|
||||
}
|
||||
|
||||
// UserIDHasPrefix applies the HasPrefix predicate on the "user_id" field.
|
||||
func UserIDHasPrefix(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldHasPrefix(FieldUserID, v))
|
||||
}
|
||||
|
||||
// UserIDHasSuffix applies the HasSuffix predicate on the "user_id" field.
|
||||
func UserIDHasSuffix(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldHasSuffix(FieldUserID, v))
|
||||
}
|
||||
|
||||
// UserIDEqualFold applies the EqualFold predicate on the "user_id" field.
|
||||
func UserIDEqualFold(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldEqualFold(FieldUserID, v))
|
||||
}
|
||||
|
||||
// UserIDContainsFold applies the ContainsFold predicate on the "user_id" field.
|
||||
func UserIDContainsFold(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldContainsFold(FieldUserID, v))
|
||||
}
|
||||
|
||||
// ConnectorIDEQ applies the EQ predicate on the "connector_id" field.
|
||||
func ConnectorIDEQ(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldEQ(FieldConnectorID, v))
|
||||
}
|
||||
|
||||
// ConnectorIDNEQ applies the NEQ predicate on the "connector_id" field.
|
||||
func ConnectorIDNEQ(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldNEQ(FieldConnectorID, v))
|
||||
}
|
||||
|
||||
// ConnectorIDIn applies the In predicate on the "connector_id" field.
|
||||
func ConnectorIDIn(vs ...string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldIn(FieldConnectorID, vs...))
|
||||
}
|
||||
|
||||
// ConnectorIDNotIn applies the NotIn predicate on the "connector_id" field.
|
||||
func ConnectorIDNotIn(vs ...string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldNotIn(FieldConnectorID, vs...))
|
||||
}
|
||||
|
||||
// ConnectorIDGT applies the GT predicate on the "connector_id" field.
|
||||
func ConnectorIDGT(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldGT(FieldConnectorID, v))
|
||||
}
|
||||
|
||||
// ConnectorIDGTE applies the GTE predicate on the "connector_id" field.
|
||||
func ConnectorIDGTE(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldGTE(FieldConnectorID, v))
|
||||
}
|
||||
|
||||
// ConnectorIDLT applies the LT predicate on the "connector_id" field.
|
||||
func ConnectorIDLT(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldLT(FieldConnectorID, v))
|
||||
}
|
||||
|
||||
// ConnectorIDLTE applies the LTE predicate on the "connector_id" field.
|
||||
func ConnectorIDLTE(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldLTE(FieldConnectorID, v))
|
||||
}
|
||||
|
||||
// ConnectorIDContains applies the Contains predicate on the "connector_id" field.
|
||||
func ConnectorIDContains(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldContains(FieldConnectorID, v))
|
||||
}
|
||||
|
||||
// ConnectorIDHasPrefix applies the HasPrefix predicate on the "connector_id" field.
|
||||
func ConnectorIDHasPrefix(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldHasPrefix(FieldConnectorID, v))
|
||||
}
|
||||
|
||||
// ConnectorIDHasSuffix applies the HasSuffix predicate on the "connector_id" field.
|
||||
func ConnectorIDHasSuffix(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldHasSuffix(FieldConnectorID, v))
|
||||
}
|
||||
|
||||
// ConnectorIDEqualFold applies the EqualFold predicate on the "connector_id" field.
|
||||
func ConnectorIDEqualFold(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldEqualFold(FieldConnectorID, v))
|
||||
}
|
||||
|
||||
// ConnectorIDContainsFold applies the ContainsFold predicate on the "connector_id" field.
|
||||
func ConnectorIDContainsFold(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldContainsFold(FieldConnectorID, v))
|
||||
}
|
||||
|
||||
// NonceEQ applies the EQ predicate on the "nonce" field.
|
||||
func NonceEQ(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldEQ(FieldNonce, v))
|
||||
}
|
||||
|
||||
// NonceNEQ applies the NEQ predicate on the "nonce" field.
|
||||
func NonceNEQ(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldNEQ(FieldNonce, v))
|
||||
}
|
||||
|
||||
// NonceIn applies the In predicate on the "nonce" field.
|
||||
func NonceIn(vs ...string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldIn(FieldNonce, vs...))
|
||||
}
|
||||
|
||||
// NonceNotIn applies the NotIn predicate on the "nonce" field.
|
||||
func NonceNotIn(vs ...string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldNotIn(FieldNonce, vs...))
|
||||
}
|
||||
|
||||
// NonceGT applies the GT predicate on the "nonce" field.
|
||||
func NonceGT(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldGT(FieldNonce, v))
|
||||
}
|
||||
|
||||
// NonceGTE applies the GTE predicate on the "nonce" field.
|
||||
func NonceGTE(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldGTE(FieldNonce, v))
|
||||
}
|
||||
|
||||
// NonceLT applies the LT predicate on the "nonce" field.
|
||||
func NonceLT(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldLT(FieldNonce, v))
|
||||
}
|
||||
|
||||
// NonceLTE applies the LTE predicate on the "nonce" field.
|
||||
func NonceLTE(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldLTE(FieldNonce, v))
|
||||
}
|
||||
|
||||
// NonceContains applies the Contains predicate on the "nonce" field.
|
||||
func NonceContains(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldContains(FieldNonce, v))
|
||||
}
|
||||
|
||||
// NonceHasPrefix applies the HasPrefix predicate on the "nonce" field.
|
||||
func NonceHasPrefix(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldHasPrefix(FieldNonce, v))
|
||||
}
|
||||
|
||||
// NonceHasSuffix applies the HasSuffix predicate on the "nonce" field.
|
||||
func NonceHasSuffix(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldHasSuffix(FieldNonce, v))
|
||||
}
|
||||
|
||||
// NonceEqualFold applies the EqualFold predicate on the "nonce" field.
|
||||
func NonceEqualFold(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldEqualFold(FieldNonce, v))
|
||||
}
|
||||
|
||||
// NonceContainsFold applies the ContainsFold predicate on the "nonce" field.
|
||||
func NonceContainsFold(v string) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldContainsFold(FieldNonce, v))
|
||||
}
|
||||
|
||||
// ClientStatesEQ applies the EQ predicate on the "client_states" field.
|
||||
func ClientStatesEQ(v []byte) predicate.AuthSession {
|
||||
return predicate.AuthSession(sql.FieldEQ(FieldClientStates, v))
|
||||
|
||||
@@ -20,6 +20,24 @@ type AuthSessionCreate struct {
|
||||
hooks []Hook
|
||||
}
|
||||
|
||||
// SetUserID sets the "user_id" field.
|
||||
func (_c *AuthSessionCreate) SetUserID(v string) *AuthSessionCreate {
|
||||
_c.mutation.SetUserID(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetConnectorID sets the "connector_id" field.
|
||||
func (_c *AuthSessionCreate) SetConnectorID(v string) *AuthSessionCreate {
|
||||
_c.mutation.SetConnectorID(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetNonce sets the "nonce" field.
|
||||
func (_c *AuthSessionCreate) SetNonce(v string) *AuthSessionCreate {
|
||||
_c.mutation.SetNonce(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetClientStates sets the "client_states" field.
|
||||
func (_c *AuthSessionCreate) SetClientStates(v []byte) *AuthSessionCreate {
|
||||
_c.mutation.SetClientStates(v)
|
||||
@@ -119,6 +137,30 @@ func (_c *AuthSessionCreate) defaults() {
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (_c *AuthSessionCreate) check() error {
|
||||
if _, ok := _c.mutation.UserID(); !ok {
|
||||
return &ValidationError{Name: "user_id", err: errors.New(`db: missing required field "AuthSession.user_id"`)}
|
||||
}
|
||||
if v, ok := _c.mutation.UserID(); ok {
|
||||
if err := authsession.UserIDValidator(v); err != nil {
|
||||
return &ValidationError{Name: "user_id", err: fmt.Errorf(`db: validator failed for field "AuthSession.user_id": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := _c.mutation.ConnectorID(); !ok {
|
||||
return &ValidationError{Name: "connector_id", err: errors.New(`db: missing required field "AuthSession.connector_id"`)}
|
||||
}
|
||||
if v, ok := _c.mutation.ConnectorID(); ok {
|
||||
if err := authsession.ConnectorIDValidator(v); err != nil {
|
||||
return &ValidationError{Name: "connector_id", err: fmt.Errorf(`db: validator failed for field "AuthSession.connector_id": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := _c.mutation.Nonce(); !ok {
|
||||
return &ValidationError{Name: "nonce", err: errors.New(`db: missing required field "AuthSession.nonce"`)}
|
||||
}
|
||||
if v, ok := _c.mutation.Nonce(); ok {
|
||||
if err := authsession.NonceValidator(v); err != nil {
|
||||
return &ValidationError{Name: "nonce", err: fmt.Errorf(`db: validator failed for field "AuthSession.nonce": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := _c.mutation.ClientStates(); !ok {
|
||||
return &ValidationError{Name: "client_states", err: errors.New(`db: missing required field "AuthSession.client_states"`)}
|
||||
}
|
||||
@@ -174,6 +216,18 @@ func (_c *AuthSessionCreate) createSpec() (*AuthSession, *sqlgraph.CreateSpec) {
|
||||
_node.ID = id
|
||||
_spec.ID.Value = id
|
||||
}
|
||||
if value, ok := _c.mutation.UserID(); ok {
|
||||
_spec.SetField(authsession.FieldUserID, field.TypeString, value)
|
||||
_node.UserID = value
|
||||
}
|
||||
if value, ok := _c.mutation.ConnectorID(); ok {
|
||||
_spec.SetField(authsession.FieldConnectorID, field.TypeString, value)
|
||||
_node.ConnectorID = value
|
||||
}
|
||||
if value, ok := _c.mutation.Nonce(); ok {
|
||||
_spec.SetField(authsession.FieldNonce, field.TypeString, value)
|
||||
_node.Nonce = value
|
||||
}
|
||||
if value, ok := _c.mutation.ClientStates(); ok {
|
||||
_spec.SetField(authsession.FieldClientStates, field.TypeBytes, value)
|
||||
_node.ClientStates = value
|
||||
|
||||
@@ -262,12 +262,12 @@ func (_q *AuthSessionQuery) Clone() *AuthSessionQuery {
|
||||
// Example:
|
||||
//
|
||||
// var v []struct {
|
||||
// ClientStates []byte `json:"client_states,omitempty"`
|
||||
// UserID string `json:"user_id,omitempty"`
|
||||
// Count int `json:"count,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.AuthSession.Query().
|
||||
// GroupBy(authsession.FieldClientStates).
|
||||
// GroupBy(authsession.FieldUserID).
|
||||
// Aggregate(db.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (_q *AuthSessionQuery) GroupBy(field string, fields ...string) *AuthSessionGroupBy {
|
||||
@@ -285,11 +285,11 @@ func (_q *AuthSessionQuery) GroupBy(field string, fields ...string) *AuthSession
|
||||
// Example:
|
||||
//
|
||||
// var v []struct {
|
||||
// ClientStates []byte `json:"client_states,omitempty"`
|
||||
// UserID string `json:"user_id,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.AuthSession.Query().
|
||||
// Select(authsession.FieldClientStates).
|
||||
// Select(authsession.FieldUserID).
|
||||
// Scan(ctx, &v)
|
||||
func (_q *AuthSessionQuery) Select(fields ...string) *AuthSessionSelect {
|
||||
_q.ctx.Fields = append(_q.ctx.Fields, fields...)
|
||||
|
||||
@@ -28,6 +28,48 @@ func (_u *AuthSessionUpdate) Where(ps ...predicate.AuthSession) *AuthSessionUpda
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetUserID sets the "user_id" field.
|
||||
func (_u *AuthSessionUpdate) SetUserID(v string) *AuthSessionUpdate {
|
||||
_u.mutation.SetUserID(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableUserID sets the "user_id" field if the given value is not nil.
|
||||
func (_u *AuthSessionUpdate) SetNillableUserID(v *string) *AuthSessionUpdate {
|
||||
if v != nil {
|
||||
_u.SetUserID(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetConnectorID sets the "connector_id" field.
|
||||
func (_u *AuthSessionUpdate) SetConnectorID(v string) *AuthSessionUpdate {
|
||||
_u.mutation.SetConnectorID(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableConnectorID sets the "connector_id" field if the given value is not nil.
|
||||
func (_u *AuthSessionUpdate) SetNillableConnectorID(v *string) *AuthSessionUpdate {
|
||||
if v != nil {
|
||||
_u.SetConnectorID(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNonce sets the "nonce" field.
|
||||
func (_u *AuthSessionUpdate) SetNonce(v string) *AuthSessionUpdate {
|
||||
_u.mutation.SetNonce(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableNonce sets the "nonce" field if the given value is not nil.
|
||||
func (_u *AuthSessionUpdate) SetNillableNonce(v *string) *AuthSessionUpdate {
|
||||
if v != nil {
|
||||
_u.SetNonce(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetClientStates sets the "client_states" field.
|
||||
func (_u *AuthSessionUpdate) SetClientStates(v []byte) *AuthSessionUpdate {
|
||||
_u.mutation.SetClientStates(v)
|
||||
@@ -122,7 +164,30 @@ func (_u *AuthSessionUpdate) ExecX(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (_u *AuthSessionUpdate) check() error {
|
||||
if v, ok := _u.mutation.UserID(); ok {
|
||||
if err := authsession.UserIDValidator(v); err != nil {
|
||||
return &ValidationError{Name: "user_id", err: fmt.Errorf(`db: validator failed for field "AuthSession.user_id": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.ConnectorID(); ok {
|
||||
if err := authsession.ConnectorIDValidator(v); err != nil {
|
||||
return &ValidationError{Name: "connector_id", err: fmt.Errorf(`db: validator failed for field "AuthSession.connector_id": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.Nonce(); ok {
|
||||
if err := authsession.NonceValidator(v); err != nil {
|
||||
return &ValidationError{Name: "nonce", err: fmt.Errorf(`db: validator failed for field "AuthSession.nonce": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_u *AuthSessionUpdate) sqlSave(ctx context.Context) (_node int, err error) {
|
||||
if err := _u.check(); err != nil {
|
||||
return _node, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(authsession.Table, authsession.Columns, sqlgraph.NewFieldSpec(authsession.FieldID, field.TypeString))
|
||||
if ps := _u.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
@@ -131,6 +196,15 @@ func (_u *AuthSessionUpdate) sqlSave(ctx context.Context) (_node int, err error)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := _u.mutation.UserID(); ok {
|
||||
_spec.SetField(authsession.FieldUserID, field.TypeString, value)
|
||||
}
|
||||
if value, ok := _u.mutation.ConnectorID(); ok {
|
||||
_spec.SetField(authsession.FieldConnectorID, field.TypeString, value)
|
||||
}
|
||||
if value, ok := _u.mutation.Nonce(); ok {
|
||||
_spec.SetField(authsession.FieldNonce, field.TypeString, value)
|
||||
}
|
||||
if value, ok := _u.mutation.ClientStates(); ok {
|
||||
_spec.SetField(authsession.FieldClientStates, field.TypeBytes, value)
|
||||
}
|
||||
@@ -166,6 +240,48 @@ type AuthSessionUpdateOne struct {
|
||||
mutation *AuthSessionMutation
|
||||
}
|
||||
|
||||
// SetUserID sets the "user_id" field.
|
||||
func (_u *AuthSessionUpdateOne) SetUserID(v string) *AuthSessionUpdateOne {
|
||||
_u.mutation.SetUserID(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableUserID sets the "user_id" field if the given value is not nil.
|
||||
func (_u *AuthSessionUpdateOne) SetNillableUserID(v *string) *AuthSessionUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetUserID(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetConnectorID sets the "connector_id" field.
|
||||
func (_u *AuthSessionUpdateOne) SetConnectorID(v string) *AuthSessionUpdateOne {
|
||||
_u.mutation.SetConnectorID(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableConnectorID sets the "connector_id" field if the given value is not nil.
|
||||
func (_u *AuthSessionUpdateOne) SetNillableConnectorID(v *string) *AuthSessionUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetConnectorID(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNonce sets the "nonce" field.
|
||||
func (_u *AuthSessionUpdateOne) SetNonce(v string) *AuthSessionUpdateOne {
|
||||
_u.mutation.SetNonce(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableNonce sets the "nonce" field if the given value is not nil.
|
||||
func (_u *AuthSessionUpdateOne) SetNillableNonce(v *string) *AuthSessionUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetNonce(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetClientStates sets the "client_states" field.
|
||||
func (_u *AuthSessionUpdateOne) SetClientStates(v []byte) *AuthSessionUpdateOne {
|
||||
_u.mutation.SetClientStates(v)
|
||||
@@ -273,7 +389,30 @@ func (_u *AuthSessionUpdateOne) ExecX(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (_u *AuthSessionUpdateOne) check() error {
|
||||
if v, ok := _u.mutation.UserID(); ok {
|
||||
if err := authsession.UserIDValidator(v); err != nil {
|
||||
return &ValidationError{Name: "user_id", err: fmt.Errorf(`db: validator failed for field "AuthSession.user_id": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.ConnectorID(); ok {
|
||||
if err := authsession.ConnectorIDValidator(v); err != nil {
|
||||
return &ValidationError{Name: "connector_id", err: fmt.Errorf(`db: validator failed for field "AuthSession.connector_id": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.Nonce(); ok {
|
||||
if err := authsession.NonceValidator(v); err != nil {
|
||||
return &ValidationError{Name: "nonce", err: fmt.Errorf(`db: validator failed for field "AuthSession.nonce": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_u *AuthSessionUpdateOne) sqlSave(ctx context.Context) (_node *AuthSession, err error) {
|
||||
if err := _u.check(); err != nil {
|
||||
return _node, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(authsession.Table, authsession.Columns, sqlgraph.NewFieldSpec(authsession.FieldID, field.TypeString))
|
||||
id, ok := _u.mutation.ID()
|
||||
if !ok {
|
||||
@@ -299,6 +438,15 @@ func (_u *AuthSessionUpdateOne) sqlSave(ctx context.Context) (_node *AuthSession
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := _u.mutation.UserID(); ok {
|
||||
_spec.SetField(authsession.FieldUserID, field.TypeString, value)
|
||||
}
|
||||
if value, ok := _u.mutation.ConnectorID(); ok {
|
||||
_spec.SetField(authsession.FieldConnectorID, field.TypeString, value)
|
||||
}
|
||||
if value, ok := _u.mutation.Nonce(); ok {
|
||||
_spec.SetField(authsession.FieldNonce, field.TypeString, value)
|
||||
}
|
||||
if value, ok := _u.mutation.ClientStates(); ok {
|
||||
_spec.SetField(authsession.FieldClientStates, field.TypeBytes, value)
|
||||
}
|
||||
|
||||
@@ -66,6 +66,9 @@ var (
|
||||
// AuthSessionsColumns holds the columns for the "auth_sessions" table.
|
||||
AuthSessionsColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeString, Unique: true, Size: 2147483647, SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}},
|
||||
{Name: "user_id", Type: field.TypeString, Size: 2147483647, SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}},
|
||||
{Name: "connector_id", Type: field.TypeString, Size: 2147483647, SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}},
|
||||
{Name: "nonce", Type: field.TypeString, Size: 2147483647, SchemaType: map[string]string{"mysql": "varchar(384)", "postgres": "text", "sqlite3": "text"}},
|
||||
{Name: "client_states", Type: field.TypeBytes},
|
||||
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"mysql": "datetime(3)", "postgres": "timestamptz", "sqlite3": "timestamp"}},
|
||||
{Name: "last_activity", Type: field.TypeTime, SchemaType: map[string]string{"mysql": "datetime(3)", "postgres": "timestamptz", "sqlite3": "timestamp"}},
|
||||
|
||||
+163
-1
@@ -2727,6 +2727,9 @@ type AuthSessionMutation struct {
|
||||
op Op
|
||||
typ string
|
||||
id *string
|
||||
user_id *string
|
||||
connector_id *string
|
||||
nonce *string
|
||||
client_states *[]byte
|
||||
created_at *time.Time
|
||||
last_activity *time.Time
|
||||
@@ -2842,6 +2845,114 @@ func (m *AuthSessionMutation) IDs(ctx context.Context) ([]string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// SetUserID sets the "user_id" field.
|
||||
func (m *AuthSessionMutation) SetUserID(s string) {
|
||||
m.user_id = &s
|
||||
}
|
||||
|
||||
// UserID returns the value of the "user_id" field in the mutation.
|
||||
func (m *AuthSessionMutation) UserID() (r string, exists bool) {
|
||||
v := m.user_id
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldUserID returns the old "user_id" field's value of the AuthSession entity.
|
||||
// If the AuthSession object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *AuthSessionMutation) OldUserID(ctx context.Context) (v string, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldUserID is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
return v, errors.New("OldUserID requires an ID field in the mutation")
|
||||
}
|
||||
oldValue, err := m.oldValue(ctx)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("querying old value for OldUserID: %w", err)
|
||||
}
|
||||
return oldValue.UserID, nil
|
||||
}
|
||||
|
||||
// ResetUserID resets all changes to the "user_id" field.
|
||||
func (m *AuthSessionMutation) ResetUserID() {
|
||||
m.user_id = nil
|
||||
}
|
||||
|
||||
// SetConnectorID sets the "connector_id" field.
|
||||
func (m *AuthSessionMutation) SetConnectorID(s string) {
|
||||
m.connector_id = &s
|
||||
}
|
||||
|
||||
// ConnectorID returns the value of the "connector_id" field in the mutation.
|
||||
func (m *AuthSessionMutation) ConnectorID() (r string, exists bool) {
|
||||
v := m.connector_id
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldConnectorID returns the old "connector_id" field's value of the AuthSession entity.
|
||||
// If the AuthSession object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *AuthSessionMutation) OldConnectorID(ctx context.Context) (v string, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldConnectorID is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
return v, errors.New("OldConnectorID requires an ID field in the mutation")
|
||||
}
|
||||
oldValue, err := m.oldValue(ctx)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("querying old value for OldConnectorID: %w", err)
|
||||
}
|
||||
return oldValue.ConnectorID, nil
|
||||
}
|
||||
|
||||
// ResetConnectorID resets all changes to the "connector_id" field.
|
||||
func (m *AuthSessionMutation) ResetConnectorID() {
|
||||
m.connector_id = nil
|
||||
}
|
||||
|
||||
// SetNonce sets the "nonce" field.
|
||||
func (m *AuthSessionMutation) SetNonce(s string) {
|
||||
m.nonce = &s
|
||||
}
|
||||
|
||||
// Nonce returns the value of the "nonce" field in the mutation.
|
||||
func (m *AuthSessionMutation) Nonce() (r string, exists bool) {
|
||||
v := m.nonce
|
||||
if v == nil {
|
||||
return
|
||||
}
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// OldNonce returns the old "nonce" field's value of the AuthSession entity.
|
||||
// If the AuthSession object wasn't provided to the builder, the object is fetched from the database.
|
||||
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||
func (m *AuthSessionMutation) OldNonce(ctx context.Context) (v string, err error) {
|
||||
if !m.op.Is(OpUpdateOne) {
|
||||
return v, errors.New("OldNonce is only allowed on UpdateOne operations")
|
||||
}
|
||||
if m.id == nil || m.oldValue == nil {
|
||||
return v, errors.New("OldNonce requires an ID field in the mutation")
|
||||
}
|
||||
oldValue, err := m.oldValue(ctx)
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("querying old value for OldNonce: %w", err)
|
||||
}
|
||||
return oldValue.Nonce, nil
|
||||
}
|
||||
|
||||
// ResetNonce resets all changes to the "nonce" field.
|
||||
func (m *AuthSessionMutation) ResetNonce() {
|
||||
m.nonce = nil
|
||||
}
|
||||
|
||||
// SetClientStates sets the "client_states" field.
|
||||
func (m *AuthSessionMutation) SetClientStates(b []byte) {
|
||||
m.client_states = &b
|
||||
@@ -3056,7 +3167,16 @@ func (m *AuthSessionMutation) Type() string {
|
||||
// order to get all numeric fields that were incremented/decremented, call
|
||||
// AddedFields().
|
||||
func (m *AuthSessionMutation) Fields() []string {
|
||||
fields := make([]string, 0, 5)
|
||||
fields := make([]string, 0, 8)
|
||||
if m.user_id != nil {
|
||||
fields = append(fields, authsession.FieldUserID)
|
||||
}
|
||||
if m.connector_id != nil {
|
||||
fields = append(fields, authsession.FieldConnectorID)
|
||||
}
|
||||
if m.nonce != nil {
|
||||
fields = append(fields, authsession.FieldNonce)
|
||||
}
|
||||
if m.client_states != nil {
|
||||
fields = append(fields, authsession.FieldClientStates)
|
||||
}
|
||||
@@ -3080,6 +3200,12 @@ func (m *AuthSessionMutation) Fields() []string {
|
||||
// schema.
|
||||
func (m *AuthSessionMutation) Field(name string) (ent.Value, bool) {
|
||||
switch name {
|
||||
case authsession.FieldUserID:
|
||||
return m.UserID()
|
||||
case authsession.FieldConnectorID:
|
||||
return m.ConnectorID()
|
||||
case authsession.FieldNonce:
|
||||
return m.Nonce()
|
||||
case authsession.FieldClientStates:
|
||||
return m.ClientStates()
|
||||
case authsession.FieldCreatedAt:
|
||||
@@ -3099,6 +3225,12 @@ func (m *AuthSessionMutation) Field(name string) (ent.Value, bool) {
|
||||
// database failed.
|
||||
func (m *AuthSessionMutation) OldField(ctx context.Context, name string) (ent.Value, error) {
|
||||
switch name {
|
||||
case authsession.FieldUserID:
|
||||
return m.OldUserID(ctx)
|
||||
case authsession.FieldConnectorID:
|
||||
return m.OldConnectorID(ctx)
|
||||
case authsession.FieldNonce:
|
||||
return m.OldNonce(ctx)
|
||||
case authsession.FieldClientStates:
|
||||
return m.OldClientStates(ctx)
|
||||
case authsession.FieldCreatedAt:
|
||||
@@ -3118,6 +3250,27 @@ func (m *AuthSessionMutation) OldField(ctx context.Context, name string) (ent.Va
|
||||
// type.
|
||||
func (m *AuthSessionMutation) SetField(name string, value ent.Value) error {
|
||||
switch name {
|
||||
case authsession.FieldUserID:
|
||||
v, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetUserID(v)
|
||||
return nil
|
||||
case authsession.FieldConnectorID:
|
||||
v, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetConnectorID(v)
|
||||
return nil
|
||||
case authsession.FieldNonce:
|
||||
v, ok := value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||
}
|
||||
m.SetNonce(v)
|
||||
return nil
|
||||
case authsession.FieldClientStates:
|
||||
v, ok := value.([]byte)
|
||||
if !ok {
|
||||
@@ -3202,6 +3355,15 @@ func (m *AuthSessionMutation) ClearField(name string) error {
|
||||
// It returns an error if the field is not defined in the schema.
|
||||
func (m *AuthSessionMutation) ResetField(name string) error {
|
||||
switch name {
|
||||
case authsession.FieldUserID:
|
||||
m.ResetUserID()
|
||||
return nil
|
||||
case authsession.FieldConnectorID:
|
||||
m.ResetConnectorID()
|
||||
return nil
|
||||
case authsession.FieldNonce:
|
||||
m.ResetNonce()
|
||||
return nil
|
||||
case authsession.FieldClientStates:
|
||||
m.ResetClientStates()
|
||||
return nil
|
||||
|
||||
@@ -90,12 +90,24 @@ func init() {
|
||||
authrequest.IDValidator = authrequestDescID.Validators[0].(func(string) error)
|
||||
authsessionFields := schema.AuthSession{}.Fields()
|
||||
_ = authsessionFields
|
||||
// authsessionDescUserID is the schema descriptor for user_id field.
|
||||
authsessionDescUserID := authsessionFields[1].Descriptor()
|
||||
// authsession.UserIDValidator is a validator for the "user_id" field. It is called by the builders before save.
|
||||
authsession.UserIDValidator = authsessionDescUserID.Validators[0].(func(string) error)
|
||||
// authsessionDescConnectorID is the schema descriptor for connector_id field.
|
||||
authsessionDescConnectorID := authsessionFields[2].Descriptor()
|
||||
// authsession.ConnectorIDValidator is a validator for the "connector_id" field. It is called by the builders before save.
|
||||
authsession.ConnectorIDValidator = authsessionDescConnectorID.Validators[0].(func(string) error)
|
||||
// authsessionDescNonce is the schema descriptor for nonce field.
|
||||
authsessionDescNonce := authsessionFields[3].Descriptor()
|
||||
// authsession.NonceValidator is a validator for the "nonce" field. It is called by the builders before save.
|
||||
authsession.NonceValidator = authsessionDescNonce.Validators[0].(func(string) error)
|
||||
// authsessionDescIPAddress is the schema descriptor for ip_address field.
|
||||
authsessionDescIPAddress := authsessionFields[4].Descriptor()
|
||||
authsessionDescIPAddress := authsessionFields[7].Descriptor()
|
||||
// authsession.DefaultIPAddress holds the default value on creation for the ip_address field.
|
||||
authsession.DefaultIPAddress = authsessionDescIPAddress.Default.(string)
|
||||
// authsessionDescUserAgent is the schema descriptor for user_agent field.
|
||||
authsessionDescUserAgent := authsessionFields[5].Descriptor()
|
||||
authsessionDescUserAgent := authsessionFields[8].Descriptor()
|
||||
// authsession.DefaultUserAgent holds the default value on creation for the user_agent field.
|
||||
authsession.DefaultUserAgent = authsessionDescUserAgent.Default.(string)
|
||||
// authsessionDescID is the schema descriptor for id field.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user