mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-26 11:51:02 +00:00
parent
c186e2fa8c
commit
7986eba002
3 changed files with 77 additions and 15 deletions
|
@ -7,6 +7,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/woodpecker-ci/woodpecker/pipeline/shared"
|
||||
)
|
||||
|
||||
// Identifies the type of line in the logs.
|
||||
|
@ -49,22 +51,14 @@ type LineWriter struct {
|
|||
|
||||
// NewLineWriter returns a new line reader.
|
||||
func NewLineWriter(peer Peer, id, name string, secret ...string) *LineWriter {
|
||||
w := new(LineWriter)
|
||||
w.peer = peer
|
||||
w.id = id
|
||||
w.name = name
|
||||
w.num = 0
|
||||
w.now = time.Now().UTC()
|
||||
|
||||
var oldnew []string
|
||||
for _, old := range secret {
|
||||
oldnew = append(oldnew, old)
|
||||
oldnew = append(oldnew, "********")
|
||||
return &LineWriter{
|
||||
peer: peer,
|
||||
id: id,
|
||||
name: name,
|
||||
now: time.Now().UTC(),
|
||||
rep: shared.NewSecretsReplacer(secret),
|
||||
lines: nil,
|
||||
}
|
||||
if len(oldnew) != 0 {
|
||||
w.rep = strings.NewReplacer(oldnew...)
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *LineWriter) Write(p []byte) (n int, err error) {
|
||||
|
@ -72,6 +66,7 @@ func (w *LineWriter) Write(p []byte) (n int, err error) {
|
|||
if w.rep != nil {
|
||||
out = w.rep.Replace(out)
|
||||
}
|
||||
log.Trace().Str("name", w.name).Str("ID", w.id).Msgf("grpc write line: %s", out)
|
||||
|
||||
line := &Line{
|
||||
Out: out,
|
||||
|
|
34
pipeline/shared/replace_secrets.go
Normal file
34
pipeline/shared/replace_secrets.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2022 Woodpecker Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package shared
|
||||
|
||||
import "strings"
|
||||
|
||||
func NewSecretsReplacer(secrets []string) *strings.Replacer {
|
||||
var oldnew []string
|
||||
for _, old := range secrets {
|
||||
old = strings.TrimSpace(old)
|
||||
if len(old) == 0 {
|
||||
continue
|
||||
}
|
||||
// since replacer is executed on each line we have to split multi-line-secrets
|
||||
for _, part := range strings.Split(old, "\n") {
|
||||
oldnew = append(oldnew, part)
|
||||
oldnew = append(oldnew, "********")
|
||||
}
|
||||
}
|
||||
|
||||
return strings.NewReplacer(oldnew...)
|
||||
}
|
33
pipeline/shared/replace_secrets_test.go
Normal file
33
pipeline/shared/replace_secrets_test.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
package shared
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewSecretsReplacer(t *testing.T) {
|
||||
tc := []struct {
|
||||
log string
|
||||
secrets []string
|
||||
expect string
|
||||
}{{
|
||||
log: "start log\ndone",
|
||||
secrets: []string{""},
|
||||
expect: "start log\ndone",
|
||||
}, {
|
||||
log: `this IS secret: password`,
|
||||
secrets: []string{"password", " IS "},
|
||||
expect: `this ******** secret: ********`,
|
||||
}, {
|
||||
log: "start log\ndone\nnow\nan\nmulti line secret!! ;)",
|
||||
secrets: []string{"an\nmulti line secret!!"},
|
||||
expect: "start log\ndone\nnow\n********\n******** ;)",
|
||||
}}
|
||||
|
||||
for _, c := range tc {
|
||||
rep := NewSecretsReplacer(c.secrets)
|
||||
result := rep.Replace(c.log)
|
||||
assert.EqualValues(t, c.expect, result)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue