Skip to content

Commit 99479f1

Browse files
committed
Authorization package refactor - part 2
1 parent d344589 commit 99479f1

File tree

6 files changed

+193
-197
lines changed

6 files changed

+193
-197
lines changed

controllers/operator/authentication/authentication.go

Lines changed: 28 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
package authentication
22

33
import (
4-
"crypto/sha1" //nolint //Part of the algorithm
5-
"crypto/sha256"
6-
"fmt"
7-
84
"go.uber.org/zap"
95
"golang.org/x/xerrors"
106

@@ -147,33 +143,6 @@ func Configure(conn om.Connection, opts Options, isRecovering bool, log *zap.Sug
147143
return nil
148144
}
149145

150-
// ConfigureScramCredentials creates both SCRAM-SHA-1 and SCRAM-SHA-256 credentials. This ensures
151-
// that changes to the authentication settings on the MongoDB resources won't leave MongoDBUsers without
152-
// the correct credentials.
153-
func ConfigureScramCredentials(user *om.MongoDBUser, password string) error {
154-
scram256Salt, err := GenerateSalt(sha256.New)
155-
if err != nil {
156-
return xerrors.Errorf("error generating scramSha256 salt: %w", err)
157-
}
158-
159-
scram1Salt, err := GenerateSalt(sha1.New)
160-
if err != nil {
161-
return xerrors.Errorf("error generating scramSha1 salt: %w", err)
162-
}
163-
164-
scram256Creds, err := ComputeScramShaCreds(user.Username, password, scram256Salt, ScramSha256)
165-
if err != nil {
166-
return xerrors.Errorf("error generating scramSha256 creds: %w", err)
167-
}
168-
scram1Creds, err := ComputeScramShaCreds(user.Username, password, scram1Salt, MongoDBCR)
169-
if err != nil {
170-
return xerrors.Errorf("error generating scramSha1Creds: %w", err)
171-
}
172-
user.ScramSha256Creds = scram256Creds
173-
user.ScramSha1Creds = scram1Creds
174-
return nil
175-
}
176-
177146
// Disable disables all authentication mechanisms, and waits for the agents to reach goal state. It is still required to provide
178147
// automation agent username, password and keyfile contents to ensure a valid Automation Config.
179148
func Disable(conn om.Connection, opts Options, deleteUsers bool, log *zap.SugaredLogger) error {
@@ -254,46 +223,6 @@ func Disable(conn om.Connection, opts Options, deleteUsers bool, log *zap.Sugare
254223
return nil
255224
}
256225

257-
func getMechanismName(mongodbResourceMode string, ac *om.AutomationConfig) MechanismName {
258-
switch mongodbResourceMode {
259-
case util.X509:
260-
return MongoDBX509
261-
case util.LDAP:
262-
return LDAPPlain
263-
case util.SCRAMSHA1:
264-
return ScramSha1
265-
case util.MONGODBCR:
266-
return MongoDBCR
267-
case util.SCRAMSHA256:
268-
return ScramSha256
269-
case util.SCRAM:
270-
// if we have already configured authentication and it has been set to MONGODB-CR/SCRAM-SHA-1
271-
// we can not transition. This needs to be done in the UI
272-
273-
// if no authentication has been configured, the default value for "AutoAuthMechanism" is "MONGODB-CR"
274-
// even if authentication is disabled, so we need to ensure that auth has been enabled.
275-
if ac.Auth.AutoAuthMechanism == string(MongoDBCR) && ac.Auth.IsEnabled() {
276-
return MongoDBCR
277-
}
278-
return ScramSha256
279-
}
280-
// this should never be reached as validation of this string happens at the CR level
281-
panic(fmt.Sprintf("unknown mechanism name %s", mongodbResourceMode))
282-
}
283-
284-
// Mechanism is an interface that needs to be implemented for any Ops Manager authentication mechanism
285-
type Mechanism interface {
286-
EnableAgentAuthentication(conn om.Connection, opts Options, log *zap.SugaredLogger) error
287-
DisableAgentAuthentication(conn om.Connection, log *zap.SugaredLogger) error
288-
EnableDeploymentAuthentication(conn om.Connection, opts Options, log *zap.SugaredLogger) error
289-
DisableDeploymentAuthentication(conn om.Connection, log *zap.SugaredLogger) error
290-
// IsAgentAuthenticationConfigured should not rely on util.MergoDelete since the method is always
291-
// called directly after deserializing the response from OM which should not contain the util.MergoDelete value in any field.
292-
IsAgentAuthenticationConfigured(ac *om.AutomationConfig, opts Options) bool
293-
IsDeploymentAuthenticationConfigured(ac *om.AutomationConfig, opts Options) bool
294-
GetName() MechanismName
295-
}
296-
297226
// removeUnsupportedAgentMechanisms removes authentication mechanism that were previously enabled, or were required
298227
// as part of the transition process.
299228
func removeUnsupportedAgentMechanisms(conn om.Connection, opts Options, log *zap.SugaredLogger) error {
@@ -302,20 +231,19 @@ func removeUnsupportedAgentMechanisms(conn om.Connection, opts Options, log *zap
302231
return xerrors.Errorf("error reading automation config: %w", err)
303232
}
304233

305-
automationConfigAuthMechanismNames := getMechanismNames(ac, opts.Mechanisms)
234+
automationConfigAuthMechanismNames := convertToMechanismList(opts.Mechanisms, ac)
306235

307236
unsupportedMechanisms := mechanismsToDisable(automationConfigAuthMechanismNames)
308237

309238
log.Infow("configuring agent authentication mechanisms", "enabled", opts.AgentMechanism, "disabling", unsupportedMechanisms)
310-
for _, mechanismName := range unsupportedMechanisms {
311-
mechanism := fromName(mechanismName)
239+
for _, mechanism := range unsupportedMechanisms {
312240
if mechanism.IsAgentAuthenticationConfigured(ac, opts) {
313-
log.Infof("disabling authentication mechanism %s", mechanismName)
241+
log.Infof("disabling authentication mechanism %s", mechanism.GetName())
314242
if err := mechanism.DisableAgentAuthentication(conn, log); err != nil {
315243
return xerrors.Errorf("error disabling agent authentication: %w", err)
316244
}
317245
} else {
318-
log.Infof("mechanism %s is already disabled", mechanismName)
246+
log.Infof("mechanism %s is already disabled", mechanism.GetName())
319247
}
320248
}
321249

@@ -331,8 +259,8 @@ func enableAgentAuthentication(conn om.Connection, opts Options, log *zap.Sugare
331259
}
332260

333261
// we then configure the agent authentication for that type
334-
agentAuthMechanism := getMechanismName(opts.AgentMechanism, ac)
335-
if err := ensureAgentAuthenticationIsConfigured(conn, opts, ac, agentAuthMechanism, log); err != nil {
262+
mechanism := convertToMechanism(opts.AgentMechanism, ac)
263+
if err := ensureAgentAuthenticationIsConfigured(conn, opts, ac, mechanism, log); err != nil {
336264
return xerrors.Errorf("error ensuring agent authentication is configured: %w", err)
337265
}
338266

@@ -368,10 +296,10 @@ func ensureDeploymentsMechanismsExist(conn om.Connection, opts Options, log *zap
368296

369297
// "opts.Mechanisms" is the list of mechanism names passed through from the MongoDB resource.
370298
// We need to convert this to the list of strings the automation config expects.
371-
automationConfigMechanismNames := getMechanismNames(ac, opts.Mechanisms)
299+
automationConfigMechanisms := convertToMechanismList(opts.Mechanisms, ac)
372300

373-
log.Debugf("Automation config authentication mechanisms: %+v", automationConfigMechanismNames)
374-
if err := ensureDeploymentMechanisms(conn, ac, automationConfigMechanismNames, opts, log); err != nil {
301+
log.Debugf("Automation config authentication mechanisms: %+v", automationConfigMechanisms)
302+
if err := ensureDeploymentMechanisms(conn, ac, automationConfigMechanisms, opts, log); err != nil {
375303
return xerrors.Errorf("error ensuring deployment mechanisms: %w", err)
376304
}
377305

@@ -387,10 +315,9 @@ func removeUnsupportedDeploymentMechanisms(conn om.Connection, opts Options, log
387315
}
388316

389317
// "opts.Mechanisms" is the list of mechanism names passed through from the MongoDB resource.
390-
// We need to convert this to the list of strings the automation config expects.
391-
automationConfigAuthMechanismNames := getMechanismNames(ac, opts.Mechanisms)
318+
automationConfigAuthMechanisms := convertToMechanismList(opts.Mechanisms, ac)
392319

393-
unsupportedMechanisms := mechanismsToDisable(automationConfigAuthMechanismNames)
320+
unsupportedMechanisms := mechanismsToDisable(automationConfigAuthMechanisms)
394321

395322
log.Infow("Removing unsupported deployment authentication mechanisms", "Mechanisms", unsupportedMechanisms)
396323
if err := ensureDeploymentMechanismsAreDisabled(conn, ac, unsupportedMechanisms, opts, log); err != nil {
@@ -408,7 +335,7 @@ func addOrRemoveAgentClientCertificate(conn om.Connection, opts Options, log *za
408335
// If x509 is not enabled but still Client Certificates are, this automation config update
409336
// will add the required configuration.
410337
return conn.ReadUpdateAutomationConfig(func(ac *om.AutomationConfig) error {
411-
if getMechanismName(opts.AgentMechanism, ac) == MongoDBX509 {
338+
if convertToMechanism(opts.AgentMechanism, ac).GetName() == MongoDBX509 {
412339
// If TLS client authentication is managed by x509, we won't disable or enable it
413340
// in here.
414341
return nil
@@ -430,98 +357,36 @@ func addOrRemoveAgentClientCertificate(conn om.Connection, opts Options, log *za
430357
}, log)
431358
}
432359

433-
func getMechanismNames(ac *om.AutomationConfig, mechanisms []string) []MechanismName {
434-
automationConfigMechanismNames := make([]MechanismName, 0)
435-
for _, m := range mechanisms {
436-
automationConfigMechanismNames = append(automationConfigMechanismNames, getMechanismName(m, ac))
437-
}
438-
return automationConfigMechanismNames
439-
}
440-
441-
// MechanismName corresponds to the string used in the automation config representing
442-
// a particular type of authentication
443-
type MechanismName string
444-
445-
const (
446-
ScramSha256 MechanismName = "SCRAM-SHA-256"
447-
ScramSha1 MechanismName = "SCRAM-SHA-1"
448-
MongoDBX509 MechanismName = "MONGODB-X509"
449-
LDAPPlain MechanismName = "PLAIN"
450-
451-
// MongoDBCR is an umbrella term for SCRAM-SHA-1 and MONGODB-CR for legacy reasons, once MONGODB-CR
452-
// is enabled, users can auth with SCRAM-SHA-1 credentials
453-
MongoDBCR MechanismName = "MONGODB-CR"
454-
)
455-
456-
// supportedMechanisms returns a list of all the authentication mechanisms
457-
// that can be configured by the Operator
458-
func supportedMechanisms() []MechanismName {
459-
return []MechanismName{ScramSha256, MongoDBCR, MongoDBX509, LDAPPlain}
460-
}
461-
462-
// fromName returns an implementation of mechanism from the string value
463-
// used in the AutomationConfig. All supported fields are in supportedMechanisms
464-
func fromName(name MechanismName) Mechanism {
465-
switch name {
466-
case MongoDBCR:
467-
return MongoDBCRMechanism
468-
case ScramSha1:
469-
return ScramSha1Mechanism
470-
case ScramSha256:
471-
return ScramSha256Mechanism
472-
case MongoDBX509:
473-
return MongoDBX509Mechanism
474-
case LDAPPlain:
475-
return LDAPPlainMechanism
476-
}
477-
478-
panic(xerrors.Errorf("unknown authentication mechanism %s. Supported mechanisms are %+v", name, supportedMechanisms()))
479-
}
480-
481-
// mechanismsToDisable returns a list of mechanisms which need to be disabled
482-
// based on the currently supported authentication mechanisms and the desiredMechanisms
483-
func mechanismsToDisable(desiredMechanisms []MechanismName) []MechanismName {
484-
toDisable := make([]MechanismName, 0)
485-
for _, m := range supportedMechanisms() {
486-
if !containsMechanismName(desiredMechanisms, m) {
487-
toDisable = append(toDisable, m)
488-
}
489-
}
490-
return toDisable
491-
}
492-
493360
// ensureAgentAuthenticationIsConfigured will configure the agent authentication settings based on the desiredAgentAuthMechanism
494-
func ensureAgentAuthenticationIsConfigured(conn om.Connection, opts Options, ac *om.AutomationConfig, desiredAgentAuthMechanismName MechanismName, log *zap.SugaredLogger) error {
495-
m := fromName(desiredAgentAuthMechanismName)
496-
if m.IsAgentAuthenticationConfigured(ac, opts) {
497-
log.Infof("Agent authentication mechanism %s is already configured", desiredAgentAuthMechanismName)
361+
func ensureAgentAuthenticationIsConfigured(conn om.Connection, opts Options, ac *om.AutomationConfig, mechanism Mechanism, log *zap.SugaredLogger) error {
362+
if mechanism.IsAgentAuthenticationConfigured(ac, opts) {
363+
log.Infof("Agent authentication mechanism %s is already configured", mechanism.GetName())
498364
return nil
499365
}
500366

501-
log.Infof("Enabling %s agent authentication", desiredAgentAuthMechanismName)
502-
return m.EnableAgentAuthentication(conn, opts, log)
367+
log.Infof("Enabling %s agent authentication", mechanism.GetName())
368+
return mechanism.EnableAgentAuthentication(conn, opts, log)
503369
}
504370

505371
// ensureDeploymentMechanisms configures the given AutomationConfig to allow deployments to
506372
// authenticate using the specified mechanisms
507-
func ensureDeploymentMechanisms(conn om.Connection, ac *om.AutomationConfig, desiredDeploymentAuthMechanisms []MechanismName, opts Options, log *zap.SugaredLogger) error {
508-
deploymentMechanismsToEnable := make(map[MechanismName]Mechanism)
509-
for _, mechanismName := range desiredDeploymentAuthMechanisms {
510-
mechanism := fromName(mechanismName)
373+
func ensureDeploymentMechanisms(conn om.Connection, ac *om.AutomationConfig, mechanisms MechanismList, opts Options, log *zap.SugaredLogger) error {
374+
mechanismsToEnable := make([]Mechanism, 0)
375+
for _, mechanism := range mechanisms {
511376
if !mechanism.IsDeploymentAuthenticationConfigured(ac, opts) {
512-
deploymentMechanismsToEnable[mechanismName] = mechanism
377+
mechanismsToEnable = append(mechanismsToEnable, mechanism)
513378
} else {
514-
log.Debugf("Deployment mechanism %s is already configured", mechanismName)
379+
log.Debugf("Deployment mechanism %s is already configured", mechanism.GetName())
515380
}
516381
}
517382

518-
if len(deploymentMechanismsToEnable) == 0 {
383+
if len(mechanismsToEnable) == 0 {
519384
log.Info("All required deployment authentication mechanisms are configured")
520385
return nil
521386
}
522387

523-
for mechanismName, mechanism := range deploymentMechanismsToEnable {
524-
log.Debugf("Enabling deployment mechanism %s", mechanismName)
388+
for _, mechanism := range mechanismsToEnable {
389+
log.Debugf("Enabling deployment mechanism %s", mechanism.GetName())
525390
if err := mechanism.EnableDeploymentAuthentication(conn, opts, log); err != nil {
526391
return xerrors.Errorf("error enabling deployment authentication: %w", err)
527392
}
@@ -532,17 +397,16 @@ func ensureDeploymentMechanisms(conn om.Connection, ac *om.AutomationConfig, des
532397

533398
// ensureDeploymentMechanismsAreDisabled configures the given AutomationConfig to allow deployments to
534399
// authenticate using the specified mechanisms
535-
func ensureDeploymentMechanismsAreDisabled(conn om.Connection, ac *om.AutomationConfig, mechanismsToDisable []MechanismName, opts Options, log *zap.SugaredLogger) error {
400+
func ensureDeploymentMechanismsAreDisabled(conn om.Connection, ac *om.AutomationConfig, mechanismsToDisable MechanismList, opts Options, log *zap.SugaredLogger) error {
536401
deploymentMechanismsToDisable := make([]Mechanism, 0)
537-
for _, mechanismName := range mechanismsToDisable {
538-
mechanism := fromName(mechanismName)
402+
for _, mechanism := range mechanismsToDisable {
539403
if mechanism.IsDeploymentAuthenticationConfigured(ac, opts) {
540404
deploymentMechanismsToDisable = append(deploymentMechanismsToDisable, mechanism)
541405
}
542406
}
543407

544408
if len(deploymentMechanismsToDisable) == 0 {
545-
log.Infof("Mechanisms %+v are all already disabled", mechanismsToDisable)
409+
log.Infof("Mechanisms [%s] are all already disabled", mechanismsToDisable)
546410
return nil
547411
}
548412

@@ -555,14 +419,3 @@ func ensureDeploymentMechanismsAreDisabled(conn om.Connection, ac *om.Automation
555419

556420
return nil
557421
}
558-
559-
// containsMechanismName returns true if there is at least one MechanismName in `slice`
560-
// that is equal to `mn`.
561-
func containsMechanismName(slice []MechanismName, mn MechanismName) bool {
562-
for _, item := range slice {
563-
if item == mn {
564-
return true
565-
}
566-
}
567-
return false
568-
}

0 commit comments

Comments
 (0)