github.com/argoproj/argo-cd@v1.8.7/server/session/session.go (about)

     1  package session
     2  
     3  import (
     4  	"context"
     5  
     6  	"google.golang.org/grpc/codes"
     7  	"google.golang.org/grpc/status"
     8  
     9  	"github.com/argoproj/argo-cd/pkg/apiclient/session"
    10  	"github.com/argoproj/argo-cd/server/rbacpolicy"
    11  	util "github.com/argoproj/argo-cd/util/io"
    12  	sessionmgr "github.com/argoproj/argo-cd/util/session"
    13  )
    14  
    15  // Server provides a Session service
    16  type Server struct {
    17  	mgr                *sessionmgr.SessionManager
    18  	authenticator      Authenticator
    19  	policyEnf          *rbacpolicy.RBACPolicyEnforcer
    20  	limitLoginAttempts func() (util.Closer, error)
    21  }
    22  
    23  type Authenticator interface {
    24  	Authenticate(ctx context.Context) (context.Context, error)
    25  }
    26  
    27  // NewServer returns a new instance of the Session service
    28  func NewServer(mgr *sessionmgr.SessionManager, authenticator Authenticator, policyEnf *rbacpolicy.RBACPolicyEnforcer, rateLimiter func() (util.Closer, error)) *Server {
    29  	return &Server{mgr, authenticator, policyEnf, rateLimiter}
    30  }
    31  
    32  // Create generates a JWT token signed by Argo CD intended for web/CLI logins of the admin user
    33  // using username/password
    34  func (s *Server) Create(_ context.Context, q *session.SessionCreateRequest) (*session.SessionResponse, error) {
    35  	if s.limitLoginAttempts != nil {
    36  		closer, err := s.limitLoginAttempts()
    37  		if err != nil {
    38  			return nil, err
    39  		}
    40  		defer util.Close(closer)
    41  	}
    42  
    43  	if q.Token != "" {
    44  		return nil, status.Errorf(codes.Unauthenticated, "token-based session creation no longer supported. please upgrade argocd cli to v0.7+")
    45  	}
    46  	if q.Username == "" || q.Password == "" {
    47  		return nil, status.Errorf(codes.Unauthenticated, "no credentials supplied")
    48  	}
    49  	err := s.mgr.VerifyUsernamePassword(q.Username, q.Password)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  	jwtToken, err := s.mgr.Create(q.Username, 0, "")
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  	return &session.SessionResponse{Token: jwtToken}, nil
    58  }
    59  
    60  // Delete an authentication cookie from the client.  This makes sense only for the Web client.
    61  func (s *Server) Delete(ctx context.Context, q *session.SessionDeleteRequest) (*session.SessionResponse, error) {
    62  	return &session.SessionResponse{Token: ""}, nil
    63  }
    64  
    65  // AuthFuncOverride overrides the authentication function and let us not require auth to receive auth.
    66  // Without this function here, ArgoCDServer.authenticate would be invoked and credentials checked.
    67  // Since this service is generally invoked when the user has _no_ credentials, that would create a
    68  // chicken-and-egg situation if we didn't place this here to allow traffic to pass through.
    69  func (s *Server) AuthFuncOverride(ctx context.Context, fullMethodName string) (context.Context, error) {
    70  	// this authenticates the user, but ignores any error, so that we have claims populated
    71  	ctx, _ = s.authenticator.Authenticate(ctx)
    72  	return ctx, nil
    73  }
    74  
    75  func (s *Server) GetUserInfo(ctx context.Context, q *session.GetUserInfoRequest) (*session.GetUserInfoResponse, error) {
    76  	return &session.GetUserInfoResponse{
    77  		LoggedIn: sessionmgr.LoggedIn(ctx),
    78  		Username: sessionmgr.Username(ctx),
    79  		Iss:      sessionmgr.Iss(ctx),
    80  		Groups:   sessionmgr.Groups(ctx, s.policyEnf.GetScopes()),
    81  	}, nil
    82  }