Skip to content

Commit

Permalink
A better fix for the json marshalling/unmarshalling of vcs-config.
Browse files Browse the repository at this point in the history
The issue I ran into earlier was simple, I needed VcsConfig to be
a *json.RawMessage instead of a json.RawMessage. But I did not want
to just fix that because it would have sent the vcs-config as JSON
to the client exposing any credentials that are stored there. I use
a trick here where I create a special type like json.RawMessage that
will preserve bytes in Unmarshal, but just emit {} in marshal.
  • Loading branch information
Kelly Norton committed Mar 12, 2015
1 parent 81f58a3 commit 851b9cc
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 26 deletions.
53 changes: 29 additions & 24 deletions src/hound/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package config

import (
"encoding/json"
"errors"
"os"
"path/filepath"
)
Expand All @@ -19,42 +20,46 @@ type UrlPattern struct {
}

type Repo struct {
Url string `json:"url"`
MsBetweenPolls int `json:"ms-between-poll"`
Vcs string `json:"vcs"`
VcsConfig json.RawMessage `json:"-"`
UrlPattern *UrlPattern `json:"url-pattern"`
Url string `json:"url"`
MsBetweenPolls int `json:"ms-between-poll"`
Vcs string `json:"vcs"`
VcsConfigMessage *SecretMessage `json:"vcs-config"`
UrlPattern *UrlPattern `json:"url-pattern"`
}

type Config struct {
DbPath string `json:"dbpath"`
Repos map[string]*Repo `json:"repos"`
}

// TODO(knorton): Hopefully this is a temporary measure while I straighten
// out what I broke. The issue is we cannot marshal Repos once I put the
// RawMessage in there.
func (r *Repo) UnmarshalJSON(b []byte) error {
var repo struct {
Url string `json:"url"`
MsBetweenPolls int `json:"ms-between-poll"`
Vcs string `json:"vcs"`
VcsConfig json.RawMessage `json:"vcs-config"`
UrlPattern *UrlPattern `json:"url-pattern"`
}
// SecretMessage is just like json.RawMessage but it will not
// marshal its value as JSON. This is to ensure that vcs-config
// is not marshalled into JSON and send to the UI.
type SecretMessage []byte

if err := json.Unmarshal(b, &repo); err != nil {
return err
}
// This always marshals to an empty object.
func (s *SecretMessage) MarshalJSON() ([]byte, error) {
return []byte("{}"), nil
}

r.Url = repo.Url
r.MsBetweenPolls = repo.MsBetweenPolls
r.Vcs = repo.Vcs
r.VcsConfig = repo.VcsConfig
r.UrlPattern = repo.UrlPattern
// See http://golang.org/pkg/encoding/json/#RawMessage.UnmarshalJSON
func (s *SecretMessage) UnmarshalJSON(b []byte) error {
if b == nil {
return errors.New("SecretMessage: UnmarshalJSON on nil pointer")
}
*s = append((*s)[0:0], b...)
return nil
}

// Get the JSON encode vcs-config for this repo. This returns nil if
// the repo doesn't declare a vcs-config.
func (r *Repo) VcsConfig() []byte {
if r.VcsConfigMessage == nil {
return nil
}
return *r.VcsConfigMessage
}

// Populate missing config values with default values.
func initRepo(r *Repo) {
if r.MsBetweenPolls == 0 {
Expand Down
2 changes: 1 addition & 1 deletion src/hound/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func TestExampleConfigsAreValid(t *testing.T) {

// Ensure that each of the declared vcs's are legit
for _, repo := range cfg.Repos {
_, err := vcs.New(repo.Vcs, repo.VcsConfig)
_, err := vcs.New(repo.Vcs, repo.VcsConfig())
if err != nil {
t.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion src/hound/searcher/searcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ func newSearcher(dbpath, name string, repo *config.Repo, refs *foundRefs) (*Sear

log.Printf("Searcher started for %s", name)

wd, err := vcs.New(repo.Vcs, repo.VcsConfig)
wd, err := vcs.New(repo.Vcs, repo.VcsConfig())
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 851b9cc

Please sign in to comment.