1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16
17
18
19 package clientconfig
20
21 import (
22 "errors"
23 "fmt"
24 "strings"
25
26 "go4.org/jsonconfig"
27 "perkeep.org/internal/httputil"
28
29 "go4.org/wkfs"
30 )
31
32
33 type Config struct {
34 Servers map[string]*Server `json:"servers"`
35 Identity string `json:"identity"`
36 IdentitySecretRing string `json:"identitySecretRing,omitempty"`
37 IgnoredFiles []string `json:"ignoredFiles,omitempty"`
38 }
39
40
41
42 type Server struct {
43 Server string `json:"server"`
44 Auth string `json:"auth"`
45 IsDefault bool `json:"default,omitempty"`
46 TrustedCerts []string `json:"trustedCerts,omitempty"`
47 }
48
49
50
51
52 func (conf *Config) Alias(server string) string {
53 longestMatch := ""
54 serverAlias := ""
55 for alias, serverConf := range conf.Servers {
56 if strings.HasPrefix(server, serverConf.Server) {
57 if len(serverConf.Server) > len(longestMatch) {
58 longestMatch = serverConf.Server
59 serverAlias = alias
60 }
61 }
62 }
63 return serverAlias
64 }
65
66
67
68 func GenerateClientConfig(serverConfig jsonconfig.Obj) (*Config, error) {
69 missingConfig := func(param string) (*Config, error) {
70 return nil, fmt.Errorf("required value for %q not found", param)
71 }
72
73 if serverConfig == nil {
74 return nil, errors.New("server config is a required parameter")
75 }
76 param := "auth"
77 auth := serverConfig.OptionalString(param, "")
78 if auth == "" {
79 return missingConfig(param)
80 }
81
82
83 param = "prefixes"
84 prefixes := serverConfig.OptionalObject(param)
85 if len(prefixes) == 0 {
86 return missingConfig(param)
87 }
88 param = "/sighelper/"
89 sighelper := prefixes.OptionalObject(param)
90 if len(sighelper) == 0 {
91 return missingConfig(param)
92 }
93 param = "handlerArgs"
94 handlerArgs := sighelper.OptionalObject(param)
95 if len(handlerArgs) == 0 {
96 return missingConfig(param)
97 }
98 param = "keyId"
99 keyID := handlerArgs.OptionalString(param, "")
100 if keyID == "" {
101 return missingConfig(param)
102 }
103
104 listen := serverConfig.OptionalString("listen", "")
105 baseURL := serverConfig.OptionalString("baseURL", "")
106 if listen == "" {
107 listen = baseURL
108 }
109 if listen == "" {
110 return nil, errors.New("required value for 'listen' or 'baseURL' not found")
111 }
112
113 https := serverConfig.OptionalBool("https", false)
114 if !strings.HasPrefix(listen, "http://") && !strings.HasPrefix(listen, "https://") {
115 if !https {
116 listen = "http://" + listen
117 } else {
118 listen = "https://" + listen
119 }
120 }
121
122 httpsCert := serverConfig.OptionalString("httpsCert", "")
123
124
125 var trustedList []string
126 if https && httpsCert != "" {
127 certPEMBlock, err := wkfs.ReadFile(httpsCert)
128 if err != nil {
129 return nil, fmt.Errorf("could not read certificate: %v", err)
130 }
131 sig, err := httputil.CertFingerprint(certPEMBlock)
132 if err != nil {
133 return nil, fmt.Errorf("could not get fingerprints of certificate: %v", err)
134 }
135 trustedList = []string{sig}
136 }
137
138 param = "secretRing"
139 secretRing := handlerArgs.OptionalString(param, "")
140 if secretRing == "" {
141 return missingConfig(param)
142 }
143
144 return &Config{
145 Servers: map[string]*Server{
146 "default": {
147 Server: listen,
148 Auth: auth,
149 IsDefault: true,
150 TrustedCerts: trustedList,
151 },
152 },
153 Identity: keyID,
154 IdentitySecretRing: secretRing,
155 IgnoredFiles: []string{".DS_Store", "*~"},
156 }, nil
157 }