예제 #1
0
// Update updates the form gallery in the MongoDB database
// collection.
func Update(context interface{}, db *db.DB, id string, gallery *Gallery) error {
	log.Dev(context, "Update", "Started : Gallery[%s]", id)

	if !bson.IsObjectIdHex(id) {
		log.Error(context, "Update", ErrInvalidID, "Completed")
		return ErrInvalidID
	}

	if err := gallery.Validate(); err != nil {
		log.Error(context, "Update", err, "Completed")
		return err
	}

	objectID := bson.ObjectIdHex(id)

	gallery.DateUpdated = time.Now()

	f := func(c *mgo.Collection) error {
		log.Dev(context, "Update", "MGO : db.%s.update(%s, %s)", c.Name, mongo.Query(objectID), mongo.Query(gallery))
		return c.UpdateId(objectID, gallery)
	}

	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		log.Error(context, "Update", err, "Completed")
		return err
	}

	log.Dev(context, "Update", "Completed")
	return nil
}
예제 #2
0
// List retrives the form galleries for a given form from the MongoDB database
// collection.
func List(context interface{}, db *db.DB, formID string) ([]Gallery, error) {
	log.Dev(context, "List", "Started")

	if !bson.IsObjectIdHex(formID) {
		log.Error(context, "List", ErrInvalidID, "Completed")
		return nil, ErrInvalidID
	}

	formObjectID := bson.ObjectIdHex(formID)

	var galleries = make([]Gallery, 0)
	f := func(c *mgo.Collection) error {
		q := bson.M{
			"form_id": formObjectID,
		}
		log.Dev(context, "List", "MGO : db.%s.find(%s)", c.Name, mongo.Query(q))
		return c.Find(q).All(&galleries)
	}

	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		log.Error(context, "List", err, "Completed")
		return nil, err
	}

	if err := hydrateMany(context, db, galleries); err != nil {
		log.Error(context, "List", err, "Completed")
		return nil, err
	}

	log.Dev(context, "List", "Completed")
	return galleries, nil
}
예제 #3
0
파일: regex.go 프로젝트: coralproject/xenia
// GetAll retrieves a list of regexs.
func GetAll(context interface{}, db *db.DB, tags []string) ([]Regex, error) {
	log.Dev(context, "GetAll", "Started : Tags[%v]", tags)

	key := "grs" + strings.Join(tags, "-")
	if v, found := cache.Get(key); found {
		rgxs := v.([]Regex)
		log.Dev(context, "GetAll", "Completed : CACHE : Rgxs[%d]", len(rgxs))
		return rgxs, nil
	}

	var rgxs []Regex
	f := func(c *mgo.Collection) error {
		log.Dev(context, "GetAll", "MGO : db.%s.find({}).sort([\"name\"])", c.Name)
		return c.Find(nil).All(&rgxs)
	}

	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		if err == mgo.ErrNotFound {
			err = ErrNotFound
		}

		log.Error(context, "GetAll", err, "Completed")
		return nil, err
	}

	if rgxs == nil {
		log.Error(context, "GetAll", ErrNotFound, "Completed")
		return nil, ErrNotFound
	}

	cache.Set(key, rgxs, gc.DefaultExpiration)

	log.Dev(context, "GetAll", "Completed : Rgxs[%d]", len(rgxs))
	return rgxs, nil
}
예제 #4
0
// Remove removes an item into the items collection and remove any
// corresponding quads from the graph database.
func Remove(context interface{}, db *db.DB, graph *cayley.Handle, itemID string) error {
	log.Dev(context, "Remove", "Started : ID[%s]", itemID)

	// Get the item from the items collection.
	items, err := item.GetByIDs(context, db, []string{itemID})
	if err != nil {
		log.Error(context, "Remove", err, "Completed")
		return err
	}

	// Prepare the item map data.
	itmMap := map[string]interface{}{
		"item_id": items[0].ID,
		"type":    items[0].Type,
		"version": items[0].Version,
		"data":    items[0].Data,
	}

	// Remove the corresponding relationships from the graph.
	if err := wire.RemoveFromGraph(context, db, graph, itmMap); err != nil {
		log.Error(context, "Remove", err, "Completed")
		return err
	}

	// Delete the item.
	if err := item.Delete(context, db, itemID); err != nil {
		log.Error(context, "Remove", err, "Completed")
		return err
	}

	log.Dev(context, "Remove", "Completed")
	return nil
}
예제 #5
0
파일: auth.go 프로젝트: DmitryZinchenko/kit
// Auth handles token authentication.
func Auth(h app.Handler) app.Handler {

	// Check if authentication is turned off.
	on, err := cfg.Bool(cfgAuth)
	if err == nil && !on {
		return func(c *app.Context) error {
			log.Dev(c.SessionID, "Auth", "******> Authentication Off")
			return h(c)
		}
	}

	// Turn authentication on.
	return func(c *app.Context) error {
		token := c.Request.Header.Get("Authorization")
		log.Dev(c.SessionID, "Auth", "Started : Token[%s]", token)

		if len(token) < 5 || token[0:5] != "Basic" {
			log.Error(c.SessionID, "Auth", app.ErrNotAuthorized, "Validating token")
			return app.ErrNotAuthorized
		}

		var err error
		if c.User, err = auth.ValidateWebToken(c.SessionID, c.DB, token[6:]); err != nil {
			log.Error(c.SessionID, "Auth", err, "Validating token")
			return app.ErrNotAuthorized
		}

		log.Dev(c.SessionID, "Auth", "Completed")
		return h(c)
	}
}
예제 #6
0
// Create adds a new Submission based on a given Form into
// the MongoDB database collection.
func Create(context interface{}, db *db.DB, formID string, submission *Submission) error {
	log.Dev(context, "Create", "Started : Form[%s]", formID)

	if !bson.IsObjectIdHex(formID) {
		log.Error(context, "Create", ErrInvalidID, "Completed")
		return ErrInvalidID
	}

	if err := submission.Validate(); err != nil {
		return err
	}

	// FIXME: handle Number field maybe with https://docs.mongodb.com/v3.0/tutorial/create-an-auto-incrementing-field/ to resolve race condition
	count, err := Count(context, db, formID)
	if err != nil {
		log.Error(context, "Create", err, "Completed")
		return err
	}

	submission.Number = count + 1

	f := func(c *mgo.Collection) error {
		log.Dev(context, "Create", "MGO : db.%s.insert(%s)", c.Name, mongo.Query(submission))
		return c.Insert(submission)
	}

	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		log.Error(context, "Create", err, "Completed")
		return err
	}

	log.Dev(context, "Create", "Completed")
	return nil
}
예제 #7
0
파일: auth.go 프로젝트: DmitryZinchenko/kit
// CreateWebToken return a token and session that can be used to authenticate a user.
func CreateWebToken(context interface{}, db *db.DB, u *User, expires time.Duration) (string, error) {
	log.Dev(context, "CreateWebToken", "Started : PublicID[%s]", u.PublicID)

	// Do we have a valid session right now?
	s, err := session.GetByLatest(context, db, u.PublicID)
	if err != nil && err != mgo.ErrNotFound {
		log.Error(context, "CreateUser", err, "Completed")
		return "", err
	}

	// If we don't have one or it has been expired create
	// a new one.
	if err == mgo.ErrNotFound || s.IsExpired(context) {
		if s, err = session.Create(context, db, u.PublicID, expires); err != nil {
			log.Error(context, "CreateUser", err, "Completed")
			return "", err
		}
	}

	// Set the return arguments though we will explicitly
	// return them. Don't want any confusion.
	token, err := u.WebToken(s.SessionID)
	if err != nil {
		log.Error(context, "CreateUser", err, "Completed")
		return "", err
	}

	log.Dev(context, "CreateWebToken", "Completed : WebToken[%s]", token)
	return token, nil
}
예제 #8
0
파일: auth.go 프로젝트: DmitryZinchenko/kit
// GetUserWebToken return a token if one exists and is valid.
func GetUserWebToken(context interface{}, db *db.DB, publicID string) (string, error) {
	log.Dev(context, "GetUserWebToken", "Started : PublicID[%s]", publicID)

	// Do we have a valid session right now?
	s, err := session.GetByLatest(context, db, publicID)
	if err != nil {
		log.Error(context, "GetUserWebToken", err, "Completed")
		return "", err
	}

	// If it is expired return failure.
	if s.IsExpired(context) {
		err := errors.New("Session expired.")
		log.Error(context, "GetUserWebToken", err, "Completed")
		return "", err
	}

	// Pull the user information.
	u, err := GetUserByPublicID(context, db, publicID, true)
	if err != nil {
		log.Error(context, "GetUserWebToken", err, "Completed")
		return "", err
	}

	// Generate a token that works right now.
	token, err := u.WebToken(s.SessionID)
	if err != nil {
		log.Error(context, "GetUserWebToken", err, "Completed")
		return "", err
	}

	log.Dev(context, "GetUserWebToken", "Completed : WebToken[%s]", token)
	return token, nil
}
예제 #9
0
파일: auth.go 프로젝트: DmitryZinchenko/kit
// UpdateUserPassword updates an existing user's password and token in the database.
func UpdateUserPassword(context interface{}, db *db.DB, u *User, password string) error {
	log.Dev(context, "UpdateUserPassword", "Started : PublicID[%s]", u.PublicID)

	if err := u.Validate(); err != nil {
		log.Error(context, "UpdateUserPassword", err, "Completed")
		return err
	}

	if len(password) < 8 {
		err := errors.New("Invalid password length")
		log.Error(context, "UpdateUserPassword", err, "Completed")
		return err
	}

	newPassHash, err := crypto.BcryptPassword(u.PrivateID + password)
	if err != nil {
		log.Error(context, "UpdateUserPassword", err, "Completed")
		return err
	}

	f := func(c *mgo.Collection) error {
		q := bson.M{"public_id": u.PublicID}
		upd := bson.M{"$set": bson.M{"password": newPassHash, "modified_at": time.Now().UTC()}}
		log.Dev(context, "UpdateUserPassword", "MGO : db.%s.Update(%s, CAN'T SHOW)", c.Name, mongo.Query(q))
		return c.Update(q, upd)
	}

	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		log.Error(context, "UpdateUserPassword", err, "Completed")
		return err
	}

	log.Dev(context, "UpdateUserPassword", "Completed")
	return nil
}
예제 #10
0
// TransformRow transform a row of data into the coral schema
func TransformRow(row map[string]interface{}, strategyTableName string) (interface{}, []map[string]interface{}, error) { // id row, transformation, error

	var newRows []map[string]interface{}
	var err error

	table := strategy.GetEntities()[strategyTableName]
	idField := GetID(strategyTableName)
	id := row[idField]

	if table.Local == "" {
		return "", nil, fmt.Errorf("No table %v found in the strategy file.", table)
	}

	// if has an array field type array
	if strategy.HasArrayField(table) {

		newRows, err = transformRowWithArrayField(strategyTableName, row, table.Fields)
		if err != nil {
			log.Error(uuid, "fiddler.transformRow", err, "Transform the row into several coral documents.")
		}
	} else {
		newRow, err := transformRow(strategyTableName, row, table.Fields)
		if err != nil {
			log.Error(uuid, "fiddler.transformRow", err, "Transform the row into coral.")
			return id, nil, err
		}
		newRows = append(newRows, newRow)
	}

	return id, newRows, err
}
예제 #11
0
// saveResult processes the $save command for this result.
func saveResult(context interface{}, save map[string]interface{}, results []bson.M, data map[string]interface{}) error {

	// {"$map": "list"}

	// Capture the key and value and process the save.
	for cmd, value := range save {
		name, ok := value.(string)
		if !ok {
			err := fmt.Errorf("Save key \"%v\" is a %T but must be a string", value, value)
			log.Error(context, "saveResult", err, "Extracting save key")
			return err
		}

		switch cmd {

		// Save the results into the map under the specified key.
		case "$map":
			log.Dev(context, "saveResult", "Saving result to map[%s]", name)
			data[name] = results
			return nil

		default:
			err := fmt.Errorf("Invalid save location %q", cmd)
			log.Error(context, "saveResult", err, "Nothing saved")
			return err
		}
	}

	err := errors.New("Missing save document")
	log.Error(context, "saveResult", err, "Nothing saved")
	return err
}
예제 #12
0
파일: main.go 프로젝트: DmitryZinchenko/kit
func main() {
	const context = "main"

	// Create a task value for execution.
	t := Task{
		Name: "test task",
	}

	// Start the job running with a specified duration.
	if err := runner.Run(context, time.Second, &t); err != nil {
		switch err {
		case runner.ErrTimeout:

			// The task did not finish within the specified duration.
			log.Error(context, "main", err, "Task timeout")

		case runner.ErrSignaled:

			// The user hit <control> c and we shutdown early.
			log.Error(context, "main", err, "Shutdown early")

		default:

			// An error occurred in the processing of the task.
			log.Error(context, "main", err, "Processing error")
		}

		os.Exit(1)
	}

	log.User(context, "main", "Completed")
}
예제 #13
0
// UpdateStatus updates a form submissions status inside the MongoDB database
// collection.
func UpdateStatus(context interface{}, db *db.DB, id, status string) (*Submission, error) {
	log.Dev(context, "UpdateStatus", "Started : Submission[%s]", id)

	if !bson.IsObjectIdHex(id) {
		log.Error(context, "UpdateStatus", ErrInvalidID, "Completed")
		return nil, ErrInvalidID
	}

	objectID := bson.ObjectIdHex(id)

	f := func(c *mgo.Collection) error {
		u := bson.M{
			"$set": bson.M{
				"status":       status,
				"date_updated": time.Now(),
			},
		}
		log.Dev(context, "UpdateStatus", "MGO : db.%s.update(%s, %s)", c.Name, mongo.Query(objectID), mongo.Query(u))
		return c.UpdateId(objectID, u)
	}

	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		log.Error(context, "UpdateStatus", err, "Completed")
		return nil, err
	}

	submission, err := Retrieve(context, db, id)
	if err != nil {
		log.Error(context, "UpdateStatus", err, "Completed")
		return nil, err
	}

	log.Dev(context, "UpdateStatus", "Completed")
	return submission, nil
}
예제 #14
0
// Count returns the count of current submissions for a given
// form id in the Form Submissions MongoDB database collection.
func Count(context interface{}, db *db.DB, formID string) (int, error) {
	log.Dev(context, "Count", "Completed : Form[%s]", formID)

	if !bson.IsObjectIdHex(formID) {
		log.Error(context, "Count", ErrInvalidID, "Completed")
		return 0, ErrInvalidID
	}

	formObjectID := bson.ObjectIdHex(formID)

	var count int
	f := func(c *mgo.Collection) error {
		var err error

		q := bson.M{
			"form_id": formObjectID,
		}
		log.Dev(context, "Count", "MGO : db.%s.find(%s).count()", c.Name, mongo.Query(q))
		count, err = c.Find(q).Count()
		return err
	}

	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		log.Error(context, "Count", err, "Completed")
		return 0, err
	}

	log.Dev(context, "Count", "Completed")
	return count, nil
}
예제 #15
0
// RetrieveMany retrieves a list of Submission's from the MongoDB database collection.
func RetrieveMany(context interface{}, db *db.DB, ids []string) ([]Submission, error) {
	log.Dev(context, "RetrieveMany", "Started")

	var objectIDs = make([]bson.ObjectId, len(ids))

	for i, id := range ids {
		if !bson.IsObjectIdHex(id) {
			log.Error(context, "RetrieveMany", ErrInvalidID, "Completed")
			return nil, ErrInvalidID
		}

		objectIDs[i] = bson.ObjectIdHex(id)
	}

	var submissions []Submission
	f := func(c *mgo.Collection) error {
		q := bson.M{
			"_id": bson.M{
				"$in": objectIDs,
			},
		}
		log.Dev(context, "RetrieveMany", "MGO : db.%s.find(%s)", c.Name, mongo.Query(q))
		return c.Find(q).All(&submissions)
	}

	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		log.Error(context, "RetrieveMany", err, "Completed")
		return nil, err
	}

	log.Dev(context, "RetrieveMany", "Started")
	return submissions, nil
}
예제 #16
0
// RemoveFlag removes a flag from a given Submission in
// the MongoDB database collection.
func RemoveFlag(context interface{}, db *db.DB, id, flag string) (*Submission, error) {
	log.Dev(context, "RemoveFlag", "Started : Submission[%s]", id)

	if !bson.IsObjectIdHex(id) {
		log.Error(context, "RemoveFlag", ErrInvalidID, "Completed")
		return nil, ErrInvalidID
	}

	objectID := bson.ObjectIdHex(id)

	f := func(c *mgo.Collection) error {
		u := bson.M{
			"$pull": bson.M{
				"flags": flag,
			},
		}
		log.Dev(context, "RemoveFlag", "MGO : db.%s.update(%s, %s)", c.Name, mongo.Query(objectID), mongo.Query(u))
		return c.UpdateId(objectID, u)
	}

	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		log.Error(context, "RemoveFlag", err, "Completed")
		return nil, err
	}

	submission, err := Retrieve(context, db, id)
	if err != nil {
		log.Error(context, "RemoveFlag", err, "Completed")
		return nil, err
	}

	log.Dev(context, "RemoveFlag", "Completed")
	return submission, nil
}
예제 #17
0
파일: main.go 프로젝트: coralproject/sponge
func main() {

	// Initialize logging
	logLevel := func() int {
		ll, err := cfg.Int(cfgLoggingLevel)
		if err != nil {
			return log.USER
		}
		return ll
	}
	log.Init(os.Stderr, logLevel)

	// Generate UUID to use with the logs
	uid := uuid.New()

	if err := sponge.Init(uid); err != nil {
		log.Error(uid, "main", err, "Unable to initialize configuration.")
		os.Exit(-1)
	}

	if err := cmd.RootCmd.Execute(); err != nil {
		log.Error(uid, "main", err, "Unable to execute the command.")
		os.Exit(-1)
	}
}
예제 #18
0
파일: ask.go 프로젝트: coralproject/xenia
// UpsertForm upserts the provided form into the MongoDB database collection and
// creates a gallery based on it.
func UpsertForm(context interface{}, db *db.DB, f *form.Form) error {
	log.Dev(context, "UpsertForm", "Started : Form[%s]", f.ID.Hex())

	var isNewForm bool

	// If there was no ID provided, we should set one. UpsertForm might optionally add
	// a form ID to ensure that we don't duplicate the FormGallery.
	if f.ID.Hex() == "" {
		isNewForm = true
	}

	if err := form.Upsert(context, db, f); err != nil {
		log.Error(context, "UpsertForm", err, "Completed")
		return err
	}

	if isNewForm {

		// Create the new gallery that we will create that is based on the current
		// form ID.
		g := gallery.Gallery{
			FormID: f.ID,
		}

		if err := gallery.Create(context, db, &g); err != nil {
			log.Error(context, "UpsertForm", err, "Completed")
			return err
		}
	}

	log.Dev(context, "UpsertForm", "Completed")
	return nil
}
예제 #19
0
파일: ask.go 프로젝트: coralproject/xenia
// DeleteSubmission deletes a submission as well as updating a form's stats.
func DeleteSubmission(context interface{}, db *db.DB, id, formID string) error {
	log.Dev(context, "DeleteSubmission", "Started : Submission[%s]", id)

	if !bson.IsObjectIdHex(id) {
		log.Error(context, "DeleteSubmission", ErrInvalidID, "Completed")
		return ErrInvalidID
	}

	if !bson.IsObjectIdHex(formID) {
		log.Error(context, "Delete", ErrInvalidID, "Completed")
		return ErrInvalidID
	}

	if err := submission.Delete(context, db, id); err != nil {
		log.Error(context, "DeleteSubmission", err, "Completed")
		return err
	}

	if _, err := form.UpdateStats(context, db, formID); err != nil {
		log.Error(context, "DeleteSubmission", err, "Completed")
		return err
	}

	log.Dev(context, "DeleteSubmission", "Started")
	return nil
}
예제 #20
0
파일: api.go 프로젝트: coralproject/sponge
// ConnectionMySQL returns the connection string
func connectionAPI(pageAfter string) *url.URL {

	credA, ok := credential.(str.CredentialService)
	if !ok {
		err := fmt.Errorf("Error when asserting type CredentialService on credential.")
		log.Error(uuid, "api.connectionAPI", err, "Asserting type.")
	}

	data := QueryData{}
	// Get all the data from credentials we need
	data.Basicurl = credA.GetEndpoint() //"https://comments-api.ext.nile.works/v1/search"
	data.Appkey = credA.GetAppKey()
	data.Next = pageAfter                                        //credA.GetPageAfterField()                        // field that we are going to get the next value from
	data.Attributes = credA.GetAttributes()                      // Attributes for the query. Eg, for WaPo we have scope and sortOrder
	urltemplate, urltemplatepagination := credA.GetQueryFormat() //format for the query
	regexToEscape := credA.GetRegexToEscape()

	//url.QueryEscape(

	surl, err := formatURL(data, urltemplate, urltemplatepagination, regexToEscape)
	if err != nil {
		log.Error(uuid, "api.connectionAPI", err, "Parsing url %s", surl)
	}

	u, err := url.Parse(surl)
	if err != nil {
		log.Error(uuid, "api.connectionAPI", err, "Parsing url %s", surl)
	}

	return u
}
예제 #21
0
파일: auth.go 프로젝트: DmitryZinchenko/kit
// DecodeWebToken breaks a web token into its parts.
func DecodeWebToken(context interface{}, webToken string) (sessionID string, token string, err error) {
	log.Dev(context, "DecodeWebToken", "Started : WebToken[%s]", webToken)

	// Decode the web token to break it into its parts.
	data, err := base64.StdEncoding.DecodeString(webToken)
	if err != nil {
		log.Error(context, "DecodeWebToken", err, "Completed")
		return "", "", err
	}

	// Split the web token.
	str := strings.Split(string(data), ":")
	if len(str) != 2 {
		err := errors.New("Invalid token")
		log.Error(context, "DecodeWebToken", err, "Completed")
		return "", "", err
	}

	// Pull out the session and token.
	sessionID = str[0]
	token = str[1]

	log.Dev(context, "DecodeWebToken", "Completed : SessionID[%s] Token[%s]", sessionID, token)
	return sessionID, token, nil
}
예제 #22
0
// Retrieve retrieves a form gallery from the MongoDB database
// collection as well as hydrating the form gallery with form submissions.
func Retrieve(context interface{}, db *db.DB, id string) (*Gallery, error) {
	log.Dev(context, "Retrieve", "Started : Gallery[%s]", id)

	if !bson.IsObjectIdHex(id) {
		log.Error(context, "Retrieve", ErrInvalidID, "Completed")
		return nil, ErrInvalidID
	}

	objectID := bson.ObjectIdHex(id)

	var gallery Gallery
	f := func(c *mgo.Collection) error {
		log.Dev(context, "Retrieve", "MGO : db.%s.find(%s)", c.Name, mongo.Query(objectID))
		return c.FindId(objectID).One(&gallery)
	}

	if err := db.ExecuteMGO(context, Collection, f); err != nil {
		log.Error(context, "Retrieve", err, "Completed")
		return nil, err
	}

	if err := hydrate(context, db, &gallery); err != nil {
		log.Error(context, "Retrieve", err, "Completed")
		return nil, err
	}

	log.Dev(context, "Retrieve", "Completed")
	return &gallery, nil
}
예제 #23
0
// New creates a new strategy struct variable from the json file
func New() (Strategy, error) {

	var strategy Strategy
	var err error

	//read STRATEGY_CONF env variable
	strategyFile := os.Getenv("STRATEGY_CONF")
	if strategyFile == "" {
		log.Fatal(uuid, "strategy.new", "Enviromental variable STRATEGY_CONF not setup.")
		return strategy, err
	}

	strategy, err = read(strategyFile)
	if err != nil {
		log.Error(uuid, "strategy.new", err, "Reading strategy file %s.", strategyFile)
		return Strategy{}, err
	}

	err = strategy.setCredential()
	if err != nil {
		log.Error(uuid, "strategy.new", err, "Setting credentials.")
		return Strategy{}, err
	}

	return strategy, err
}
예제 #24
0
// varLookup looks up variables and returns their values as the specified type.
func varLookup(context interface{}, cmd, variable string, vars map[string]string, results map[string]interface{}) (interface{}, error) {

	// {"field": "#cmd:variable"}
	// Before: {"field": "#number:variable_name"}  		After: {"field": 1234}
	// Before: {"field": "#string:variable_name"}  		After: {"field": "value"}
	// Before: {"field": "#date:variable_name"}    		After: {"field": time.Time}
	// Before: {"field": "#objid:variable_name"}   		After: {"field": mgo.ObjectId}
	// Before: {"field": "#regex:/pattern/<options>"}   After: {"field": bson.RegEx}
	// Before: {"field": "#since:3600"}   				After: {"field": time.Time}
	// Before: {"field": "#data.0:doc.station_id"}   	After: {"field": "23453"}

	// If the variable does not exist, use the variable straight up.
	param, exists := vars[variable]
	if !exists {
		param = variable
	}

	// Do we have a command that is not known.
	if len(cmd) < 4 {
		err := fmt.Errorf("Unknown command %q", cmd)
		log.Error(context, "varLookup", err, "Checking cmd is proper length")
		return nil, err
	}

	// Let's perform the right action per command.
	switch cmd[0:4] {
	case "numb":
		return number(context, param)

	case "stri":
		return param, nil

	case "date":
		return isoDate(context, param)

	case "obji":
		return objID(context, param)

	case "rege":
		return regExp(context, param)

	case "time":
		return adjTime(context, param)

	case "data":
		if len(cmd) == 6 {
			return dataLookup(context, cmd[5:6], param, results)
		}

		err := errors.New("Data command is missing the operator")
		log.Error(context, "varLookup", err, "Checking cmd is data")
		return nil, err

	default:
		err := fmt.Errorf("Unknown command %q", cmd)
		log.Error(context, "varLookup", err, "Checking cmd in default case")
		return nil, err
	}
}
예제 #25
0
func process(coralName string, data []map[string]interface{}) {

	// Transform the data row by row
	log.User(uuid, "sponge.process", "# Transforming data to the coral schema.\n")
	log.User(uuid, "sponge.process", "# And importing %v documents.", len(data))

	// Initialize benchmarking for current table
	start := time.Now()
	blockStart := time.Now()
	blockSize := int64(1000) // number of documents between each report
	documents := int64(0)
	totalDocuments := int64(len(data))

	for _, row := range data {

		// output benchmarking for each block of documents
		if documents%blockSize == 0 && documents > 0 {

			// calculate stats
			percentComplete := float64(documents) / float64(totalDocuments) * float64(100)
			msSinceStart := time.Since(start).Nanoseconds() / int64(1000000)
			msSinceBlock := time.Since(blockStart).Nanoseconds() / int64(1000000)
			timeRemaining := int64(float64(time.Since(start).Seconds()) / float64(percentComplete) * float64(100))

			//log stats
			log.User(uuid, "sponge.process", "%v%% (%v/%v imported) %vms, %vms avg - last %v in %vms, %vms avg -- est time remaining %vs\n", int64(percentComplete), documents, totalDocuments, msSinceStart, msSinceStart/documents, blockSize, msSinceBlock, msSinceBlock/blockSize, int64(timeRemaining))
			blockStart = time.Now()

		}
		documents = documents + 1

		// transform the row
		id, newRows, err := fiddler.TransformRow(row, coralName)
		if err != nil {
			log.Error(uuid, "sponge.process", err, "Error when transforming the row %s.", row)
			//RECORD to report about failing transformation
			if options.ReportOnFailedRecords {
				report.Record(coralName, id, "Failing transform data", err)
			}
		}

		// Usually newRows only will have a document but in the case that we have subcollections
		// we may get more than one document from a transformation
		for _, newRow := range newRows {

			log.Dev(uuid, "sponge.process", "Transforming: %v into %v.", row, newRow)

			// send the row to pillar
			err = coral.AddRow(newRow, coralName)
			if err != nil {
				log.Error(uuid, "sponge.process", err, "Error when adding a row") // thae row %v to %s.", string(newRow), modelName)
				//RECORD to report about failing adding row to coral db
				if options.ReportOnFailedRecords {
					report.Record(coralName, id, "Failing add row to coral", err)
				}
			}
		}
	}
}
예제 #26
0
// GetQueryData returns the raw data from the table based on the ids
func (m MySQL) GetQueryData(entityname string, options *Options, ids []string) ([]map[string]interface{}, error) { //offset int, limit int, orderby string

	// Get the corresponding entity to the entityname
	tableName := strategy.GetEntityForeignName(entityname)
	tableFields := strategy.GetEntityForeignFields(entityname) // []map[string]string

	// open a connection
	db, err := m.open()
	if err != nil {
		log.Error(uuid, "mysql.getquerydata", err, "Error connecting to mysql database.")
		return nil, err
	}
	defer m.close(db)

	// Fields for that external source table
	f := make([]string, 0, len(tableFields))
	for _, field := range tableFields {
		if field != nil {
			f = append(f, field["foreign"].(string))
		}
	}

	// all the fields
	fields := strings.Join(f, ", ")

	// if we are ordering by
	if len(options.Orderby) == 0 {
		options.Orderby = strategy.GetOrderBy(entityname)
	}

	var queryWhere string
	// if we are quering specifics recrords
	if len(ids) > 0 {
		idField := strategy.GetIDField(entityname)
		queryWhere = fmt.Sprintf("where %s in (%s)", idField, strings.Join(ids, ", "))
	}

	// Get only the fields that we are going to use
	// the query string . To Do. Select only the stuff you are going to use
	query := strings.Join([]string{"SELECT", fields, "from", tableName, queryWhere, "order by", options.Orderby, "limit", fmt.Sprintf("%v", options.Offset), ", ", fmt.Sprintf("%v", options.Limit)}, " ")

	data, err := gosqljson.QueryDbToMapJSON(db, "lower", query)
	if err != nil {
		log.Error(uuid, "mysql.getquerydata", err, "Running SQL query.")
		return nil, err
	}

	byt := []byte(data)

	var dat []map[string]interface{}
	err = json.Unmarshal(byt, &dat)
	if err != nil {
		log.Error(uuid, "mysql.getquerydata", err, "Unmarshalling the query.")
		return nil, err
	}

	return dat, nil
}
예제 #27
0
// GetData returns the raw data from that entity
func (m MySQL) GetData(entityname string, options *Options) ([]map[string]interface{}, error) { //offset int, limit int, orderby string, q string

	// Get the corresponding table to the modelName
	tableName := strategy.GetEntityForeignName(entityname)
	tableFields := strategy.GetEntityForeignFields(entityname) // []map[string]string

	// open a connection
	db, err := m.open()
	if err != nil {
		log.Error(uuid, "mysql.getdata", err, "Connecting to mysql database.")
		return nil, err
	}
	defer m.close(db)

	// Fields for that external source table
	f := make([]string, 0, len(tableFields))
	for _, field := range tableFields {
		if field != nil {
			f = append(f, field["foreign"].(string))
		}
	}

	fields := strings.Join(f, ", ")
	if options.Orderby == "" {
		options.Orderby = strategy.GetOrderBy(entityname)
	}

	// Get only the fields that we are going to use
	// the query string . To Do. Select only the stuff you are going to use
	//query := strings.Join([]string{"SELECT", fields, "from", tableName, "order by", orderby, "limit", fmt.Sprintf("%v", offset), ", ", fmt.Sprintf("%v", limit)}, " ")
	var where string
	if options.Query != "" {
		where = fmt.Sprintf("where %s ", options.Query)
	}
	query := fmt.Sprintf("SELECT %s from %s %s order by %s limit %v, %v", fields, tableName, where, options.Orderby, options.Offset, options.Limit)

	data, err := gosqljson.QueryDbToMapJSON(db, "lower", query)
	if err != nil {
		log.Error(uuid, "mysql.getdata", err, "Running SQL query.")
		return nil, err
	}

	byt := []byte(data)

	var dat []map[string]interface{}
	err = json.Unmarshal(byt, &dat)
	if err != nil {
		log.Error(uuid, "mysql.getdata", err, "Unmarshalling the result of the query.")
		return nil, err
	}

	return dat, nil
}
예제 #28
0
// Create creates a new FormSubmission based on the payload of replies and the
// formID that is being submitted.
// 200 Success, 400 Bad Request, 404 Not Found, 500 Internal
func (formSubmissionHandle) Create(c *web.Context) error {
	var payload struct {
		Recaptcha string                   `json:"recaptcha"`
		Answers   []submission.AnswerInput `json:"replies"`
	}
	if err := json.NewDecoder(c.Request.Body).Decode(&payload); err != nil {
		return err
	}

	formID := c.Params["form_id"]

	// We should check to see if the form has a recaptcha property.
	f, err := form.Retrieve(c.SessionID, c.Ctx["DB"].(*db.DB), formID)
	if err != nil {
		return err
	}

	// If the recaptcha is enabled on the form, then we should check that the
	// response contains the data we need and if it's valid.
	if enabled, ok := f.Settings["recaptcha"].(bool); ok && enabled {
		if len(payload.Recaptcha) <= 0 {
			log.Error(c.SessionID, "FormSubmission : Create", ErrInvalidCaptcha, "Payload empty")
			return ErrInvalidCaptcha
		}

		// Check to see if Recaptcha has been enabled on the server.
		if recaptchaSecret, ok := c.Web.Ctx["recaptcha"].(string); ok {

			// Communicate with the Google Recaptcha Web Service to validate the
			// request.
			if err := ValidateReacaptchaResponse(c, recaptchaSecret, payload.Recaptcha); err != nil {
				log.Error(c.SessionID, "FormSubmission : Create", err, "Recaptcha validation failed")
				return ErrInvalidCaptcha
			}
		} else {
			log.Dev(c.SessionID, "FormSubmission : Create", "Recaptcha disabled, will not check")
		}

	}

	s, err := ask.CreateSubmission(c.SessionID, c.Ctx["DB"].(*db.DB), formID, payload.Answers)
	if err != nil {
		return err
	}

	c.Respond(s, http.StatusOK)

	return nil
}
예제 #29
0
// API returns a handler for a set of routes.
func API() http.Handler {
	mongoURI := cfg.MustURL(cfgMongoURI)

	// The web framework middleware for Mongo is using the name of the
	// database as the name of the master session by convention. So use
	// cfg.DB as the second argument when creating the master session.
	if err := db.RegMasterSession("startup", mongoURI.Path, mongoURI.String(), 25*time.Second); err != nil {
		log.Error("startup", "Init", err, "Initializing MongoDB")
		os.Exit(1)
	}

	w := web.New(logm.Midware, errorm.Midware)

	publicKey, err := cfg.String(cfgAuthPublicKey)
	if err != nil || publicKey == "" {
		log.User("startup", "Init", "%s is missing, internal authentication is disabled", cfgAuthPublicKey)
	}

	// If the public key is provided then add the auth middleware or fail using
	// the provided public key.
	if publicKey != "" {
		log.Dev("startup", "Init", "Initializing Auth")

		authm, err := authm.Midware(publicKey, authm.MidwareOpts{})
		if err != nil {
			log.Error("startup", "Init", err, "Initializing Auth")
			os.Exit(1)
		}

		// Apply the authentication middleware on top of the application as the
		// first middleware.
		w.Use(authm)
	}

	// Add the Mongo and Cayley middlewares possibly after the auth middleware.
	w.Use(mongo.Midware(mongoURI), cayley.Midware(mongoURI))

	if cors, err := cfg.Bool(cfgEnableCORS); err == nil && cors {
		log.Dev("startup", "Init", "Initializing CORS : CORS Enabled")
		w.Use(w.CORS())
	} else {
		log.Dev("startup", "Init", "CORS Disabled")
	}

	log.Dev("startup", "Init", "Initalizing routes")
	routes(w)

	return w
}
예제 #30
0
// Midware for catching errors.
func Midware(next web.Handler) web.Handler {

	// Create the handler that will be attached in the middleware chain.
	h := func(c *web.Context) error {

		log.Dev(c.SessionID, "error : Midware", "Started")

		// In the event of a panic, we want to capture it here so we can send an
		// error down the stack.
		defer func() {
			if err := recover(); err != nil {

				// Respond with the error.
				c.RespondError("internal server error", http.StatusInternalServerError)

				// Log out that we caught the error.
				switch err := err.(type) {
				case error:
					log.Error(c.SessionID, "error : Midware", err, "Panic Caught")
				default:
					log.Error(c.SessionID, "error : Midware", fmt.Errorf("%v", err), "Panic Caught")
				}

				// Print out the stack.
				log.Dev(c.SessionID, "error : Midware", "Panic Stacktrace:\n%s", debug.Stack())

				_, filePath, line, _ := runtime.Caller(4)
				log.Dev(c.SessionID, "error : Midware", "Panic Traced to %s:%d", filePath, line)
			}
		}()

		if err := next(c); err != nil {

			// Respond with the error.
			c.Error(err)

			// Log out that we caught the error.
			log.Dev(c.SessionID, "error : Midware", "Completed : Error Caught : %s", err.Error())

			return nil
		}

		log.Dev(c.SessionID, "error : Midware", "Completed")

		return nil
	}

	return h
}