func (rc *ResourceController) LoadResource(c *echo.Context) (interface{}, error) {
	result, err := rc.DAL.Get(c.Param("id"), rc.Name)
	if err != nil {
		return nil, err
	}

	c.Set(rc.Name, result)
	c.Set("Resource", rc.Name)
	return result, nil
}
func (rc *ResourceController) ShowHandler(c *echo.Context) error {
	c.Set("Action", "read")
	_, err := rc.LoadResource(c)
	if err != nil && err != ErrNotFound {
		return err
	}

	c.Response().Header().Set("Access-Control-Allow-Origin", "*")
	if err == ErrNotFound {
		return c.NoContent(http.StatusNotFound)
	}
	return c.JSON(http.StatusOK, c.Get(rc.Name))
}
func (rc *ResourceController) ConditionalDeleteHandler(c *echo.Context) error {
	query := search.Query{Resource: rc.Name, Query: c.Request().URL.RawQuery}
	_, err := rc.DAL.ConditionalDelete(query)
	if err != nil {
		return err
	}

	c.Set("Resource", rc.Name)
	c.Set("Action", "delete")

	c.Response().Header().Set("Access-Control-Allow-Origin", "*")
	return c.NoContent(http.StatusNoContent)
}
Beispiel #4
0
func EditHandlerPost(c echo.Context) error {
	filepath := c.P(0)
	eolIndex, _ := strconv.Atoi(c.FormValue("eol"))
	content := c.FormValue("content")
	convertedContent, err := eol.LineEnding(eolIndex).Apply(content)
	if err != nil {
		convertedContent = content
		log.Println("Error while converting EOL. Saving without conversion.")
	}
	ioutil.WriteFile(filepath, []byte(convertedContent), 0644)
	c.Set("editorView", NewEditorView(filepath, content))
	return EditHandler(c)
}
Beispiel #5
0
// SetData stores the given key value in the *echo.Context(under the template context oject)
func SetData(ctx *echo.Context, key string, val interface{}) {
	v := ctx.Get(settings.DataKey)
	switch v.(type) {
	case Data:
		d := v.(Data)
		d[key] = val
		ctx.Set(settings.DataKey, d)
	default:
		d := GetContext()
		d[key] = val
		ctx.Set(settings.DataKey, d)
	}

}
func (rc *ResourceController) IndexHandler(c *echo.Context) error {
	defer func() error {
		if r := recover(); r != nil {
			switch x := r.(type) {
			case search.Error:
				return c.JSON(x.HTTPStatus, x.OperationOutcome)
			default:
				outcome := models.NewOperationOutcome("fatal", "exception", "")
				return c.JSON(http.StatusInternalServerError, outcome)
			}
		}
		return nil
	}()

	searchQuery := search.Query{Resource: rc.Name, Query: c.Request().URL.RawQuery}
	baseURL := responseURL(c.Request(), rc.Name)
	bundle, err := rc.DAL.Search(*baseURL, searchQuery)
	if err != nil {
		return err
	}

	c.Set("bundle", bundle)
	c.Set("Resource", rc.Name)
	c.Set("Action", "search")

	c.Response().Header().Set("Access-Control-Allow-Origin", "*")
	return c.JSON(http.StatusOK, bundle)
}
Beispiel #7
0
func oAuth2(c *echo.Context, handler echo.HandlerFunc) error {
	r := c.Request()
	w := c.Response()

	user, err := oauth2.GetUser(w, r)
	if err != nil {
		b, fail := err.ToJSON()
		if fail != nil {
			return fail
		}

		w.WriteHeader(err.HTTPStatusCode)
		w.Header().Set("Content-Type", "application/json")
		w.Write(b)
		return nil
	}

	if user != nil {
		c.Set("user", user)
		return handler(c)
	}
	return errors.New("unable to authenticate the user")
}
func (rc *ResourceController) DeleteHandler(c *echo.Context) error {
	id := c.Param("id")

	if err := rc.DAL.Delete(id, rc.Name); err != nil && err != ErrNotFound {
		return err
	}

	c.Set(rc.Name, id)
	c.Set("Resource", rc.Name)
	c.Set("Action", "delete")

	c.Response().Header().Set("Access-Control-Allow-Origin", "*")
	return c.NoContent(http.StatusNoContent)
}
func (rc *ResourceController) CreateHandler(c *echo.Context) error {
	resource := models.NewStructForResourceName(rc.Name)
	err := c.Bind(resource)
	if err != nil {
		oo := models.NewOperationOutcome("fatal", "exception", err.Error())
		return c.JSON(http.StatusBadRequest, oo)
	}

	id, err := rc.DAL.Post(resource)
	if err != nil {
		return err
	}

	c.Set(rc.Name, resource)
	c.Set("Resource", rc.Name)
	c.Set("Action", "create")

	c.Response().Header().Add("Location", responseURL(c.Request(), rc.Name, id).String())
	c.Response().Header().Set("Access-Control-Allow-Origin", "*")
	return c.JSON(http.StatusCreated, resource)
}
func (rc *ResourceController) UpdateHandler(c *echo.Context) error {
	resource := models.NewStructForResourceName(rc.Name)
	err := c.Bind(resource)
	if err != nil {
		oo := models.NewOperationOutcome("fatal", "exception", err.Error())
		return c.JSON(http.StatusBadRequest, oo)
	}

	createdNew, err := rc.DAL.Put(c.Param("id"), resource)
	if err != nil {
		return err
	}

	c.Set(rc.Name, resource)
	c.Set("Resource", rc.Name)
	c.Set("Action", "update")

	c.Response().Header().Set("Access-Control-Allow-Origin", "*")
	if createdNew {
		return c.JSON(http.StatusCreated, resource)
	}
	return c.JSON(http.StatusOK, resource)
}
Beispiel #11
0
// AddFlashToCtx takes flash messages stored in a cookie which is associated with the
// request found in ctx, and puts them inside the ctx object. The flash messages can then
// be retrived by calling ctx.Get(settings.FlashKey).
//
// NOTE When there are no flash messages then nothing is set.
func AddFlashToCtx(ctx *echo.Context) {
	f := GetFlashes(ctx)
	if f != nil {
		ctx.Set(settings.FlashKey, f)
	}
}
Beispiel #12
0
func userMiddleware(ctx *echo.Context) error {
	ctx.Set("User", user)
	return nil
}
Beispiel #13
0
func (s *Server) serverContext(c *echo.Context) error {
	c.Set("engine", s.Engine)
	return nil
}
Beispiel #14
0
// Set makes a two-way binding between the given Echo request context and the
// given golang.org/x/net/context.Context. Returns the fresh context.Context that contains
// this binding. Using the ToContext and FromContext functions will allow you to convert
// between one and the other.
//
// Note that since context.Context's are immutable, you will have to call this
// function to "re-bind" the request's canonical context.Context if you ever
// decide to change it.
func Set(c *echo.Context, context context.Context) context.Context {
	ctx := ctx{c, context}
	c.Set(ckey, ctx)
	return ctx
}
// Post processes and incoming batch request
func (b *BatchController) Post(c *echo.Context) error {
	bundle := &models.Bundle{}
	err := c.Bind(bundle)
	if err != nil {
		return err
	}

	// TODO: If type is batch, ensure there are no interdendent resources

	// Loop through the entries, ensuring they have a request and that we support the method,
	// while also creating a new entries array that can be sorted by method.
	entries := make([]*models.BundleEntryComponent, len(bundle.Entry))
	for i := range bundle.Entry {
		if bundle.Entry[i].Request == nil {
			// TODO: Use correct response code
			return errors.New("Entries in a batch operation require a request")
		}

		switch bundle.Entry[i].Request.Method {
		default:
			// TODO: Use correct response code
			return errors.New("Operation currently unsupported in batch requests: " + bundle.Entry[i].Request.Method)
		case "DELETE":
			if bundle.Entry[i].Request.Url == "" {
				// TODO: Use correct response code
				return errors.New("Batch DELETE must have a URL")
			}
		case "POST":
			if bundle.Entry[i].Resource == nil {
				// TODO: Use correct response code
				return errors.New("Batch POST must have a resource body")
			}
		}
		entries[i] = &bundle.Entry[i]
	}

	sort.Sort(byRequestMethod(entries))

	// Now loop through the entries, assigning new IDs to those that are POST and fixing any references
	// to reference the new ID.
	refMap := make(map[string]models.Reference)
	newIDs := make([]string, len(entries))
	for i, entry := range entries {
		if entry.Request.Method == "POST" {
			id := bson.NewObjectId().Hex()
			newIDs[i] = id
			refMap[entry.FullUrl] = models.Reference{
				Reference:    fmt.Sprintf("%s/%s", entry.Request.Url, id),
				Type:         entry.Request.Url,
				ReferencedID: id,
				External:     new(bool),
			}
			entry.FullUrl = responseURL(c.Request(), entry.Request.Url, id).String()
		}
	}
	// Update all the references to the entries (to reflect newly assigned IDs)
	updateAllReferences(entries, refMap)

	// Then make the changes in the database and update the entry response
	for i, entry := range entries {
		switch entry.Request.Method {
		case "DELETE":
			rURL := entry.Request.Url
			if strings.Contains(rURL, "/") && !strings.Contains(rURL, "?") {
				// It's a normal DELETE
				parts := strings.SplitN(entry.Request.Url, "/", 2)
				if len(parts) != 2 {
					return fmt.Errorf("Couldn't identify resource and id to delete from %s", entry.Request.Url)
				}
				if err := b.DAL.Delete(parts[1], parts[0]); err != nil && err != ErrNotFound {
					return err
				}
			} else {
				// It's a conditional (query-based) delete
				parts := strings.SplitN(entry.Request.Url, "?", 2)
				query := search.Query{Resource: parts[0], Query: parts[1]}
				if _, err := b.DAL.ConditionalDelete(query); err != nil {
					return err
				}
			}

			entry.Request = nil
			entry.Response = &models.BundleEntryResponseComponent{
				Status: "204",
			}
		case "POST":
			if err := b.DAL.PostWithID(newIDs[i], entry.Resource); err != nil {
				return err
			}
			entry.Request = nil
			entry.Response = &models.BundleEntryResponseComponent{
				Status:   "201",
				Location: entry.FullUrl,
			}
			if meta, ok := models.GetResourceMeta(entry.Resource); ok {
				entry.Response.LastModified = meta.LastUpdated
			}
		}
	}

	total := uint32(len(entries))
	bundle.Total = &total
	bundle.Type = fmt.Sprintf("%s-response", bundle.Type)

	c.Set("Bundle", bundle)
	c.Set("Resource", "Bundle")
	c.Set("Action", "batch")

	// Send the response

	c.Response().Header().Set("Access-Control-Allow-Origin", "*")
	return c.JSON(http.StatusOK, bundle)
}
Beispiel #16
0
//delete Mark Task as Deleted.
func (a *App) delete(c *echo.Context) error {
	c.Set("deleted", true)
	return a.update(c)
}