Beispiel #1
0
func (a *Advisory) APIRequest(user *models.User, action string, value string) (interface{}, error) {
	if a.Ready {
		return nil, ErrAdvisoryAlreadyReady
	}

	switch action {
	case "type":
		a.Type = value
		a.model.ParentList().AddActivity(user, fmt.Sprintf("[Advisory] switched type to %v", value))
	case "summary":
		a.Summary = value
		a.model.ParentList().AddActivity(user, fmt.Sprintf("[Advisory] switched summary to %v", value))
	case "description":
		a.Description = value
		a.model.ParentList().AddActivity(user, fmt.Sprintf("[Advisory] switched description to %v", value))

	case "existingAdv":
		a.ExistingAdvisoryID = uint(to.Uint64(value))
		if a.ExistingAdvisoryID == 0 {
			a.model.ParentList().AddActivity(user, "[Advisory] detached from existing advisory")
		} else {
			a.model.ParentList().AddActivity(user, fmt.Sprintf("[Advisory] attached to existing advisory %v", a.ExistingAdvisoryID))
		}
	case "ready":
		if a.ExistingAdvisoryID != 0 {
			a.Ready = true
		} else {
			if a.Type == "" || a.Summary == "" || a.Description == "" {
				return nil, ErrAdvisoryNotReady
			}
		}
		a.model.ParentList().AddActivity(user, "[Advisory] marked ready")
	default:
		return nil, ErrAdvisoryNoAction
	}

	if err := a.save(); err != nil {
		return nil, err
	}

	return map[string]interface{}{
		"success": true,
	}, nil
}
Beispiel #2
0
// Accept tells ABF to publish the build lists specified in the List.
func (a *ABF) Accept(m *models.List) error {
	for _, v := range strings.Split(m.IntegrationOne, ";") {
		noBrackets := v[1 : len(v)-1]
		id := to.Uint64(noBrackets)
		req, err := http.NewRequest("PUT", abfURL+"/api/v1/build_lists/"+to.String(id)+"/publish.json", nil)
		if err != nil {
			return err
		}

		req.SetBasicAuth(abfUser, abfAPIKey)
		req.Header.Add("Content-Length", "0")

		resp, err := abfClient.Do(req)
		if err != nil {
			return err
		}

		defer resp.Body.Close()
	}
	return nil
}
Beispiel #3
0
// BuildGetHandler displays build information for a specific build
func BuildGetHandler(ctx context.Context, rw http.ResponseWriter, r *http.Request) {
	dataRenderer := data.FromContext(ctx)

	toRender := map[string]interface{}{}

	id := to.Uint64(pat.Param(ctx, "id"))

	var pkg models.List
	if err := models.DB.Where("id = ?", id).First(&pkg).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			panic(ErrNotFound)
		} else {
			panic(err)
		}
	}

	toRender["Title"] = "Build " + to.String(id) + ": " + pkg.Name
	toRender["Nav"] = 2
	toRender["ID"] = to.String(id)

	dataRenderer.Data = toRender
	dataRenderer.Template = "builds/build"
}
Beispiel #4
0
// Tests datatype conversions.
func TestDataTypes(t *testing.T) {
	var res db.Result
	var items []db.Item

	sess, err := db.Open(wrapperName, settings)

	if err != nil {
		t.Fatalf(err.Error())
	}

	defer sess.Close()

	dataTypes := sess.ExistentCollection("data_types")

	dataTypes.Truncate()

	ids, err := dataTypes.Append(testValues)

	if err != nil {
		t.Fatalf(err.Error())
	}

	found, err := dataTypes.Count(db.Cond{"id": db.Id(ids[0])})

	if err != nil {
		t.Fatalf(err.Error())
	}

	if found == 0 {
		t.Errorf("Expecting an item.")
	}

	// Getting and reinserting (a db.Item).
	item, _ := dataTypes.Find()

	_, err = dataTypes.Append(item)

	if err == nil {
		t.Fatalf("Expecting duplicated-key error.")
	}

	delete(item, "id")

	_, err = dataTypes.Append(item)

	if err != nil {
		t.Fatalf(err.Error())
	}

	// Testing date ranges
	items, err = dataTypes.FindAll(db.Cond{
		"_date": time.Now(),
	})

	if err != nil {
		t.Fatalf(err.Error())
	}

	if len(items) > 0 {
		t.Fatalf("Expecting no results.")
	}

	items, err = dataTypes.FindAll(db.Cond{
		"_date <=": time.Now(),
	})

	if err != nil {
		t.Fatalf(err.Error())
	}

	if len(items) != 2 {
		t.Fatalf("Expecting some results.")
	}

	// Testing struct
	sresults := []testValuesStruct{}

	res, err = dataTypes.Query()

	if err != nil {
		t.Fatalf(err.Error())
	}

	err = res.All(&sresults)

	if err != nil {
		t.Fatalf(err.Error())
	}

	// Testing struct equality
	for _, item := range sresults {
		if reflect.DeepEqual(item, testValues) == false {
			t.Errorf("Struct is different.")
		}
	}

	// Testing maps
	results, _ := dataTypes.FindAll()

	for _, item := range results {

		for key, _ := range item {

			switch key {

			// Signed integers.
			case
				"_int",
				"_int8",
				"_int16",
				"_int32",
				"_int64":
				if to.Int64(item[key]) != testValues.Int64 {
					t.Fatalf("Wrong datatype %v.", key)
				}

			// Unsigned integers.
			case
				"_uint",
				"_uint8",
				"_uint16",
				"_uint32",
				"_uint64":
				if to.Uint64(item[key]) != testValues.Uint64 {
					t.Fatalf("Wrong datatype %v.", key)
				}

			// Floating point.
			case "_float32":
			case "_float64":
				if to.Float64(item[key]) != testValues.Float64 {
					t.Fatalf("Wrong datatype %v.", key)
				}

			// Boolean
			case "_bool":
				if to.Bool(item[key]) != testValues.Bool {
					t.Fatalf("Wrong datatype %v.", key)
				}

			// String
			case "_string":
				if to.String(item[key]) != testValues.String {
					t.Fatalf("Wrong datatype %v.", key)
				}

			// Date
			case "_date":
				if to.Time(item[key]).Equal(testValues.Date) == false {
					t.Fatalf("Wrong datatype %v.", key)
				}
			}
		}
	}

}
Beispiel #5
0
// BuildPostHandler handles post actions that occur to the current active stage.
func BuildPostHandler(ctx context.Context, rw http.ResponseWriter, r *http.Request) {
	// check for authentication
	user := models.FindUser(MustAuthenticate(r))

	// setup
	dataRenderer := data.FromContext(ctx)

	// read parameters
	id := to.Uint64(pat.Param(ctx, "id"))
	target := r.FormValue("target") // either activity or process
	name := r.FormValue("name")     // activity (ignored), process - find process
	action := r.FormValue("action") // activity (ignored), process passed on
	value := r.FormValue("value")   // activity (comment), process passed on

	// find the build list
	var pkg models.List
	if err := models.DB.Where("id = ?", id).First(&pkg).Related(&pkg.Stages, "Stages").Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			panic(ErrNotFound)
		} else {
			panic(err)
		}
	}

	var result interface{}

	// act based on target
	switch target {
	case "activity":
		if value == "" {
			panic(ErrBadRequest)
		}
		pkg.AddActivity(user, value)
		result = map[string]interface{}{
			"success": true,
		}
	case "process":
		// load up the stage & process
		if err := models.DB.Related(&pkg.Stages, "Stages").Error; err != nil {
			panic(err)
		}
		var currentStage *models.ListStage
		for _, v := range pkg.Stages {
			if v.Name == pkg.StageCurrent {
				currentStage = &v
				break
			}
		}

		if currentStage == nil {
			panic(ErrNoCurrentStage)
		}

		if err := models.DB.Related(&currentStage.Processes).Error; err != nil {
			panic(err)
		}

		var selectedProcess *models.ListStageProcess
		for _, v := range currentStage.Processes {
			if v.Name == name {
				selectedProcess = &v
				break
			}
		}

		if selectedProcess == nil {
			panic(ErrBadRequest)
		}

		// initialise the process
		process, err := processes.BuildProcess(selectedProcess)
		if err != nil {
			panic(err)
		}

		r, err := process.APIRequest(user, action, value)
		if err != nil {
			result = map[string]interface{}{
				"error":   true,
				"message": err.Error(),
				"result":  r,
			}
		} else {
			result = r
		}
	default:
		panic(ErrBadRequest)
	}

	dataRenderer.Type = data.DataJSON
	dataRenderer.Data = result

	//http.Redirect(rw, r, r.URL.String(), http.StatusTemporaryRedirect)
}
Beispiel #6
0
// BuildGetJSONHandler displays build information in JSON for a specific build.
func BuildGetJSONHandler(ctx context.Context, rw http.ResponseWriter, r *http.Request) {
	dataRenderer := data.FromContext(ctx)
	id := to.Uint64(pat.Param(ctx, "id"))
	user := models.FindUserNoCreate(Authenticated(r))

	// load the requested build list
	var pkg models.List
	if err := models.DB.Where("id = ?", id).First(&pkg).Related(&pkg.Activity, "Activity").Related(&pkg.Artifacts, "Artifacts").Related(&pkg.Links, "Links").Related(&pkg.Stages, "Stages").Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			panic(ErrNotFound)
		} else {
			panic(err)
		}
	}

	// load stage information
	var stageInfo []buildGetJSONStage

	for _, v := range pkg.Stages {
		if err := models.DB.Related(&v.Processes, "Processes").Error; err != nil && err != gorm.ErrRecordNotFound {
			panic(err)
		}

		// get all process info
		status := map[string]processes.ProcessStatus{}
		metadata := map[string]interface{}{}
		optional := map[string]bool{}

		for _, p := range v.Processes {
			process, err := processes.BuildProcess(&p)
			if err != nil {
				panic(err)
			}

			status[p.Name] = process.Status()
			metadata[p.Name] = process.APIMetadata(user)
			optional[p.Name] = p.Optional
		}

		stageInfo = append(stageInfo, buildGetJSONStage{
			Name:     v.Name,
			Status:   status,
			Metadata: metadata,
			Optional: optional,
		})
	}

	// render the data in a nice way

	dataRenderer.Data = &buildGetJSON{
		ID:       pkg.ID,
		Platform: pkg.Platform,
		Channel:  pkg.Channel,
		Variants: strings.Split(pkg.Variants, ";"),
		Name:     pkg.Name,

		Artifacts: pkg.Artifacts,
		Links:     pkg.Links,
		Activity:  pkg.Activity,
		Changes:   pkg.Changes,

		BuildDate: pkg.BuildDate,
		Updated:   pkg.UpdatedAt,

		PlatformConfig: pkg.PlatformGitConfig,
		Stages:         stageInfo,
		CurrentStage:   pkg.StageCurrent,
		Status:         pkg.StageResult,
		Advisory:       pkg.AdvisoryID,
	}
	dataRenderer.Type = data.DataJSON
}
Beispiel #7
0
// Appends an item (map or struct) into the collection.
func (t *table) Append(item interface{}) (interface{}, error) {

	var pKey []string
	var columns sqlgen.Columns
	var values sqlgen.Values
	var arguments []interface{}
	//var id []interface{}

	cols, vals, err := t.FieldValues(item, toInternal)

	if err != nil {
		return nil, err
	}

	columns = make(sqlgen.Columns, 0, len(cols))
	for i := range cols {
		columns = append(columns, sqlgen.Column{cols[i]})
	}

	arguments = make([]interface{}, 0, len(vals))
	values = make(sqlgen.Values, 0, len(vals))
	for i := range vals {
		switch v := vals[i].(type) {
		case sqlgen.Value:
			// Adding value.
			values = append(values, v)
		default:
			// Adding both value and placeholder.
			values = append(values, sqlPlaceholder)
			arguments = append(arguments, v)
		}
	}

	if pKey, err = t.source.getPrimaryKey(t.tableN(0)); err != nil {
		if err != sql.ErrNoRows {
			// Can't tell primary key.
			return nil, err
		}
	}

	stmt := sqlgen.Statement{
		Type:    sqlgen.SqlInsert,
		Table:   sqlgen.Table{t.tableN(0)},
		Columns: columns,
		Values:  values,
	}

	// No primary keys defined.
	if len(pKey) == 0 {
		var res sql.Result

		if res, err = t.source.doExec(stmt, arguments...); err != nil {
			return nil, err
		}

		// Attempt to use LastInsertId() (probably won't work, but the exec()
		// succeeded, so the error from LastInsertId() is ignored).
		lastID, _ := res.LastInsertId()

		return lastID, nil
	}

	var rows *sql.Rows

	// A primary key was found.
	stmt.Extra = sqlgen.Extra(fmt.Sprintf(`RETURNING "%s"`, strings.Join(pKey, `", "`)))
	if rows, err = t.source.doQuery(stmt, arguments...); err != nil {
		return nil, err
	}

	defer rows.Close()

	var keyMap map[string]interface{}
	err = sqlutil.FetchRow(rows, &keyMap)

	// Does the item satisfy the db.IDSetter interface?
	if setter, ok := item.(db.IDSetter); ok {
		if err := setter.SetID(keyMap); err != nil {
			return nil, err
		}
		return nil, nil
	}

	// The IDSetter interface does not match, we'll be looking for another
	// interface match.
	if len(keyMap) == 1 {

		id := keyMap[pKey[0]]

		// Matches db.Int64IDSetter
		if setter, ok := item.(db.Int64IDSetter); ok {
			if err = setter.SetID(to.Int64(id)); err != nil {
				return nil, err
			}
			return nil, nil
		}

		// Matches db.Uint64IDSetter
		if setter, ok := item.(db.Uint64IDSetter); ok {
			if err = setter.SetID(to.Uint64(id)); err != nil {
				return nil, err
			}
			return nil, nil
		}

		// No interface matched, falling back to old behaviour.
		return to.Int64(id), nil
	}

	// More than one key, no interface matched, let's return a map.
	return keyMap, nil
}