github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/security/ticket/helper.go (about)

     1  package ticket
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strings"
     7  	"v.io/v23/context"
     8  )
     9  
    10  // An UnexpectedTicketType error is produced when a ticket cannot be cast to the expected type.
    11  type UnexpectedTicketType struct {
    12  	Expected string
    13  	Actual   string
    14  }
    15  
    16  func (err UnexpectedTicketType) Error() string {
    17  	return fmt.Sprintf("ticket was a %q, not a %q", err.Actual, err.Expected)
    18  }
    19  
    20  func expected(expected interface{}, actual interface{}) UnexpectedTicketType {
    21  	return UnexpectedTicketType{
    22  		Expected: reflect.TypeOf(expected).Name(),
    23  		Actual:   reflect.TypeOf(actual).Name(),
    24  	}
    25  }
    26  
    27  // A Getter retrieves a ticket value for the key.
    28  //
    29  // Users of this package should use the default Client.
    30  // This type exists primarily for unit tests which do not rely on the ticket-server.
    31  type Getter func(ctx *context.T, key string) (Ticket, error)
    32  
    33  /*
    34  Client is the default Getter which uses Vanadium to interact with the ticket-server.
    35  
    36  For example, to get a string value:
    37  
    38    myValue, err := ticket.Client.GetString(ctx, "ticket/path")
    39  */
    40  var Client Getter = func(ctx *context.T, key string) (Ticket, error) {
    41  	return TicketServiceClient(key).Get(ctx)
    42  }
    43  
    44  func (g Getter) getTicket(ctx *context.T, path ...string) (Ticket, error) {
    45  	key := strings.Join(path, "/")
    46  	return g(ctx, key)
    47  }
    48  
    49  // GetData for key from the ticket-server. It must be stored in a GenericTicket.
    50  // Path components will be joined with a `/`.
    51  func (g Getter) GetData(ctx *context.T, path ...string) (data []byte, err error) {
    52  	tick, err := g.getTicket(ctx, path...)
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	cast, ok := tick.(TicketGenericTicket)
    58  	if !ok {
    59  		return nil, expected(TicketGenericTicket{}, tick)
    60  	}
    61  
    62  	return cast.Value.Data, nil
    63  }
    64  
    65  // GetString for key from the ticket-server. It must be stored in a GenericTicket.
    66  // Path components will be joined with a `/`.
    67  func (g Getter) GetString(ctx *context.T, path ...string) (value string, err error) {
    68  	data, err := g.GetData(ctx, path...)
    69  	if err != nil {
    70  		return "", err
    71  	}
    72  
    73  	return string(data), nil
    74  }
    75  
    76  // GetAws credentials and helpers for key from the ticket-server.
    77  // Path components will be joined with a `/`.
    78  func (g Getter) GetAws(ctx *context.T, path ...string) (aws AwsTicket, err error) {
    79  	tick, err := g.getTicket(ctx, path...)
    80  	if err != nil {
    81  		return aws, err
    82  	}
    83  
    84  	cast, ok := tick.(TicketAwsTicket)
    85  	if !ok {
    86  		return aws, expected(TicketAwsTicket{}, cast)
    87  	}
    88  
    89  	return cast.Value, nil
    90  }
    91  
    92  // GetS3 credentials and helpers for key from the ticket-server.
    93  // Path components will be joined with a `/`.
    94  func (g Getter) GetS3(ctx *context.T, path ...string) (S3 S3Ticket, err error) {
    95  	tick, err := g.getTicket(ctx, path...)
    96  	if err != nil {
    97  		return S3, err
    98  	}
    99  
   100  	cast, ok := tick.(TicketS3Ticket)
   101  	if !ok {
   102  		return S3, expected(TicketS3Ticket{}, cast)
   103  	}
   104  
   105  	return cast.Value, nil
   106  }
   107  
   108  // GetSshCertificate for key from the ticket-server.
   109  // Path components will be joined with a `/`.
   110  func (g Getter) GetSshCertificate(ctx *context.T, path ...string) (SshCertificate SshCertificateTicket, err error) {
   111  	tick, err := g.getTicket(ctx, path...)
   112  	if err != nil {
   113  		return SshCertificate, err
   114  	}
   115  
   116  	cast, ok := tick.(TicketSshCertificateTicket)
   117  	if !ok {
   118  		return SshCertificate, expected(TicketSshCertificateTicket{}, cast)
   119  	}
   120  
   121  	return cast.Value, nil
   122  }
   123  
   124  // GetEcr endpoint and helpers for key from the ticket-server.
   125  // Path components will be joined with a `/`.
   126  func (g Getter) GetEcr(ctx *context.T, path ...string) (Ecr EcrTicket, err error) {
   127  	tick, err := g.getTicket(ctx, path...)
   128  	if err != nil {
   129  		return Ecr, err
   130  	}
   131  
   132  	cast, ok := tick.(TicketEcrTicket)
   133  	if !ok {
   134  		return Ecr, expected(TicketEcrTicket{}, cast)
   135  	}
   136  
   137  	return cast.Value, nil
   138  }
   139  
   140  // GetTlsServer credentials and helpers for key from the ticket-server.
   141  // Path components will be joined with a `/`.
   142  func (g Getter) GetTlsServer(ctx *context.T, path ...string) (TlsServer TlsServerTicket, err error) {
   143  	tick, err := g.getTicket(ctx, path...)
   144  	if err != nil {
   145  		return TlsServer, err
   146  	}
   147  
   148  	cast, ok := tick.(TicketTlsServerTicket)
   149  	if !ok {
   150  		return TlsServer, expected(TicketTlsServerTicket{}, cast)
   151  	}
   152  
   153  	return cast.Value, nil
   154  }
   155  
   156  // GetTlsClient credentials and helpers for key from the ticket-server.
   157  // Path components will be joined with a `/`.
   158  func (g Getter) GetTlsClient(ctx *context.T, path ...string) (TlsClient TlsClientTicket, err error) {
   159  	tick, err := g.getTicket(ctx, path...)
   160  	if err != nil {
   161  		return TlsClient, err
   162  	}
   163  
   164  	cast, ok := tick.(TicketTlsClientTicket)
   165  	if !ok {
   166  		return TlsClient, expected(TicketTlsClientTicket{}, cast)
   167  	}
   168  
   169  	return cast.Value, nil
   170  }
   171  
   172  // GetDocker credentials and helpers for key from the ticket-server.
   173  // Path components will be joined with a `/`.
   174  func (g Getter) GetDocker(ctx *context.T, path ...string) (Docker DockerTicket, err error) {
   175  	tick, err := g.getTicket(ctx, path...)
   176  	if err != nil {
   177  		return Docker, err
   178  	}
   179  
   180  	cast, ok := tick.(TicketDockerTicket)
   181  	if !ok {
   182  		return Docker, expected(TicketDockerTicket{}, cast)
   183  	}
   184  
   185  	return cast.Value, nil
   186  }
   187  
   188  // GetDockerServer credentials and helpers for key from the ticket-server.
   189  // Path components will be joined with a `/`.
   190  func (g Getter) GetDockerServer(ctx *context.T, path ...string) (DockerServer DockerServerTicket, err error) {
   191  	tick, err := g.getTicket(ctx, path...)
   192  	if err != nil {
   193  		return DockerServer, err
   194  	}
   195  
   196  	cast, ok := tick.(TicketDockerServerTicket)
   197  	if !ok {
   198  		return DockerServer, expected(TicketDockerServerTicket{}, cast)
   199  	}
   200  
   201  	return cast.Value, nil
   202  }
   203  
   204  // GetDockerClient credentials and helpers for key from the ticket-server.
   205  // Path components will be joined with a `/`.
   206  func (g Getter) GetDockerClient(ctx *context.T, path ...string) (DockerClient DockerClientTicket, err error) {
   207  	tick, err := g.getTicket(ctx, path...)
   208  	if err != nil {
   209  		return DockerClient, err
   210  	}
   211  
   212  	cast, ok := tick.(TicketDockerClientTicket)
   213  	if !ok {
   214  		return DockerClient, expected(TicketDockerClientTicket{}, cast)
   215  	}
   216  
   217  	return cast.Value, nil
   218  }
   219  
   220  // GetB2 credentials and helpers for key from the ticket-server.
   221  // Path components will be joined with a `/`.
   222  func (g Getter) GetB2(ctx *context.T, path ...string) (B2 B2Ticket, err error) {
   223  	tick, err := g.getTicket(ctx, path...)
   224  	if err != nil {
   225  		return B2, err
   226  	}
   227  
   228  	cast, ok := tick.(TicketB2Ticket)
   229  	if !ok {
   230  		return B2, expected(TicketB2Ticket{}, cast)
   231  	}
   232  
   233  	return cast.Value, nil
   234  }
   235  
   236  // GetVanadium blessing and helpers for key from the ticket-server.
   237  // Path components will be joined with a `/`.
   238  func (g Getter) GetVanadium(ctx *context.T, path ...string) (Vanadium VanadiumTicket, err error) {
   239  	tick, err := g.getTicket(ctx, path...)
   240  	if err != nil {
   241  		return Vanadium, err
   242  	}
   243  
   244  	cast, ok := tick.(TicketVanadiumTicket)
   245  	if !ok {
   246  		return Vanadium, expected(TicketVanadiumTicket{}, cast)
   247  	}
   248  
   249  	return cast.Value, nil
   250  }