package actions import ( "fmt" "io" "os" "path/filepath" "regexp" "git.t-juice.club/torjus/ezshare/pb" "github.com/urfave/cli/v2" "google.golang.org/grpc" ) func ParseBinary(path string) (*pb.Binary, error) { baseName := filepath.Base(path) pattern := `ezshare-(\d+\.\d+\.\d+).([a-z]+)-([a-z1-9]+)(\.exe)*` re := regexp.MustCompile(pattern) match := re.FindStringSubmatch(baseName) if len(match) < 4 { return nil, fmt.Errorf("invalid filename") } version := fmt.Sprintf("v%s", match[1]) operatingSystem := match[2] arch := match[3] binary := &pb.Binary{ Arch: arch, Os: operatingSystem, Version: version, } // TODO: Verify that os and arch are valid f, err := os.Open(path) if err != nil { return nil, err } binary.Data, err = io.ReadAll(f) if err != nil { return nil, err } return binary, nil } func ActionAdminUploadBinary(c *cli.Context) error { if c.Args().Len() < 1 { return cli.Exit("need at least 1 argument", 1) } cfg, err := getConfig(c) if err != nil { return err } addr := cfg.Client.DefaultServer if c.IsSet("addr") { addr = c.String("addr") } clientCreds, err := cfg.Client.Creds() if err != nil { return err } conn, err := grpc.DialContext(c.Context, addr, grpc.WithTransportCredentials(clientCreds), grpc.WithMaxMsgSize(1024*1024*100)) if err != nil { return err } defer conn.Close() client := pb.NewBinaryServiceClient(conn) var binaries []*pb.Binary for _, arg := range c.Args().Slice() { binary, err := ParseBinary(arg) if err != nil { return cli.Exit(fmt.Sprintf("error reading binary: %s", err), 1) } binaries = append(binaries, binary) } if _, err := client.UploadBinaries(c.Context, &pb.UploadBinariesRequest{Binaries: binaries}); err != nil { return cli.Exit(fmt.Sprintf("error upload binaries: %s", err), 1) } return nil } func ActionAdminCertList(c *cli.Context) error { cfg, err := getConfig(c) if err != nil { return err } addr := cfg.Client.DefaultServer if c.IsSet("addr") { addr = c.String("addr") } clientCreds, err := cfg.Client.Creds() if err != nil { return err } conn, err := grpc.DialContext(c.Context, addr, grpc.WithTransportCredentials(clientCreds)) if err != nil { return err } defer conn.Close() client := pb.NewCertificateServiceClient(conn) resp, err := client.ListCertificates(c.Context, &pb.Empty{}) if err != nil { return cli.Exit(fmt.Sprintf("unable to list certificates: %s", err), 1) } for _, info := range resp.Certificates { fmt.Printf("%s - %s", info.Serial, info.OwnerUsername) } return nil } func ActionAdminCertRevoke(c *cli.Context) error { if c.Args().Len() < 1 { return cli.Exit("need at least 1 argument", 1) } cfg, err := getConfig(c) if err != nil { return err } addr := cfg.Client.DefaultServer if c.IsSet("addr") { addr = c.String("addr") } clientCreds, err := cfg.Client.Creds() if err != nil { return err } conn, err := grpc.DialContext(c.Context, addr, grpc.WithTransportCredentials(clientCreds)) if err != nil { return err } defer conn.Close() client := pb.NewCertificateServiceClient(conn) for _, serial := range c.Args().Slice() { if _, err := client.RevokeCertificate(c.Context, &pb.RevokeCertificateRequest{Serial: serial}); err != nil { fmt.Printf("Revoked %s\n", serial) } } return nil }