1package internal 2 3import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "os" 8 "regexp" 9) 10 11type Passport struct { 12 SubjectID string `json:"subject_id"` 13 CertificateID string `json:"certificate_id"` 14 Issuer string `json:"issuer"` 15 PrivateKey string `json:"private_key"` 16 PublicKey string `json:"public_key"` 17} 18 19func LoadPassportFile(location string) (*Passport, error) { 20 file, err := os.Open(location) 21 if err != nil { 22 return nil, fmt.Errorf("failed to open passport file: %w", err) 23 } 24 25 defer func() { _ = file.Close() }() 26 27 var passport Passport 28 err = json.NewDecoder(file).Decode(&passport) 29 if err != nil { 30 return nil, fmt.Errorf("failed to parse passport file: %w", err) 31 } 32 33 err = passport.validate() 34 if err != nil { 35 return nil, fmt.Errorf("passport file validation failed: %w", err) 36 } 37 38 return &passport, nil 39} 40 41func (passport *Passport) validate() error { 42 if passport.Issuer == "" { 43 return errors.New("issuer is empty") 44 } 45 46 if passport.CertificateID == "" { 47 return errors.New("certificate ID is empty") 48 } 49 50 if passport.PrivateKey == "" { 51 return errors.New("private key is missing") 52 } 53 54 if passport.SubjectID == "" { 55 return errors.New("subject is empty") 56 } 57 58 return nil 59} 60 61func (passport *Passport) ExtractProjectID() (string, error) { 62 re := regexp.MustCompile("iam/project/([a-zA-Z0-9]+)") 63 64 parts := re.FindStringSubmatch(passport.SubjectID) 65 if len(parts) != 2 { 66 return "", fmt.Errorf("failed to extract project ID from subject ID: %s", passport.SubjectID) 67 } 68 69 return parts[1], nil 70} 71