annotate cmd/sievemgr/internal/config/config.go @ 22:fc5e6970a0d5 default tip

Add support for specifying an authorization identity on the command line
author Guido Berhoerster <guido+sievemgr@berhoerster.name>
date Wed, 17 Feb 2021 07:50:55 +0100
parents 4dff4c3f0fbb
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
1 // Copyright (C) 2020 Guido Berhoerster <guido+sievemgr@berhoerster.name>
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
2 //
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
3 // Permission is hereby granted, free of charge, to any person obtaining
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
4 // a copy of this software and associated documentation files (the
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
5 // "Software"), to deal in the Software without restriction, including
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
6 // without limitation the rights to use, copy, modify, merge, publish,
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
7 // distribute, sublicense, and/or sell copies of the Software, and to
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
8 // permit persons to whom the Software is furnished to do so, subject to
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
9 // the following conditions:
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
10 //
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
11 // The above copyright notice and this permission notice shall be included
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
12 // in all copies or substantial portions of the Software.
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
13 //
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
17 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
18 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
19 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
20 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
21
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
22 package config
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
23
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
24 import (
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
25 "bufio"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
26 "bytes"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
27 "fmt"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
28 "os"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
29 "path/filepath"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
30 )
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
31
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
32 const bom = '\ufeff'
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
33
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
34 type ParserError struct {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
35 Message string
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
36 LineNo int
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
37 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
38
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
39 func (e *ParserError) Error() string {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
40 if e.LineNo > 0 {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
41 return fmt.Sprintf("error in line %d: %s", e.LineNo, e.Message)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
42 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
43 return e.Message
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
44 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
45
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
46 func NewParserError(message string, lineNo int) *ParserError {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
47 return &ParserError{message, lineNo}
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
48 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
49
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
50 type Configuration struct {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
51 Accounts []*Account
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
52 Default *Account
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
53 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
54
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
55 type Account struct {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
56 Name string
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
57 Host string
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
58 Port string
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
59 User string
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
60 Password string
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
61 Insecure bool
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
62 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
63
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
64 func Parse(data []byte, conf *Configuration) error {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
65 rd := bytes.NewReader(data)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
66 s := newScanner(bufio.NewReader(rd))
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
67 p := &parser{s: s}
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
68 return p.parse(conf)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
69 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
70
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
71 func DefaultFilename() (string, error) {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
72 dir, err := os.UserConfigDir()
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
73 if err != nil {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
74 return "", fmt.Errorf("failed to determine the name of the configuration file: %s", err)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
75 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
76 return filepath.Join(dir, "sievemgr", "sievemgr.conf"), nil
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
77 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
78
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
79 func ParseFile(filename string, conf *Configuration) error {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
80 f, err := os.Open(filename)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
81 if os.IsNotExist(err) {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
82 return nil
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
83 } else if err != nil {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
84 return fmt.Errorf("failed to open configuration file: %s", err)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
85 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
86 defer f.Close()
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
87
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
88 // configutaion file must be a regular file with no more than 0600
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
89 // permissions
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
90 info, err := f.Stat()
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
91 if err != nil {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
92 return fmt.Errorf("failed to stat configuration file: %s", err)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
93 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
94 mode := info.Mode()
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
95 if !mode.IsRegular() {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
96 return fmt.Errorf("configuration file is not a regular file")
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
97 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
98 if perm := mode.Perm(); perm&0077 != 0 {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
99 return fmt.Errorf("permissions %04o on configuration file are too open", perm)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
100 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
101
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
102 s := newScanner(bufio.NewReader(f))
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
103 p := &parser{s: s}
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
104 return p.parse(conf)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
105 }