github.com/argoproj/argo-cd/v2@v2.10.9/reposerver/askpass/server.go (about)

     1  package askpass
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  	"os"
     7  	"sync"
     8  
     9  	"github.com/google/uuid"
    10  	"google.golang.org/grpc"
    11  	"google.golang.org/grpc/codes"
    12  	"google.golang.org/grpc/status"
    13  
    14  	"github.com/argoproj/argo-cd/v2/util/git"
    15  	"github.com/argoproj/argo-cd/v2/util/io"
    16  )
    17  
    18  type Server interface {
    19  	git.CredsStore
    20  	AskPassServiceServer
    21  	Run(path string) error
    22  }
    23  
    24  type server struct {
    25  	lock  sync.Mutex
    26  	creds map[string]Creds
    27  }
    28  
    29  // NewServer returns a new server
    30  func NewServer() *server {
    31  	return &server{
    32  		creds: make(map[string]Creds),
    33  	}
    34  }
    35  
    36  func (s *server) GetCredentials(_ context.Context, q *CredentialsRequest) (*CredentialsResponse, error) {
    37  	if q.Nonce == "" {
    38  		return nil, status.Errorf(codes.InvalidArgument, "missing nonce")
    39  	}
    40  	creds, ok := s.getCreds(q.Nonce)
    41  	if !ok {
    42  		return nil, status.Errorf(codes.NotFound, "unknown nonce")
    43  	}
    44  	return &CredentialsResponse{Username: creds.Username, Password: creds.Password}, nil
    45  }
    46  
    47  func (s *server) Start(path string) (io.Closer, error) {
    48  	_ = os.Remove(path)
    49  	listener, err := net.Listen("unix", path)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  	server := grpc.NewServer()
    54  	RegisterAskPassServiceServer(server, s)
    55  	go func() {
    56  		_ = server.Serve(listener)
    57  	}()
    58  	return io.NewCloser(listener.Close), nil
    59  }
    60  
    61  func (s *server) Run(path string) error {
    62  	_, err := s.Start(path)
    63  	return err
    64  }
    65  
    66  // Add adds a new credential to the server and returns associated id
    67  func (s *server) Add(username string, password string) string {
    68  	s.lock.Lock()
    69  	defer s.lock.Unlock()
    70  	id := uuid.New().String()
    71  	s.creds[id] = Creds{
    72  		Username: username,
    73  		Password: password,
    74  	}
    75  	return id
    76  }
    77  
    78  // Remove removes the credential with the given id
    79  func (s *server) Remove(id string) {
    80  	s.lock.Lock()
    81  	defer s.lock.Unlock()
    82  	delete(s.creds, id)
    83  }
    84  
    85  func (s *server) getCreds(id string) (*Creds, bool) {
    86  	s.lock.Lock()
    87  	defer s.lock.Unlock()
    88  	creds, ok := s.creds[id]
    89  	return &creds, ok
    90  }