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