...
1 package msgdata
2
3 import (
4 "errors"
5 "fmt"
6 "strings"
7
8 "github.com/google/shlex"
9
10 "edge-infra.dev/pkg/sds/emergencyaccess/eaconst"
11 )
12
13
14
15
16 type Request interface {
17
18
19 AddAttribute(key, val string)
20
21 Attributes() map[string]string
22
23
24
25 CommandToBeAuthorized() string
26
27
28 Data() ([]byte, error)
29
30 RequestType() eaconst.RequestType
31 }
32
33
34 type Artifactor interface {
35
36
37
38 WriteContents(contents string)
39 }
40
41
42
43
44 func NewRequest(data []byte, attributes map[string]string) (Request, error) {
45 version, ok := attributes[eaconst.VersionKey]
46 if !ok {
47 return nil, errors.New("failed to find version attribute")
48 }
49 requestType, ok := attributes[eaconst.RequestTypeKey]
50 if !ok {
51 return nil, errors.New("failed to find requestType attribute")
52 }
53 switch version {
54 case string(eaconst.MessageVersion1_0):
55 return assembleV1_0Request(data, attributes)
56 case string(eaconst.MessageVersion2_0):
57 if requestType == string(eaconst.Command) {
58 return assembleV2_0CommandRequest(data, attributes)
59 }
60 if requestType == string(eaconst.Executable) {
61 return assembleV2_0ExecutableRequest(data, attributes)
62 }
63 return nil, fmt.Errorf("received version 2.0 message with unsupported request type %q", requestType)
64 default:
65 return nil, fmt.Errorf("received unsupported request message version %q", version)
66 }
67 }
68
69 func determineRequestType(payload string) eaconst.RequestType {
70 switch {
71 case strings.HasPrefix(payload, eaconst.ExecutableIdentifier):
72 return eaconst.Executable
73 default:
74 return eaconst.Command
75 }
76 }
77
78 func deepCopyMap(m map[string]string) map[string]string {
79 newMap := make(map[string]string)
80 for k, v := range m {
81 newMap[k] = v
82 }
83 return newMap
84 }
85
86 func stripExecutablePrefix(s string) string {
87 after, _ := strings.CutPrefix(s, eaconst.ExecutableIdentifier)
88 return after
89 }
90
91 func validateAttributes(attributes map[string]string, expectedVersion, expectedType string) error {
92 var err error
93 if actualVersion := attributes[eaconst.VersionKey]; actualVersion != expectedVersion {
94 err = errors.Join(err, fmt.Errorf("version attribute %q should be %q", actualVersion, expectedVersion))
95 }
96 if actualType := attributes[eaconst.RequestTypeKey]; actualType != expectedType {
97 err = errors.Join(err, fmt.Errorf("type attribute %q should be %q", actualType, expectedType))
98 }
99 return err
100 }
101
102 func parsePayload(payload string) (name string, args []string, err error) {
103 if payload == "" {
104 return "", nil, errors.New("payload cannot be empty")
105 }
106 cmdAndArgs, err := shlex.Split(payload)
107 if err != nil {
108 return "", nil, fmt.Errorf("failed to parse payload: %w", err)
109 }
110 return cmdAndArgs[0], cmdAndArgs[1:], nil
111 }
112
View as plain text