• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mongodb / mongodb-atlas-cli / 16671521771

01 Aug 2025 09:28AM UTC coverage: 57.953% (-7.1%) from 65.017%
16671521771

push

github

web-flow
chore: remove unit tag from tests (#4071)

23613 of 40745 relevant lines covered (57.95%)

2.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/internal/decryption/decryption.go
1
// Copyright 2022 MongoDB Inc
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
package decryption
16

17
import (
18
        "io"
19
)
20

21
type DecryptSection struct {
22
        lek                    []byte
23
        compressionMode        CompressionMode
24
        lastKeyInvocationCount uint64
25
}
26

27
func (s *DecryptSection) zeroLEK() {
×
28
        if s == nil {
×
29
                return
×
30
        }
×
31
        for i := range s.lek {
×
32
                s.lek[i] = 0
×
33
        }
×
34
}
35

36
type Decryption struct {
37
        opts KeyProviderOpts
38
}
39

40
type Option func(d *Decryption)
41

42
func NewDecryption(options ...Option) *Decryption {
×
43
        d := &Decryption{}
×
44
        for _, opt := range options {
×
45
                opt(d)
×
46
        }
×
47
        return d
×
48
}
49

50
func WithAWSOpts(accessKey, secretAccessKey, sessionToken string) func(d *Decryption) {
×
51
        return func(d *Decryption) {
×
52
                d.opts.AWS = &KeyProviderAWSOpts{
×
53
                        AccessKey:       accessKey,
×
54
                        SecretAccessKey: secretAccessKey,
×
55
                        SessionToken:    sessionToken,
×
56
                }
×
57
        }
×
58
}
59

60
func WithGCPOpts(serviceAccountKey string) func(d *Decryption) {
×
61
        return func(d *Decryption) {
×
62
                d.opts.GCP = &KeyProviderGCPOpts{
×
63
                        ServiceAccountKey: serviceAccountKey,
×
64
                }
×
65
        }
×
66
}
67

68
func WithAzureOpts(tenantID, clientID, secret string) func(d *Decryption) {
×
69
        return func(d *Decryption) {
×
70
                d.opts.Azure = &KeyProviderAzureOpts{
×
71
                        TenantID: tenantID,
×
72
                        ClientID: clientID,
×
73
                        Secret:   secret,
×
74
                }
×
75
        }
×
76
}
77

78
// Decrypt decrypts the content of an audit log file using the metadata found in the file,
79
// the credentials provided by the user and the AES-GCM algorithm.
80
// The decrypted audit log records are saved in the out stream.
81
func (d *Decryption) Decrypt(logReader io.ReadSeeker, out io.Writer) error {
×
82
        logLineScanner, err := readAuditLogFile(logReader)
×
83
        if err != nil {
×
84
                return err
×
85
        }
×
86

87
        output := NewAuditLogOutput(out)
×
88
        var decryptSection *DecryptSection
×
89

×
90
        idx := 0
×
91
        for ; logLineScanner.Scan(); idx++ {
×
92
                lineNb := idx + 1
×
93
                logLine, err := logLineScanner.AuditLogLine()
×
94
                if err != nil {
×
95
                        if outputErr := output.Errorf(lineNb, logLine, "error parsing line %d, %v", lineNb, err); outputErr != nil {
×
96
                                return outputErr
×
97
                        }
×
98
                        if decryptSection != nil {
×
99
                                // even if log record is corrupted, consider it was encrypted,
×
100
                                // so the lastKeyInvocationCount should be incremented
×
101
                                decryptSection.lastKeyInvocationCount++
×
102
                        }
×
103
                        continue
×
104
                }
105

106
                switch logLine.AuditRecordType {
×
107
                case AuditHeaderRecord:
×
108
                        decryptSection.zeroLEK()
×
109
                        if decryptSection, err = processHeader(logLine, d.opts); err != nil {
×
110
                                if outputErr := output.Errorf(lineNb, logLine, `error processing header line %d: %s`, lineNb, err); outputErr != nil {
×
111
                                        return outputErr
×
112
                                }
×
113
                        }
114
                case AuditLogRecord:
×
115
                        if err := decryptAuditLogRecord(decryptSection, logLine, output, lineNb); err != nil {
×
116
                                return err
×
117
                        }
×
118
                default:
×
119
                        if outputErr := output.Errorf(lineNb, logLine, `line %d skipped, unknown auditRecordType="%s"`, lineNb, logLine.AuditRecordType); outputErr != nil {
×
120
                                return outputErr
×
121
                        }
×
122
                }
123
        }
124
        decryptSection.zeroLEK()
×
125
        if err := logLineScanner.Err(); err != nil {
×
126
                lineNb := idx + 1
×
127
                if outputErr := output.Errorf(lineNb, nil, "error parsing line %d, %v", lineNb, err); outputErr != nil {
×
128
                        return outputErr
×
129
                }
×
130
        }
131

132
        return nil
×
133
}
134

135
func decryptAuditLogRecord(decryptSection *DecryptSection, logLine *AuditLogLine, output AuditLogOutput, lineNb int) error {
×
136
        if decryptSection == nil {
×
137
                return output.Warningf(lineNb, logLine, `line %d skipped, the header record for current section is missing or corrupted`, lineNb)
×
138
        }
×
139

140
        decryptedLogRecord, keyInvocationCount, err := processLogRecord(decryptSection, logLine, lineNb)
×
141
        if err != nil {
×
142
                // even if log record is corrupted, consider it was encrypted,
×
143
                // so the lastKeyInvocationCount should be incremented
×
144
                decryptSection.lastKeyInvocationCount++
×
145
                return output.Error(lineNb, logLine, err)
×
146
        }
×
147

148
        err = validateLogRecord(decryptSection, keyInvocationCount)
×
149
        decryptSection.lastKeyInvocationCount = keyInvocationCount
×
150
        if err != nil {
×
151
                if outputErr := output.Error(lineNb, logLine, err); outputErr != nil {
×
152
                        return outputErr
×
153
                }
×
154
        }
155

156
        return output.LogRecord(lineNb, decryptedLogRecord)
×
157
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc