forked from Versent/saml2aws
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cfg.go
143 lines (109 loc) · 3.56 KB
/
cfg.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package cfg
import (
"net/url"
"github.com/fatih/structs"
"github.com/mitchellh/go-homedir"
"github.com/pkg/errors"
ini "gopkg.in/ini.v1"
)
// ErrIdpAccountNotFound returned if the idp account is not found in the configuration file
var ErrIdpAccountNotFound = errors.New("IDP account not found, run configure to set it up")
// DefaultConfigPath the default saml2aws configuration path
var DefaultConfigPath = "~/.saml2aws"
// IDPAccount saml IDP account
type IDPAccount struct {
URL string `ini:"url"`
Username string `ini:"username"`
Provider string `ini:"provider"`
MFA string `ini:"mfa"`
SkipVerify bool `ini:"skip_verify"`
Timeout int `ini:"timeout"`
}
// Validate validate the required / expected fields are set
func (ia *IDPAccount) Validate() error {
if ia.URL == "" {
return errors.New("URL empty in idp account")
}
_, err := url.Parse(ia.URL)
if err != nil {
return errors.New("URL parse failed")
}
if ia.Provider == "" {
return errors.New("Provider empty in idp account")
}
if ia.MFA == "" {
return errors.New("MFA empty in idp account")
}
return nil
}
// ConfigManager manage the various IDP account settings
type ConfigManager struct {
configPath string
}
// NewConfigManager build a new config manager and optionally override the config path
func NewConfigManager(configFile string) (*ConfigManager, error) {
if configFile == "" {
configFile = DefaultConfigPath
}
configPath, err := homedir.Expand(configFile)
if err != nil {
return nil, err
}
return &ConfigManager{configPath}, nil
}
// SaveIDPAccount save idp account
func (cm *ConfigManager) SaveIDPAccount(idpAccountName string, account *IDPAccount) error {
cfg, err := ini.LoadSources(ini.LoadOptions{Loose: true}, cm.configPath)
if err != nil {
return errors.Wrap(err, "Unable to load configuration file")
}
newSec, err := cfg.NewSection(idpAccountName)
if err != nil {
return errors.Wrap(err, "Unable to build a new section in configuration file")
}
err = newSec.ReflectFrom(account)
if err != nil {
return errors.Wrap(err, "Unable to save account to configuration file")
}
err = cfg.SaveTo(cm.configPath)
if err != nil {
return errors.Wrap(err, "Failed to save configuration file")
}
return nil
}
// LoadIDPAccount load the idp account and default to an empty one if it doesn't exist
func (cm *ConfigManager) LoadIDPAccount(idpAccountName string) (*IDPAccount, error) {
cfg, err := ini.LoadSources(ini.LoadOptions{Loose: true}, cm.configPath)
if err != nil {
return nil, errors.Wrap(err, "Unable to load configuration file")
}
return readAccount(idpAccountName, cfg)
}
// LoadVerifyIDPAccount load the idp account and verify it isn't empty
func (cm *ConfigManager) LoadVerifyIDPAccount(idpAccountName string) (*IDPAccount, error) {
cfg, err := ini.LoadSources(ini.LoadOptions{Loose: true}, cm.configPath)
if err != nil {
return nil, errors.Wrap(err, "Unable to load configuration file")
}
account, err := readAccount(idpAccountName, cfg)
if err != nil {
return nil, errors.Wrap(err, "Unable to read idp account")
}
if structs.IsZero(account) {
return nil, ErrIdpAccountNotFound
}
return account, nil
}
// IsErrIdpAccountNotFound check if the error is a ErrIdpAccountNotFound
func IsErrIdpAccountNotFound(err error) bool {
return err == ErrIdpAccountNotFound
}
func readAccount(idpAccountName string, cfg *ini.File) (*IDPAccount, error) {
account := new(IDPAccount)
sec := cfg.Section(idpAccountName)
err := sec.MapTo(account)
if err != nil {
return nil, errors.Wrap(err, "Unable to map account")
}
return account, nil
}