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

     1  // Copyright 2018 GRAIL, Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache-2.0
     3  // license that can be found in the LICENSE file.
     4  
     5  package ticket
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/base64"
    10  	"fmt"
    11  	"strings"
    12  	"time"
    13  
    14  	"github.com/Schaudge/grailbase/common/log"
    15  	v23 "v.io/v23"
    16  	"v.io/v23/security"
    17  	"v.io/v23/vom"
    18  )
    19  
    20  const requiredSuffix = security.ChainSeparator + "_role"
    21  
    22  func base64urlVomEncode(i interface{}) (string, error) {
    23  	buf := &bytes.Buffer{}
    24  	closer := base64.NewEncoder(base64.URLEncoding, buf)
    25  	enc := vom.NewEncoder(closer)
    26  	if err := enc.Encode(i); err != nil {
    27  		return "", err
    28  	}
    29  	// Must close the base64 encoder to flush out any partially written
    30  	// blocks.
    31  	if err := closer.Close(); err != nil {
    32  		return "", err
    33  	}
    34  	return buf.String(), nil
    35  }
    36  
    37  func (b *VanadiumBuilder) newVanadiumTicket(ctx *TicketContext) (TicketVanadiumTicket, error) {
    38  	empty := TicketVanadiumTicket{}
    39  
    40  	if !strings.HasSuffix(ctx.remoteBlessings.String(), requiredSuffix) {
    41  		return empty, fmt.Errorf("%q doesn't have the required %q suffix", ctx.remoteBlessings.String(), requiredSuffix)
    42  	}
    43  
    44  	pubKey := ctx.remoteBlessings.PublicKey()
    45  	expiryCaveat, err := security.NewExpiryCaveat(time.Now().Add(365 * 24 * time.Hour))
    46  	if err != nil {
    47  		return empty, err
    48  	}
    49  
    50  	blessing, _ := v23.GetPrincipal(ctx.ctx).BlessingStore().Default()
    51  	resultBlessings, err := v23.GetPrincipal(ctx.ctx).Bless(pubKey, blessing, b.BlessingName, expiryCaveat)
    52  	if err != nil {
    53  		return empty, err
    54  	}
    55  
    56  	log.Infof(ctx.ctx, "resultBlessings: %+v", resultBlessings)
    57  
    58  	s, err := base64urlVomEncode(resultBlessings)
    59  	if err != nil {
    60  		return empty, err
    61  	}
    62  
    63  	return TicketVanadiumTicket{
    64  		Value: VanadiumTicket{
    65  			Blessing: s,
    66  		},
    67  	}, nil
    68  }