Skip to content
This repository has been archived by the owner on Sep 4, 2021. It is now read-only.

controller: Don't allow artifact type or uri to be empty strings and fix validation error responses #830

Merged
merged 4 commits into from
Jan 26, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 1 addition & 5 deletions cli/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,7 @@ func runEnvGet(args *docopt.Args, client *controller.Client) error {
func setEnv(client *controller.Client, proc string, env map[string]*string) (string, error) {
release, err := client.GetAppRelease(mustApp())
if err == controller.ErrNotFound {
artifact := &ct.Artifact{}
if err := client.CreateArtifact(artifact); err != nil {
return "", err
}
release = &ct.Release{ArtifactID: artifact.ID}
release = &ct.Release{}
if proc != "" {
release.Processes = make(map[string]ct.ProcessType)
release.Processes[proc] = ct.ProcessType{}
Expand Down
6 changes: 6 additions & 0 deletions controller/artifact.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ func (r *ArtifactRepo) Add(data interface{}) error {
if a.ID == "" {
a.ID = random.UUID()
}
if a.Type == "" {
return ct.ValidationError{"type", "must not be empty"}
}
if a.URI == "" {
return ct.ValidationError{"uri", "must not be empty"}
}
err := r.db.QueryRow("INSERT INTO artifacts (artifact_id, type, uri) VALUES ($1, $2, $3) RETURNING created_at",
a.ID, a.Type, a.URI).Scan(&a.CreatedAt)
if e, ok := err.(*pq.Error); ok && e.Code.Name() == "unique_violation" {
Expand Down
12 changes: 11 additions & 1 deletion controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/subtle"
"encoding/base64"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"log"
Expand Down Expand Up @@ -80,8 +81,17 @@ type handlerConfig struct {

// NOTE: this is temporary until httphelper supports custom errors
func respondWithError(w http.ResponseWriter, err error) {
switch err.(type) {
switch v := err.(type) {
case ct.ValidationError:
var detail []byte
if v.Field != "" {
detail, _ = json.Marshal(map[string]string{"field": v.Field})
}
err = httphelper.JSONError{
Code: httphelper.ValidationError,
Message: fmt.Sprintf("%s %s", v.Field, v.Message),
Detail: detail,
}
httphelper.JSON(w, 400, err)
default:
if err == ErrNotFound {
Expand Down
6 changes: 6 additions & 0 deletions controller/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,12 @@ func (s *S) TestProtectedApp(c *C) {
}

func (s *S) createTestArtifact(c *C, in *ct.Artifact) *ct.Artifact {
if in.Type == "" {
in.Type = "docker"
}
if in.URI == "" {
in.URI = fmt.Sprintf("https://example.com/%s", random.String(8))
}
c.Assert(s.c.CreateArtifact(in), IsNil)
return in
}
Expand Down
5 changes: 5 additions & 0 deletions controller/formation.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,11 @@ func (c *controllerAPI) PutFormation(ctx context.Context, w http.ResponseWriter,
return
}

if release.ArtifactID == "" {
respondWithError(w, ct.ValidationError{Message: "release is not deployable"})
return
}

formation.AppID = app.ID
formation.ReleaseID = release.ID
if app.Protected {
Expand Down
18 changes: 15 additions & 3 deletions controller/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,19 @@ func NewReleaseRepo(db *postgres.DB) *ReleaseRepo {
}

func scanRelease(s postgres.Scanner) (*ct.Release, error) {
var artifactID *string
release := &ct.Release{}
var data []byte
err := s.Scan(&release.ID, &release.ArtifactID, &data, &release.CreatedAt)
err := s.Scan(&release.ID, &artifactID, &data, &release.CreatedAt)
if err != nil {
if err == sql.ErrNoRows {
err = ErrNotFound
}
return nil, err
}
if artifactID != nil {
release.ArtifactID = *artifactID
}
release.ID = postgres.CleanUUID(release.ID)
release.ArtifactID = postgres.CleanUUID(release.ArtifactID)
err = json.Unmarshal(data, release)
Expand All @@ -52,10 +56,18 @@ func (r *ReleaseRepo) Add(data interface{}) error {
release.ID = random.UUID()
}

var artifactID *string
if release.ArtifactID != "" {
artifactID = &release.ArtifactID
}

err = r.db.QueryRow("INSERT INTO releases (release_id, artifact_id, data) VALUES ($1, $2, $3) RETURNING created_at",
release.ID, release.ArtifactID, data).Scan(&release.CreatedAt)
release.ID, artifactID, data).Scan(&release.CreatedAt)

release.ID = postgres.CleanUUID(release.ID)
release.ArtifactID = postgres.CleanUUID(release.ArtifactID)
if release.ArtifactID != "" {
release.ArtifactID = postgres.CleanUUID(release.ArtifactID)
}
return err
}

Expand Down
2 changes: 1 addition & 1 deletion controller/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func migrateDB(db *sql.DB) error {

`CREATE TABLE releases (
release_id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
artifact_id uuid NOT NULL REFERENCES artifacts (artifact_id),
artifact_id uuid REFERENCES artifacts (artifact_id),
data text NOT NULL,
created_at timestamptz NOT NULL DEFAULT now(),
deleted_at timestamptz
Expand Down