Skip to content

Commit 8437b65

Browse files
committed
fix(o365-plugin): Remove invalid field check and add multi-cloud support
- Implement cloud-aware connection checking per authority - Use correct endpoints and scopes for each cloud environment
1 parent 42a19ad commit 8437b65

2 files changed

Lines changed: 81 additions & 20 deletions

File tree

plugins/modules-config/validations/o365.go

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,51 @@ import (
1313
)
1414

1515
const (
16-
loginUrl = "https://login.microsoftonline.com/"
1716
grantType = "client_credentials"
18-
scope = "https://manage.office.com/.default"
1917
endPointLogin = "/oauth2/v2.0/token"
2018
)
2119

20+
type CloudEnvironment string
21+
22+
const (
23+
CloudCommercial CloudEnvironment = "Commercial"
24+
CloudGCC CloudEnvironment = "GCC"
25+
CloudGCCHigh CloudEnvironment = "GCCHigh"
26+
CloudDoD CloudEnvironment = "DoD"
27+
)
28+
29+
type CloudConfig struct {
30+
LoginAuthority string
31+
Scope string
32+
}
33+
34+
func getCloudConfig(env CloudEnvironment) CloudConfig {
35+
configs := map[CloudEnvironment]CloudConfig{
36+
CloudCommercial: {
37+
LoginAuthority: "https://login.microsoftonline.com/",
38+
Scope: "https://manage.office.com/.default",
39+
},
40+
CloudGCC: {
41+
LoginAuthority: "https://login.microsoftonline.com/",
42+
Scope: "https://manage-gcc.office.com/.default",
43+
},
44+
CloudGCCHigh: {
45+
LoginAuthority: "https://login.microsoftonline.us/",
46+
Scope: "https://manage.office365.us/.default",
47+
},
48+
CloudDoD: {
49+
LoginAuthority: "https://login.microsoftonline.us/",
50+
Scope: "https://manage.protection.apps.mil/.default",
51+
},
52+
}
53+
54+
cloudConfig, exists := configs[env]
55+
if !exists {
56+
return configs[CloudCommercial]
57+
}
58+
return cloudConfig
59+
}
60+
2261
type MicrosoftLoginResponse struct {
2362
TokenType string `json:"token_type,omitempty"`
2463
Expires int `json:"expires_in,omitempty"`
@@ -30,6 +69,7 @@ type MicrosoftLoginResponse struct {
3069

3170
func ValidateO365Config(config *config.ModuleGroup) error {
3271
var clientId, clientSecret, tenantId string
72+
var cloudEnvironment CloudEnvironment = CloudCommercial
3373

3474
if config == nil {
3575
return fmt.Errorf("O365 configuration is nil")
@@ -43,6 +83,10 @@ func ValidateO365Config(config *config.ModuleGroup) error {
4383
clientSecret = cnf.ConfValue
4484
case "office365_tenant_id":
4585
tenantId = cnf.ConfValue
86+
case "office365_cloud_environment":
87+
if cnf.ConfValue != "" {
88+
cloudEnvironment = CloudEnvironment(cnf.ConfValue)
89+
}
4690
}
4791
}
4892

@@ -56,14 +100,16 @@ func ValidateO365Config(config *config.ModuleGroup) error {
56100
return fmt.Errorf("Tenant ID is required in O365 configuration")
57101
}
58102

103+
cloudConfig := getCloudConfig(cloudEnvironment)
104+
59105
// Validate credentials by attempting to get an access token
60-
requestUrl := fmt.Sprintf("%s%s%s", loginUrl, tenantId, endPointLogin)
106+
requestUrl := fmt.Sprintf("%s%s%s", cloudConfig.LoginAuthority, tenantId, endPointLogin)
61107

62108
data := url.Values{}
63109
data.Set("grant_type", grantType)
64110
data.Set("client_id", clientId)
65111
data.Set("client_secret", clientSecret)
66-
data.Set("scope", scope)
112+
data.Set("scope", cloudConfig.Scope)
67113

68114
client := &http.Client{
69115
Timeout: 10 * time.Second,

plugins/o365/main.go

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -90,30 +90,17 @@ func main() {
9090
for range ticker.C {
9191
endTime := time.Now().UTC()
9292

93-
defaultConfig := GetCloudConfig(CloudCommercial)
94-
if err := ConnectionChecker(defaultConfig.LoginAuthority); err != nil {
95-
_ = catcher.Error("External connection failure detected: %v", err, nil)
96-
}
97-
9893
moduleConfig := config.GetConfig()
9994
if moduleConfig != nil && moduleConfig.ModuleActive {
95+
checkConfiguredEnvironments(moduleConfig.ModuleGroups)
96+
10097
var wg sync.WaitGroup
10198
wg.Add(len(moduleConfig.ModuleGroups))
10299

103100
for _, grp := range moduleConfig.ModuleGroups {
104101
go func(group *config.ModuleGroup) {
105102
defer wg.Done()
106-
var invalid bool
107-
for _, c := range group.ModuleGroupConfigurations {
108-
if strings.TrimSpace(c.ConfValue) == "" {
109-
invalid = true
110-
break
111-
}
112-
}
113-
114-
if !invalid {
115-
pull(startTime, endTime, group)
116-
}
103+
pull(startTime, endTime, group)
117104
}(grp)
118105
}
119106

@@ -124,6 +111,34 @@ func main() {
124111
}
125112
}
126113

114+
func checkConfiguredEnvironments(groups []*config.ModuleGroup) {
115+
uniqueAuthorities := make(map[string]CloudEnvironment)
116+
117+
for _, group := range groups {
118+
env := getGroupEnvironment(group)
119+
cloudConfig := GetCloudConfig(env)
120+
uniqueAuthorities[cloudConfig.LoginAuthority] = env
121+
}
122+
123+
for authority, env := range uniqueAuthorities {
124+
if err := ConnectionChecker(authority); err != nil {
125+
_ = catcher.Error("External connection failure detected", err, map[string]any{
126+
"environment": env,
127+
"authority": authority,
128+
})
129+
}
130+
}
131+
}
132+
133+
func getGroupEnvironment(group *config.ModuleGroup) CloudEnvironment {
134+
for _, cnf := range group.ModuleGroupConfigurations {
135+
if cnf.ConfKey == "office365_cloud_environment" && cnf.ConfValue != "" {
136+
return CloudEnvironment(cnf.ConfValue)
137+
}
138+
}
139+
return CloudCommercial
140+
}
141+
127142
func pull(startTime time.Time, endTime time.Time, group *config.ModuleGroup) {
128143
agent := GetOfficeProcessor(group)
129144

0 commit comments

Comments
 (0)