Ejemplo n.º 1
0
func HandleFind(registry kit.Registry, request kit.Request) (kit.Response, bool) {
	collection := request.GetContext().MustString("collection")

	res := registry.Resource(collection)
	if res == nil || !res.IsPublic() {
		err := &apperror.Err{
			Code:    "unknown_resource",
			Message: fmt.Sprintf("The resource '%v' does not exist", collection),
		}
		return kit.NewErrorResponse(err), false
	}

	response, err := Find(res, request)
	if err != nil {
		response = kit.NewErrorResponse(err)
	}

	// If response contains a count and the request a "perPage" param, add a total_pages param
	// to meta.
	perPage, err2 := request.GetContext().Int("per_page")

	meta := response.GetMeta()
	if meta != nil && err2 == nil {
		count, ok := meta["count"]
		if ok {
			meta["total_pages"] = math.Ceil(float64(count.(int)) / float64(perPage))
		}
	}

	return response, false
}
Ejemplo n.º 2
0
func (a *App) RunMethod(name string, r kit.Request, responder func(kit.Response), withFinishedChannel bool) (chan bool, apperror.Error) {
	method := a.registry.Method(name)
	if method == nil {
		return nil, &apperror.Err{
			Code:    "unknown_method",
			Message: fmt.Sprintf("The method %v does not exist", name),
		}
	}

	if r.GetSession() == nil {
		session, err := a.UserService().StartSession(r.GetUser(), "")
		if err != nil {
			return nil, err
		}
		r.SetSession(session)
	}

	instance := NewMethodInstance(method, r, responder)

	if withFinishedChannel {
		c := make(chan bool)
		instance.finishedChannel = c
		return c, a.sessionManager.QueueMethod(r.GetSession(), instance)
	} else {
		return nil, a.sessionManager.QueueMethod(r.GetSession(), instance)
	}
}
Ejemplo n.º 3
0
func notFoundHandler(registry kit.Registry, r kit.Request) (kit.Response, bool) {
	httpRequest := r.GetHttpRequest()
	apiPrefix := "/" + registry.Config().UString("api.prefix", "api")
	isApiRequest := strings.HasPrefix(httpRequest.URL.Path, apiPrefix)

	// Try to render the page on the server, if enabled.
	if !isApiRequest {
		renderEnabled := registry.Config().UBool("serverRenderer.enabled", false)
		noRender := strings.Contains(httpRequest.URL.String(), "no-server-render")

		if renderEnabled && !noRender {
			return serverRenderer(registry, r), false
		}
	}

	// For non-api requests, render the default template.
	if !isApiRequest {
		tpl, err := getIndexTpl(registry)
		if err != nil {
			return kit.NewErrorResponse(err), false
		}
		return &kit.AppResponse{
			RawData: tpl,
		}, false
	}

	// For api requests, render the api not found error.
	return &kit.AppResponse{
		Error: &apperror.Err{
			Code:    "not_found",
			Message: "This api route does not exist",
		},
	}, false
}
Ejemplo n.º 4
0
func (_ FilesResource) ApiCreate(res kit.Resource, obj kit.Model, r kit.Request) kit.Response {
	// Verify that tmp path is set either in metadata or on model.

	file := obj.(kit.File)
	if file.GetTmpPath() == "" {
		file.SetTmpPath(r.GetMeta().String("file"))
	}

	filePath := file.GetTmpPath()
	if filePath == "" {
		return kit.NewErrorResponse("no_tmp_path", "A tmp path must be set when creating a file", true)
	}

	tmpPath := getTmpPath(res)

	if !strings.HasPrefix(filePath, tmpPath) && filePath[0] != '/' {
		filePath = tmpPath + string(os.PathSeparator) + filePath
		file.SetTmpPath(filePath)
	}

	// Build the file, save it to backend and persist it to the db.
	err := res.Registry().FileService().BuildFile(file, r.GetUser(), true, true)
	if err != nil {
		kit.NewErrorResponse(err)
	}

	return &kit.AppResponse{
		Data: file,
	}
}
Ejemplo n.º 5
0
func (PageResource) ApiAlterQuery(res kit.Resource, query db.Query, r kit.Request) apperror.Error {
	typ := r.GetContext().String("type")
	if typ != "" {
		query.Filter("type", typ)
	}
	return nil
}
Ejemplo n.º 6
0
func SerializeResponseMiddleware(registry kit.Registry, request kit.Request, response kit.Response) (kit.Response, bool) {
	// Try to serialize the reponse data.

	// Determine serializer.
	serializer := registry.DefaultSerializer()

	// Check if a custom serializer was specified.
	if name := request.GetContext().String("response-serializer"); name != "" {
		serializer = registry.Serializer(name)
		if serializer == nil {
			errResp := kit.NewErrorResponse("unknown_response_serializer", true)
			data, _ := serializer.MustSerializeResponse(errResp)
			errResp.SetData(data)
			return errResp, false
		}
	}

	// Set format in metadata.
	meta := response.GetMeta()
	if meta == nil {
		meta = make(map[string]interface{})
	}

	meta["format"] = serializer.Name()
	response.SetMeta(meta)

	data, err := serializer.MustSerializeResponse(response)
	if err != nil {
		registry.Logger().Errorf("Response serialization error: %v (%+v)", err, response)
	}
	response.SetData(data)

	return nil, false
}
Ejemplo n.º 7
0
// Creating a session is equivalent to logging in.
func (hooks SessionResourceHooks) ApiCreate(res kit.Resource, obj kit.Model, r kit.Request) kit.Response {
	userService := res.Registry().UserService()

	meta := r.GetMeta()

	isAnonymous, _ := meta.Bool("anonymous")

	// Find user.
	userIdentifier := meta.String("user")
	adaptor := meta.String("adaptor")
	data, _ := meta.Map("authData")

	var user kit.User
	if !isAnonymous {
		if adaptor == "" {
			return kit.NewErrorResponse("adaptor_missing", "Expected 'adaptor' in metadata.", true)
		}

		if data == nil {
			kit.NewErrorResponse("no_or_invalid_auth_data", "Expected 'authData' dictionary in metadata.")
		}

		var err apperror.Error
		user, err = userService.AuthenticateUser(userIdentifier, adaptor, data)
		if err != nil {
			return kit.NewErrorResponse(err)
		}
	}

	session, err := userService.StartSession(user, r.GetFrontend())
	if err != nil {
		return kit.NewErrorResponse(err)
	}

	responseMeta := make(map[string]interface{})

	if !isAnonymous {
		userData, err := res.Backend().ModelToMap(user, true, false)
		if err != nil {
			return kit.NewErrorResponse("marshal_error", err)
		}
		responseMeta["user"] = userData

		if user.GetProfile() != nil {
			profileData, err := res.Backend().ModelToMap(user.GetProfile(), true, false)
			if err != nil {
				return kit.NewErrorResponse("marshal_error", err)
			}
			responseMeta["profile"] = profileData
		}
	}

	return &kit.AppResponse{
		Data: session,
		Meta: responseMeta,
	}
}
Ejemplo n.º 8
0
// UnserializeRequest converts request data into a request object.
func (s *Serializer) UnserializeRequest(rawData interface{}, request kit.Request) apperror.Error {
	transData, err := s.UnserializeTransferData(rawData)
	if err != nil {
		return err
	}
	request.SetTransferData(transData)
	request.SetData(transData.GetData())
	return nil
}
Ejemplo n.º 9
0
func (SessionResourceHooks) ApiDelete(res kit.Resource, id string, r kit.Request) kit.Response {
	if id != r.GetSession().GetStrId() {
		return kit.NewErrorResponse("permission_denied", "Permission denied", 403)
	}

	if err := res.Backend().Delete(r.GetSession()); err != nil {
		return kit.NewErrorResponse("db_delete_error", err, true)
	}

	return &kit.AppResponse{}
}
Ejemplo n.º 10
0
func ServerErrorMiddleware(registry kit.Registry, r kit.Request, response kit.Response) (kit.Response, bool) {
	err := response.GetError()
	if err == nil {
		return nil, false
	}

	status := 500

	// If the error is an apperror, and it contains a status,
	// set it as the http status of the response.
	if apperr, ok := err.(apperror.Error); ok {
		if apperr.GetStatus() != 0 {
			status = apperr.GetStatus()
		}
	}

	response.SetHttpStatus(status)

	if response.GetRawData() != nil || response.GetRawDataReader() != nil {
		return nil, false
	}

	httpRequest := r.GetHttpRequest()
	apiPrefix := "/" + registry.Config().UString("api.prefix", "api")
	isApiRequest := strings.HasPrefix(httpRequest.URL.Path, apiPrefix)

	if isApiRequest {
		return nil, false
	}

	data := map[string]interface{}{"errors": []error{response.GetError()}}

	tpl := defaultErrorTpl()

	tplPath := registry.Config().UString("frontend.errorTemplate")
	if tplPath != "" {
		t, err := template.ParseFiles(tplPath)
		if err != nil {
			registry.Logger().Fatalf("Could not parse error template at '%v': %v", tplPath, err)
		} else {
			tpl = t
		}
	}

	var buffer *bytes.Buffer
	if err := tpl.Execute(buffer, data); err != nil {
		registry.Logger().Fatalf("Could not render error template: %v\n", err)
		response.SetRawData([]byte("Server error"))
	} else {
		response.SetRawData(buffer.Bytes())
	}

	return nil, false
}
Ejemplo n.º 11
0
func HandleDelete(registry kit.Registry, request kit.Request) (kit.Response, bool) {
	collection := request.GetContext().MustString("collection")
	id := request.GetContext().MustString("id")

	res := registry.Resource(collection)
	if res == nil || !res.IsPublic() {
		resp := kit.NewErrorResponse("unknown_resource", fmt.Sprintf("The resource '%v' does not exist", collection))
		return resp, false
	}

	return res.ApiDelete(id, request), false
}
Ejemplo n.º 12
0
func (res *Resource) ApiPartialUpdate(obj kit.Model, r kit.Request) kit.Response {
	if updateHook, ok := res.hooks.(ApiUpdateHook); ok {
		return updateHook.ApiUpdate(res, obj, r)
	}

	user := r.GetUser()
	err := res.PartialUpdate(obj, user)
	if err != nil {
		return kit.NewErrorResponse(err)
	}

	return &kit.AppResponse{
		Data: obj,
	}
}
Ejemplo n.º 13
0
func (hooks UserResourceHooks) ApiCreate(res kit.Resource, obj kit.Model, r kit.Request) kit.Response {
	meta := r.GetMeta()

	adaptor := meta.String("adaptor")
	if adaptor == "" {
		return kit.NewErrorResponse("adaptor_missing", "Expected 'adaptor' in metadata.", true)
	}

	rawData, ok := meta.Get("authData")
	if !ok {
		return kit.NewErrorResponse("auth_data_missing", "Expected 'authData' in metadata.", true)
	}

	data, ok := rawData.(map[string]interface{})
	if !ok {
		return kit.NewErrorResponse("invalid_auth_data", "Invalid auth data: expected dictionary", true)
	}

	user := obj.(kit.User)

	service := res.Registry().UserService()

	// If a profile model was registered, and profile data is in meta,
	// create the profile model.
	if profiles := service.ProfileResource(); profiles != nil {
		profile := profiles.CreateModel().(kit.UserProfile)

		if rawData, ok := meta.Get("profile"); ok {
			if data, ok := rawData.(map[string]interface{}); ok {
				// Profile data present in meta.
				// Update profile with data.
				if err := res.ModelInfo().UpdateModelFromData(profile, data); err != nil {
					return kit.NewErrorResponse("invalid_profile_data", "Invalid profile data.", err, true)
				}
			}
		}

		user.SetProfile(profile)
	}

	if err := service.CreateUser(user, adaptor, data); err != nil {
		return kit.NewErrorResponse(err)
	}

	return &kit.AppResponse{
		Data: user,
	}
}
Ejemplo n.º 14
0
func AuthenticationMiddleware(registry kit.Registry, r kit.Request) (kit.Response, bool) {
	// Handle authentication.
	httpRequest := r.GetHttpRequest()
	userService := registry.UserService()

	if userService == nil {
		return nil, false
	}

	authHeader := httpRequest.Header.Get("Authentication")
	if authHeader == "" {
		return nil, false
	}

	// Check for basic auth.
	if strings.HasPrefix(authHeader, "Basic ") {
		str := authHeader[6:]
		data, err := base64.StdEncoding.DecodeString(str)
		if err != nil {
			return kit.NewErrorResponse("invalid_basic_auth"), false
		} else {
			parts := strings.Split(string(data), ":")
			if len(parts) == 2 {
				userIdentifier := parts[0]
				pw := parts[1]

				user, err := userService.AuthenticateUser(userIdentifier, "password", map[string]interface{}{"password": pw})
				if err != nil {
					return kit.NewErrorResponse(err), false
				}

				r.SetUser(user)
				return nil, false
			}
		}
	}

	// Check for auth token.
	if authHeader != "" {
		token := authHeader
		user, session, err := userService.VerifySession(token)
		if err == nil {
			r.SetUser(user)
			r.SetSession(session)

			return nil, false
		} else {
			return kit.NewErrorResponse(err), false
		}
	}

	return nil, false
}
Ejemplo n.º 15
0
func Update(registry kit.Registry, request kit.Request) (kit.Response, apperror.Error) {
	collection := request.GetContext().MustString("collection")

	res := registry.Resource(collection)
	if res == nil || !res.IsPublic() {
		return nil, &apperror.Err{
			Code:    "unknown_resource",
			Message: fmt.Sprintf("The resource '%v' does not exist", collection),
		}
	}

	model, ok := request.GetData().(kit.Model)
	if !ok {
		return nil, apperror.New("invalid_data_no_model", "Node model data in request.")
	}

	response := res.ApiUpdate(model, request)

	return response, nil
}
Ejemplo n.º 16
0
func (res *Resource) ApiDelete(id string, r kit.Request) kit.Response {
	if deleteHook, ok := res.hooks.(ApiDeleteHook); ok {
		return deleteHook.ApiDelete(res, id, r)
	}

	oldObj, err := res.FindOne(id)
	if err != nil {
		return kit.NewErrorResponse(err)
	} else if oldObj == nil {
		return kit.NewErrorResponse("not_found", "")
	}

	user := r.GetUser()
	if err := res.Delete(oldObj, user); err != nil {
		return kit.NewErrorResponse(err)
	}

	return &kit.AppResponse{
		Data: oldObj,
	}
}
Ejemplo n.º 17
0
func UnserializerMiddleware(registry kit.Registry, request kit.Request) (kit.Response, bool) {
	serializer := registry.DefaultSerializer()

	// Try to find custom serializer.
	data, ok := request.GetData().(map[string]interface{})
	if ok {
		name, ok := data["request_serializer"].(string)
		if ok {
			s := registry.Serializer(name)
			if s == nil {
				resp := kit.NewErrorResponse("unknown_request_serializer", fmt.Sprintf("The given request serializer %v does not exist", name))
				return resp, false
			} else {
				serializer = s
			}
		}
	}

	if err := serializer.UnserializeRequest(request.GetData(), request); err != nil {
		return kit.NewErrorResponse(err), false
	}

	return nil, false
}
Ejemplo n.º 18
0
func (res *Resource) ApiFindOne(rawId string, r kit.Request) kit.Response {
	hook, ok := res.hooks.(ApiFindOneHook)
	if ok {
		return hook.ApiFindOne(res, rawId, r)
	}

	result, err := res.FindOne(rawId)
	if err != nil {
		return kit.NewErrorResponse(err)
	} else if result == nil {
		return kit.NewErrorResponse("not_found", "")
	}

	user := r.GetUser()
	if allowFind, ok := res.hooks.(AllowFindHook); ok {
		if !allowFind.AllowFind(res, result, user) {
			return kit.NewErrorResponse("permission_denied", "")
		}
	}

	return &kit.AppResponse{
		Data: result,
	}
}
Ejemplo n.º 19
0
func Create(registry kit.Registry, request kit.Request) (kit.Response, apperror.Error) {
	collection := request.GetContext().MustString("collection")

	res := registry.Resource(collection)
	if res == nil || !res.IsPublic() {
		return nil, &apperror.Err{
			Code:    "unknown_resource",
			Message: fmt.Sprintf("The resource '%v' does not exist", collection),
		}
	}

	fmt.Printf("data: %v |  %+v\n\n", nil, request.GetData())
	model, ok := request.GetData().(kit.Model)
	if !ok {
		return nil, apperror.New("invalid_data_no_model", "No model data in request.")
	}

	response := res.ApiCreate(model, request)
	if response.GetError() == nil {
		response.SetHttpStatus(201)
	}

	return response, nil
}
Ejemplo n.º 20
0
func Find(res kit.Resource, request kit.Request) (kit.Response, apperror.Error) {
	collection := res.Collection()

	info := res.Backend().ModelInfo(collection)

	var query *db.Query

	jsonQuery := request.GetContext().String("query")
	if jsonQuery != "" {
		var rawQuery map[string]interface{}
		if err := json.Unmarshal([]byte(jsonQuery), &rawQuery); err != nil {
			return nil, apperror.Wrap(err, "invalid_query_json")
		}

		rawQuery["collection"] = collection

		// A custom query was supplied.
		// Try to parse the query.
		var err apperror.Error
		query, err = db.ParseQuery(res.Backend(), rawQuery)
		if err != nil {
			return nil, apperror.Wrap(err, "invalid_query", "", false)
		}
	}

	if query == nil {
		query = res.Backend().Q(collection)
	}

	// Check paging parameters.
	var limit, offset int

	context := request.GetContext()

	if context.Has("limit") {
		val, err := context.Int("limit")
		if err != nil {
			return nil, &apperror.Err{
				Public:  true,
				Code:    "non_numeric_limit_parameter",
				Message: "The get query contains a non-numeric ?limit",
			}
		}
		limit = val
	}

	if context.Has("offset") {
		val, err := context.Int("offset")
		if err != nil {
			return nil, &apperror.Err{
				Public:  true,
				Code:    "non_numeric_offset_parameter",
				Message: "The get query contains a non-numeric ?offset",
			}
		}
		offset = val
	}

	var page, perPage int

	if context.Has("page") {
		val, err := context.Int("page")
		if err != nil {
			return nil, &apperror.Err{
				Public:  true,
				Code:    "non_numeric_page_parameter",
				Message: "The get query contains a non-numeric ?page",
			}
		}
		page = val
	}

	if context.Has("per_page") {
		val, err := context.Int("per_page")
		if err != nil {
			return nil, &apperror.Err{
				Public:  true,
				Code:    "non_numeric_per_page_parameter",
				Message: "The get query contains a non-numeric ?per_page",
			}
		}
		perPage = val
	}

	if perPage > 0 {
		limit = perPage
	}

	if page > 1 {
		offset = (page - 1) * limit
	}

	if limit > 0 {
		query.Limit(int(limit)).Offset(int(offset))
	}

	// Add joins.
	if context.Has("joins") {
		parts := strings.Split(context.String("joins"), ",")
		for _, name := range parts {
			relation := info.FindRelation(name)

			if relation == nil {
				return nil, &apperror.Err{
					Code:    "invalid_join",
					Message: fmt.Sprintf("Tried to join a NON-existant relationship %v", name),
					Public:  true,
				}
			}

			query.Join(relation.Name())
		}
	}

	// Add filters.
	if context.Has("filters") {
		parts := strings.Split(context.String("filters"), ",")
		for _, filter := range parts {
			filterParts := strings.Split(filter, ":")

			if len(filterParts) != 2 {
				return nil, &apperror.Err{
					Public:  true,
					Code:    "invalid_filter",
					Message: fmt.Sprintf("Invalid filter: %v", filter),
				}
			}

			fieldName := filterParts[0]
			// COnvert id query to pk field.
			if fieldName == "id" {
				fieldName = info.PkAttribute().BackendName()
			}

			var typ reflect.Type

			if attr := info.FindAttribute(fieldName); attr != nil {
				fieldName = attr.BackendName()
				typ = attr.Type()
			} else if rel := info.FindRelation(fieldName); rel != nil {
				if rel.RelationType() == db.RELATION_TYPE_HAS_ONE {
					fieldName = rel.LocalField()
					typ = info.Attribute(rel.LocalField()).Type()
				} else {
					return nil, &apperror.Err{
						Public:  true,
						Code:    "cant_filter_on_relation",
						Message: fmt.Sprintf("Tried to filter on relationship field %v (only possible for has-one relations)", fieldName),
					}
				}
			} else {
				return nil, &apperror.Err{
					Public:  true,
					Code:    "filter_for_inexistant_field",
					Message: fmt.Sprintf("Tried to filter with inexistant field %v", fieldName),
				}
			}

			converted, err := reflector.R(filterParts[1]).ConvertTo(typ)
			if err != nil {
				return nil, &apperror.Err{
					Public: true,
					Code:   "inconvertible_filter_value",
					Message: fmt.Sprintf("Coult not convert filter value %v for field %v (should be %v)",
						filterParts[1], fieldName, typ),
				}
			}
			query.Filter(fieldName, converted)
		}
	}

	return res.ApiFind(query, request), nil
}
Ejemplo n.º 21
0
func RequestLoggerMiddleware(registry kit.Registry, r kit.Request, response kit.Response) (kit.Response, bool) {

	// Calculate time taken.
	rawStarted, ok1 := r.GetContext().Get("startTime")
	rawFinished, ok2 := r.GetContext().Get("endTime")

	timeTaken := int64(-1)
	if ok1 && ok2 {
		started := rawStarted.(time.Time)
		finished := rawFinished.(time.Time)
		timeTaken = int64(finished.Sub(started) / time.Millisecond)
	}

	// Log the request.
	method := r.GetHttpMethod()
	path := r.GetPath()
	if response.GetError() != nil {
		registry.Logger().WithFields(logrus.Fields{
			"frontend":     r.GetFrontend(),
			"action":       "request",
			"method":       method,
			"path":         path,
			"status":       response.GetHttpStatus(),
			"err":          response.GetError(),
			"milliseconds": timeTaken,
		}).Errorf("%v: %v - %v - %v", response.GetHttpStatus(), method, path, response.GetError())
	} else {
		registry.Logger().WithFields(logrus.Fields{
			"frontend":     r.GetFrontend(),
			"action":       "request",
			"method":       method,
			"path":         path,
			"status":       response.GetHttpStatus(),
			"milliseconds": timeTaken,
		}).Debugf("%v: %v - %v", response.GetHttpStatus(), method, path)
	}

	return nil, false
}
Ejemplo n.º 22
0
func serverRenderer(registry kit.Registry, r kit.Request) kit.Response {
	url := r.GetHttpRequest().URL

	// Build the url to query.
	if url.Scheme == "" {
		url.Scheme = "http"
	}
	if url.Host == "" {
		url.Host = registry.Config().UString("host", "localhost") + ":" + registry.Config().UString("port", "8000")
	}

	q := url.Query()
	q.Set("no-server-render", "1")
	url.RawQuery = q.Encode()

	strUrl := url.String()

	cacheKey := "serverrenderer_" + strUrl
	cacheName := registry.Config().UString("serverRenderer.cache")
	var cache kit.Cache

	// If a cache is specified, try to retrieve it.
	if cacheName != "" {
		cache = registry.Cache(cacheName)
		if cache == nil {
			registry.Logger().Errorf("serverRenderer.cache is set to %v, but the cache is not registered with app", cacheName)
		}
	}

	// If a cache was found, try to retrieve cached response.
	if cache != nil {
		item, err := cache.Get(cacheKey)
		if err != nil {
			registry.Logger().Errorf("serverRenderer: cache retrieval error: %v", err)
		} else if item != nil {
			// Cache item found, return response with cache item.
			status, _ := strconv.ParseInt(item.GetTags()[0], 10, 64)
			data, _ := item.ToString()

			return &kit.AppResponse{
				HttpStatus: int(status),
				RawData:    []byte(data),
			}
		}
	}

	// Either no cache or url not yet cached, so render it.

	// First, ensure that the tmp directory exists.
	tmpDir := path.Join(registry.Config().TmpDir(), "phantom")
	if ok, _ := utils.FileExists(tmpDir); !ok {
		if err := os.MkdirAll(tmpDir, 0777); err != nil {
			return &kit.AppResponse{
				Error: &apperror.Err{
					Code:    "create_tmp_dir_failed",
					Message: fmt.Sprintf("Could not create the tmp directory at %v: %v", tmpDir, err),
				},
			}
		}
	}

	// Build a unique file name.
	filePath := path.Join(tmpDir, utils.UUIdv4()+".html")

	// Execute phantom js.

	// Find path of phantom script.
	_, filename, _, _ := runtime.Caller(1)
	scriptPath := path.Join(path.Dir(path.Dir(filename)), "phantom", "render.js")

	start := time.Now()

	phantomPath := registry.Config().UString("serverRenderer.phantomJsPath", "phantomjs")

	args := []string{
		"--web-security=false",
		"--local-to-remote-url-access=true",
		scriptPath,
		"10",
		strUrl,
		filePath,
	}
	result, err := exec.Command(phantomPath, args...).CombinedOutput()
	if err != nil {
		registry.Logger().Errorf("Phantomjs execution error: %v", string(result))

		return &kit.AppResponse{
			Error: apperror.Wrap(err, "phantom_execution_failed"),
		}
	}

	// Get time taken as milliseconds.
	timeTaken := int(time.Now().Sub(start) / time.Millisecond)
	registry.Logger().WithFields(log.Fields{
		"action":       "phantomjs_render",
		"milliseconds": timeTaken,
	}).Debugf("Rendered url %v with phantomjs", url)

	content, err2 := utils.ReadFile(filePath)
	if err2 != nil {
		return kit.NewErrorResponse(err2)
	}

	// Find http status code.
	status := 200
	res := regexp.MustCompile("http_status_code\\=(\\d+)").FindStringSubmatch(string(content))
	if res != nil {
		s, _ := strconv.ParseInt(res[1], 10, 64)
		status = int(s)
	}

	// Save to cache.
	if cache != nil {
		lifetime := registry.Config().UInt("serverRenderer.cacheLiftetime", 3600)

		err := cache.Set(&caches.StrItem{
			Key:       cacheKey,
			Value:     string(content),
			Tags:      []string{strconv.FormatInt(int64(status), 10)},
			ExpiresAt: time.Now().Add(time.Duration(lifetime) * time.Second),
		})
		if err != nil {
			registry.Logger().Errorf("serverRenderer: Cache persist error: %v", err)
		}
	}

	return &kit.AppResponse{
		HttpStatus: status,
		RawData:    content,
	}
}
Ejemplo n.º 23
0
func (res *Resource) ApiFind(query *db.Query, r kit.Request) kit.Response {
	// If query is empty, query for all records.
	if query == nil {
		query = res.Q()
	}

	apiFindHook, ok := res.hooks.(ApiFindHook)
	if ok {
		return apiFindHook.ApiFind(res, query, r)
	}

	if alterQuery, ok := res.hooks.(ApiAlterQueryHook); ok {
		alterQuery.ApiAlterQuery(res, query, r)
	}

	result, err := res.Query(query)
	if err != nil {
		return kit.NewErrorResponse(err)
	}

	user := r.GetUser()
	if allowFind, ok := res.hooks.(AllowFindHook); ok {
		finalItems := make([]kit.Model, 0)
		for _, item := range result {
			if allowFind.AllowFind(res, item, user) {
				finalItems = append(finalItems, item)
			}
		}
		result = finalItems
	}

	response := &kit.AppResponse{
		Data: result,
	}

	// If a limit was set, count the total number of results
	// and set count parameter in metadata.
	limit := query.GetLimit()
	if limit > 0 {
		query.Limit(0).Offset(0)
		count, err := res.backend.Count(query)
		if err != nil {
			return &kit.AppResponse{
				Error: apperror.Wrap(err, "count_error", ""),
			}
		}

		response.SetMeta(map[string]interface{}{
			"count":       count,
			"total_pages": math.Ceil(float64(count) / float64(limit)),
		})
	}

	if hook, ok := res.hooks.(ApiAfterFindHook); ok {
		if err := hook.ApiAfterFind(res, result, r, response); err != nil {
			return kit.NewErrorResponse(err)
		}
	}

	return response
}
Ejemplo n.º 24
0
func RequestTraceMiddleware(registry kit.Registry, r kit.Request) (kit.Response, bool) {
	r.GetContext().Set("startTime", time.Now())
	return nil, false
}
Ejemplo n.º 25
0
func UnserializeRequestMiddleware(registry kit.Registry, request kit.Request) (kit.Response, bool) {
	// Try to parse json in body. Ignore error since body might not contain json.
	contentType := request.GetHttpRequest().Header.Get("Content-Type")
	if strings.Contains(contentType, "json") {
		// Only read the HTTP body automatically for json content type requests,
		// since some handlers might need to read it themselfes (see the files package resource).
		if err := request.ReadHttpBody(); err != nil {
			return kit.NewErrorResponse(err, "http_body_read_error"), false
		} else {
			if request.GetRawData() != nil {
				if err := request.ParseJsonData(); err != nil {
					return kit.NewErrorResponse(err, "invalid_json_body", true), false
				}

				if request.GetData() != nil {
					// Successfully parsed json body.

					// Now try to unserialize.

					// Determine serializer.
					serializer := registry.DefaultSerializer()

					// Check if a custom serializer was specified.
					if name := request.GetContext().String("request-serializer"); name != "" {
						serializer = registry.Serializer(name)
					}

					if serializer == nil {
						return kit.NewErrorResponse("unknown_serializer", fmt.Sprintf("The specified request serializer does not exist")), false
					} else {
						if err := request.Unserialize(serializer); err != nil {
							return kit.NewErrorResponse(err, "request_unserialize_error", true), false
						}
					}
				}
			}
		}
	}

	return nil, false
}
Ejemplo n.º 26
0
func RequestTraceAfterMiddleware(registry kit.Registry, r kit.Request, response kit.Response) (kit.Response, bool) {
	r.GetContext().Set("endTime", time.Now())
	return nil, false
}