Documentation ¶
Overview ¶
Package api provides general purpose tools for implementing the Traffic Ops API.
Index ¶
- Constants
- func AddLastModifiedHdr(w http.ResponseWriter, t time.Time)
- func AddUserToReq(r *http.Request, u auth.CurrentUser)
- func AllParams(req *http.Request, required []string, ints []string) (map[string]string, map[string]int, error, error, int)
- func CheckIfUnModified(h http.Header, tx *sqlx.Tx, ID int, tableName string) (error, error, int)
- func CreateChangeLog(level string, action string, i Identifier, user *auth.CurrentUser, tx *sql.Tx) error
- func CreateChangeLogBuildMsg(level string, action string, user *auth.CurrentUser, tx *sql.Tx, ...) error
- func CreateChangeLogRawErr(level string, msg string, user *auth.CurrentUser, tx *sql.Tx) error
- func CreateChangeLogRawTx(level string, msg string, user *auth.CurrentUser, tx *sql.Tx)
- func CreateDeprecationAlerts(alternative *string) tc.Alerts
- func CreateHandler(creator Creator) http.HandlerFunc
- func DefaultSort(readerType *APIInfo, param string)
- func DeleteHandler(deleter Deleter) http.HandlerFunc
- func DeprecatedDeleteHandler(deleter Deleter, alternative *string) http.HandlerFunc
- func DeprecatedReadHandler(reader Reader, alternative *string) http.HandlerFunc
- func FormatLastModified(t time.Time) string
- func GenericCreate(val GenericCreator) (error, error, int)
- func GenericCreateNameBasedID(val GenericCreator) (error, error, int)
- func GenericDelete(val GenericDeleter) (error, error, int)
- func GenericOptionsDelete(val GenericOptionsDeleter) (error, error, int)
- func GenericRead(h http.Header, val GenericReader, useIMS bool) ([]interface{}, error, error, int, *time.Time)
- func GenericUpdate(h http.Header, val GenericUpdater) (error, error, int)
- func GetCombinedParams(r *http.Request) (map[string]string, error)
- func GetConfig(ctx context.Context) (*config.Config, error)
- func GetDB(ctx context.Context) (*sqlx.DB, error)
- func GetIntKey(s string) (interface{}, error)
- func GetLastUpdated(tx *sqlx.Tx, ID int, tableName string) (*time.Time, bool, error)
- func GetLastUpdatedByName(tx *sqlx.Tx, name string, tableName string) (*time.Time, bool, error)
- func GetPathParams(ctx context.Context) (map[string]string, error)
- func GetStringKey(s string) (interface{}, error)
- func GetUserFromReq(w http.ResponseWriter, r *http.Request, secret string) (auth.CurrentUser, error, error, int)
- func GoneHandler(w http.ResponseWriter, r *http.Request)
- func HandleDeprecatedErr(w http.ResponseWriter, r *http.Request, tx *sql.Tx, statusCode int, ...)
- func HandleErr(w http.ResponseWriter, r *http.Request, tx *sql.Tx, statusCode int, ...)
- func HandleErrOptionalDeprecation(w http.ResponseWriter, r *http.Request, tx *sql.Tx, statusCode int, ...)
- func IntParams(params map[string]string, intParamNames []string) (map[string]int, error)
- func IsBool(s string) error
- func IsInt(s string) error
- func IsUnmodified(h http.Header, lastUpdated time.Time) bool
- func LogErr(r *http.Request, errCode int, userErr error, sysErr error) error
- func LoginAuth(identity, username, password, host string) smtp.Auth
- func ParamsHaveRequired(params map[string]string, required []string) error
- func Parse(r io.Reader, tx *sql.Tx, v ParseValidator) error
- func ParseDBError(ierr error) (error, error, int)
- func ReadHandler(reader Reader) http.HandlerFunc
- func RespWriter(w http.ResponseWriter, r *http.Request, tx *sql.Tx) func(v interface{}, err error)
- func RespWriterVals(w http.ResponseWriter, r *http.Request, tx *sql.Tx, ...) func(v interface{}, err error)
- func SendEmailFromTemplate(config config.Config, header string, data interface{}, templateFile string, ...) (int, error, error)
- func SendMail(to rfc.EmailAddress, msg []byte, cfg *config.Config) (int, error, error)
- func SetLastModifiedHeader(r *http.Request, useIMS bool) bool
- func StripParamJSON(params map[string]string) map[string]string
- func TryIfModifiedSinceQuery(val GenericReader, h http.Header, where string, orderBy string, ...) (bool, time.Time)
- func UpdateHandler(updater Updater) http.HandlerFunc
- func WriteAlerts(w http.ResponseWriter, r *http.Request, code int, alerts tc.Alerts)
- func WriteAlertsObj(w http.ResponseWriter, r *http.Request, code int, alerts tc.Alerts, ...)
- func WriteResp(w http.ResponseWriter, r *http.Request, v interface{})
- func WriteRespAlert(w http.ResponseWriter, r *http.Request, level tc.AlertLevel, msg string)
- func WriteRespAlertNotFound(w http.ResponseWriter, r *http.Request)
- func WriteRespAlertObj(w http.ResponseWriter, r *http.Request, level tc.AlertLevel, msg string, ...)
- func WriteRespRaw(w http.ResponseWriter, r *http.Request, v interface{})
- func WriteRespVals(w http.ResponseWriter, r *http.Request, v interface{}, ...)
- func WriteRespWithSummary(w http.ResponseWriter, r *http.Request, v interface{}, count uint64)
- type APIInfo
- type APIInfoImpl
- type APIInfoer
- type APIResponse
- type APIResponseWithSummary
- type AlertsResponse
- type CRUDer
- type ChangeLog
- type ChangeLogger
- type Creator
- type Deleter
- type GenericCreator
- type GenericDeleter
- type GenericOptionsDeleter
- type GenericReader
- type GenericUpdater
- type Identifier
- type KeyFieldInfo
- type MultipleCreator
- type OptionsDeleter
- type ParseValidator
- type Reader
- type Tenantable
- type Updater
- type Validator
- type Version
Constants ¶
const ( DBContextKey = "db" ConfigContextKey = "context" ReqIDContextKey = "reqid" APIRespWrittenKey = "respwritten" )
Common context.Context value keys.
const ( ApiChange = "APICHANGE" Updated = "Updated" Created = "Created" Deleted = "Deleted" )
const ConfigKey = "cfg"
const DBKey = "db"
const PathParamsKey = "pathParams"
Variables ¶
This section is empty.
Functions ¶
func AddLastModifiedHdr ¶
func AddLastModifiedHdr(w http.ResponseWriter, t time.Time)
AddLastModifiedHdr adds the "last modified" header to the response.
func AddUserToReq ¶
func AddUserToReq(r *http.Request, u auth.CurrentUser)
func AllParams ¶
func AllParams(req *http.Request, required []string, ints []string) (map[string]string, map[string]int, error, error, int)
AllParams takes the request (in which the router has inserted context for path parameters), and an array of parameters required to be integers, and returns the map of combined parameters, and the map of int parameters; or a user or system error and the HTTP error code. The intParams may be nil if no integer parameters are required. This is a helper for the common case; not using this in unusual cases is perfectly acceptable.
func CheckIfUnModified ¶
CheckIfUnModified checks to see if the resource was modified since the "If-Unmodified-Since" header value in the request. In case it was, the 412 error code is returned. If some other error was encountered while checking, the appropriate error code along with error details is returned. If the resource was not modified since the specified time, the UPDATE proceeds in the normal fashion.
func CreateChangeLog ¶
func CreateChangeLog(level string, action string, i Identifier, user *auth.CurrentUser, tx *sql.Tx) error
func CreateChangeLogBuildMsg ¶
func CreateChangeLogRawErr ¶
func CreateChangeLogRawTx ¶
func CreateDeprecationAlerts ¶
func CreateDeprecationAlerts(alternative *string) tc.Alerts
CreateDeprecationAlerts creates a deprecation notice with an optional alternative route suggestion.
func CreateHandler ¶
func CreateHandler(creator Creator) http.HandlerFunc
CreateHandler creates a handler function from the pointer to a struct implementing the Creator interface
this generic handler encapsulates the logic for handling: *current user *decoding and validating the struct *change log entry *forming and writing the body over the wire
func DefaultSort ¶
DefaultSort sorts alphabetically for a given readerType (eg: TOCDN, TODeliveryService, TOOrigin etc).
func DeleteHandler ¶
func DeleteHandler(deleter Deleter) http.HandlerFunc
DeleteHandler creates a handler function from the pointer to a struct implementing the Deleter interface
this generic handler encapsulates the logic for handling: *fetching the id from the path parameter *current user *change log entry *forming and writing the body over the wire
func DeprecatedDeleteHandler ¶
func DeprecatedDeleteHandler(deleter Deleter, alternative *string) http.HandlerFunc
DeprecatedDeleteHandler creates a handler function from the pointer to a struct implementing the Deleter interface with a optional deprecation notice
this generic handler encapsulates the logic for handling: *fetching the id from the path parameter *current user *change log entry *forming and writing the body over the wire
func DeprecatedReadHandler ¶
func DeprecatedReadHandler(reader Reader, alternative *string) http.HandlerFunc
DeprecatedReadHandler creates a net/http.HandlerFunc for the passed Reader object, and adds a deprecation notice, optionally with a passed alternative route suggestion.
func FormatLastModified ¶
FormatLastModified trims the time string and formats it according to RFC1123.
func GenericCreate ¶
func GenericCreate(val GenericCreator) (error, error, int)
GenericCreate does a Create (POST) for the given GenericCreator object and type. This exists as a generic function, for the common use case of a single "id" key and a lastUpdated field.
func GenericCreateNameBasedID ¶
func GenericCreateNameBasedID(val GenericCreator) (error, error, int)
GenericCreateNameBasedID does a Create (POST) for the given GenericCreator object and type. This exists as a generic function, for the use case of a single "name" key (not a numerical "id" key) and a lastUpdated field.
func GenericDelete ¶
func GenericDelete(val GenericDeleter) (error, error, int)
GenericDelete does a Delete (DELETE) for the given GenericDeleter object and type. This exists as a generic function, for the common use case of a simple delete with query parameters defined in the sqlx struct tags.
func GenericOptionsDelete ¶
func GenericOptionsDelete(val GenericOptionsDeleter) (error, error, int)
GenericOptionsDelete does a Delete (DELETE) for the given GenericOptionsDeleter object and type. Unlike GenericDelete, there is no requirement that a specific key is used as the parameter. GenericOptionsDeleter.DeleteKeyOptions() specifies which keys can be used.
func GenericRead ¶
func GenericUpdate ¶
GenericUpdate handles the common update case, where the update returns the new last_modified time.
func GetDB ¶
GetDB returns the database from the context. This should very rarely be needed, rather `NewInfo` should always be used to get a transaction, except in extenuating circumstances.
func GetLastUpdated ¶
GetLastUpdated checks for the resource by ID in the database, and returns its last_updated timestamp, if available.
func GetLastUpdatedByName ¶
GetLastUpdatedByName checks for the resource by name in the database, and returns its last_updated timestamp, if available.
func GetStringKey ¶
func GetUserFromReq ¶
func GetUserFromReq(w http.ResponseWriter, r *http.Request, secret string) (auth.CurrentUser, error, error, int)
GetUserFromReq returns the current user, any user error, any system error, and an error code to be returned if either error was not nil. This also uses the given ResponseWriter to refresh the cookie, if it was valid.
func GoneHandler ¶
func GoneHandler(w http.ResponseWriter, r *http.Request)
GoneHandler is an http.Handler function that just writes a 410 Gone response back to the client, along with an error-level alert stating that the endpoint is no longer available.
func HandleDeprecatedErr ¶
func HandleDeprecatedErr(w http.ResponseWriter, r *http.Request, tx *sql.Tx, statusCode int, userErr error, sysErr error, alternative *string)
HandleDeprecatedErr handles an API error, adding a deprecation alert, rolling back the transaction, writing the given statusCode and userErr to the user, and logging the sysErr. If userErr is nil, the text of the HTTP statusCode is written.
The alternative may be nil if there is no alternative and the deprecation message will be selected appropriately.
The tx may be nil, if there is no transaction. Passing a nil tx is strongly discouraged if a transaction exists, because it will result in copy-paste errors for the common APIInfo use case.
This is a helper for the common case; not using this in unusual cases is perfectly acceptable.
func HandleErr ¶
func HandleErr(w http.ResponseWriter, r *http.Request, tx *sql.Tx, statusCode int, userErr error, sysErr error)
HandleErr handles an API error, rolling back the transaction, writing the given statusCode and userErr to the user, and logging the sysErr. If userErr is nil, the text of the HTTP statusCode is written.
The tx may be nil, if there is no transaction. Passing a nil tx is strongly discouraged if a transaction exists, because it will result in copy-paste errors for the common APIInfo use case.
This is a helper for the common case; not using this in unusual cases is perfectly acceptable.
func IntParams ¶
IntParams parses integer parameters, and returns map of the given params, or an error if any integer param is not an integer. The intParams may be nil if no integer parameters are required. Note this does not check existence; if an integer paramter is required, it should be included in the requiredParams given to NewInfo. This is a helper for the common case; not using this in unusual cases is perfectly acceptable.
func IsUnmodified ¶
IsUnmodified returns a boolean, saying whether or not the resource in question was modified since the time specified in the headers.
func LogErr ¶
LogErr handles the logging of errors and setting up possibly nil errors without actually writing anything to a http.ResponseWriter, unlike handleSimpleErr. It returns the userErr which will be initialized to the http.StatusText of errCode if it was passed as nil - otherwise left alone.
func ParamsHaveRequired ¶
ParamsHaveRequired checks that params have all the required parameters, and returns nil on success, or an error providing information on which params are missing.
func Parse ¶
Parse decodes a JSON object from r into v, validating and sanitizing the input. Use this function instead of the json package when writing API endpoints to safely decode and validate PUT and POST requests.
TODO: change to take data loaded from db, to remove sql from tc package.
func ParseDBError ¶
ParseDBError parses pq errors for database constraint violations, and returns the (userErr, sysErr, httpCode) format expected by the API helpers.
func ReadHandler ¶
func ReadHandler(reader Reader) http.HandlerFunc
ReadHandler creates a handler function from the pointer to a struct implementing the Reader interface
this handler retrieves the user from the context combines the path and query parameters produces the proper status code based on the error code returned marshals the structs returned into the proper response json
func RespWriter ¶
RespWriter is a helper to allow a one-line response, for endpoints with a function that returns the object that needs to be written and an error. This is a helper for the common case; not using this in unusual cases is perfectly acceptable.
func RespWriterVals ¶
func RespWriterVals(w http.ResponseWriter, r *http.Request, tx *sql.Tx, vals map[string]interface{}) func(v interface{}, err error)
RespWriterVals is like RespWriter, but also takes a map of root-level values to write. The API most commonly needs these for meta-parameters, like size, limit, and orderby. This is a helper for the common case; not using this in unusual cases is perfectly acceptable.
func SendEmailFromTemplate ¶
func SendEmailFromTemplate(config config.Config, header string, data interface{}, templateFile string, toEmail string) (int, error, error)
SendEmailFromTemplate allows a user to input an html template to format an email. It parses the template and creates a message before calling the SendMail method. SendEmailFromTemplate returns (in order) an HTTP status code, a user-friendly error, and an error fit for logging to system error logs. If either the user or system error is non-nil, the operation failed, and the HTTP status code indicates the type of failure.
func SendMail ¶
SendMail sends an email msg to the address identified by to. The msg parameter should be an RFC822-style email with headers first, a blank line, and then the message body. The lines of msg should be CRLF terminated. The msg headers should usually include fields such as "From", "To", "Subject", and "Cc". Sending "Bcc" messages is accomplished by including an email address in the to parameter but not including it in the msg headers. The cfg parameter is used to set things like the "From" field, as well as for connection and authentication with an external SMTP server. SendMail returns (in order) an HTTP status code, a user-friendly error, and an error fit for logging to system error logs. If either the user or system error is non-nil, the operation failed, and the HTTP status code indicates the type of failure.
func SetLastModifiedHeader ¶
SetLastModifiedHeader sets the Last-Modified header in case the "useIMS" is set to true in the config, and if there is an "If-Modified-Since" header in the incoming request
func StripParamJSON ¶
StripParamJSON removes ".json" trailing any parameter value, and returns the modified params. This allows the API handlers to transparently accept /id.json routes, as allowed by the 1.x API.
func TryIfModifiedSinceQuery ¶
func TryIfModifiedSinceQuery(val GenericReader, h http.Header, where string, orderBy string, pagination string, queryValues map[string]interface{}) (bool, time.Time)
TryIfModifiedSinceQuery checks to see the max time that an entity was changed, and then returns a boolean (which tells us whether or not to run the main query for the endpoint) along with the max time If the returned boolean is false, there is no need to run the main query for the GET API endpoint, and we return a 304 status
func UpdateHandler ¶
func UpdateHandler(updater Updater) http.HandlerFunc
UpdateHandler creates a handler function from the pointer to a struct implementing the Updater interface
this generic handler encapsulates the logic for handling: *fetching the id from the path parameter *current user *decoding and validating the struct *change log entry *forming and writing the body over the wire
func WriteAlerts ¶
func WriteAlerts(w http.ResponseWriter, r *http.Request, code int, alerts tc.Alerts)
func WriteAlertsObj ¶
func WriteAlertsObj(w http.ResponseWriter, r *http.Request, code int, alerts tc.Alerts, obj interface{})
func WriteResp ¶
func WriteResp(w http.ResponseWriter, r *http.Request, v interface{})
WriteResp takes any object, serializes it as JSON, and writes that to w. Any errors are logged and written to w via tc.GetHandleErrorsFunc. This is a helper for the common case; not using this in unusual cases is perfectly acceptable.
func WriteRespAlert ¶
func WriteRespAlert(w http.ResponseWriter, r *http.Request, level tc.AlertLevel, msg string)
WriteRespAlert creates an alert, serializes it as JSON, and writes that to w. Any errors are logged and written to w via tc.GetHandleErrorsFunc. This is a helper for the common case; not using this in unusual cases is perfectly acceptable.
func WriteRespAlertNotFound ¶
func WriteRespAlertNotFound(w http.ResponseWriter, r *http.Request)
WriteRespAlertNotFound creates an alert indicating that the resource was not found and writes that to w.
func WriteRespAlertObj ¶
func WriteRespAlertObj(w http.ResponseWriter, r *http.Request, level tc.AlertLevel, msg string, obj interface{})
WriteRespAlertObj Writes the given alert, and the given response object. This is a helper for the common case; not using this in unusual cases is perfectly acceptable.
func WriteRespRaw ¶
func WriteRespRaw(w http.ResponseWriter, r *http.Request, v interface{})
WriteRespRaw acts like WriteResp, but doesn't wrap the object in a `{"response":` object. This should be used to respond with endpoints which don't wrap their response in a "response" object.
func WriteRespVals ¶
func WriteRespVals(w http.ResponseWriter, r *http.Request, v interface{}, vals map[string]interface{})
WriteRespVals is like WriteResp, but also takes a map of root-level values to write. The API most commonly needs these for meta-parameters, like size, limit, and orderby. This is a helper for the common case; not using this in unusual cases is perfectly acceptable.
func WriteRespWithSummary ¶
func WriteRespWithSummary(w http.ResponseWriter, r *http.Request, v interface{}, count uint64)
WriteRespWithSummary writes a JSON-encoded representation of an arbitrary object to the provided writer, and cleans up the corresponding request object. It also provides a "summary" section to the response object that contains the given "count".
Types ¶
type APIInfo ¶
type APIInfo struct { Params map[string]string IntParams map[string]int User *auth.CurrentUser ReqID uint64 Version *Version Tx *sqlx.Tx Config *config.Config }
func NewInfo ¶
func NewInfo(r *http.Request, requiredParams []string, intParamNames []string) (*APIInfo, error, error, int)
NewInfo get and returns the context info needed by handlers. It also returns any user error, any system error, and the status code which should be returned to the client if an error occurred.
It is encouraged to call APIInfo.Tx.Tx.Commit() manually when all queries are finished, to release database resources early, and also to return an error to the user if the commit failed.
NewInfo guarantees the returned APIInfo.Tx is non-nil and APIInfo.Tx.Tx is nil or valid, even if a returned error is not nil. Hence, it is safe to pass the Tx.Tx to HandleErr when this returns errors.
Close() must be called to free resources, and should be called in a defer immediately after NewInfo(), to finish the transaction.
Example:
func handler(w http.ResponseWriter, r *http.Request) { inf, userErr, sysErr, errCode := api.NewInfo(r, nil, nil) if userErr != nil || sysErr != nil { api.HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr) return } defer inf.Close() respObj, err := finalDatabaseOperation(inf.Tx) if err != nil { api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("final db op: " + err.Error())) return } if err := inf.Tx.Tx.Commit(); err != nil { api.HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("committing transaction: " + err.Error())) return } api.WriteResp(w, r, respObj) }
func (*APIInfo) Close ¶
func (inf *APIInfo) Close()
Close implements the io.Closer interface. It should be called in a defer immediately after NewInfo().
Close will commit the transaction, if it hasn't been rolled back.
func (*APIInfo) CreateInfluxClient ¶
CreateInfluxClient constructs and returns an InfluxDB HTTP client, if enabled and when possible. The error this returns should not be exposed to the user; it's for logging purposes only.
If Influx connections are not enabled, this will return `nil` - but also no error. It is expected that the caller will handle this situation appropriately.
func (*APIInfo) IsResourceAuthorizedToCurrentUser ¶
IsResourceAuthorizedToCurrentUser is a convenience method used to call github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/tenant.IsResourceAuthorizedToUserTx using an APIInfo structure to provide the current user and database transaction.
type APIInfoImpl ¶
type APIInfoImpl struct {
ReqInfo *APIInfo
}
APIInfoImpl implements APIInfo via the APIInfoer interface
func (APIInfoImpl) APIInfo ¶
func (val APIInfoImpl) APIInfo() *APIInfo
func (*APIInfoImpl) SetInfo ¶
func (val *APIInfoImpl) SetInfo(inf *APIInfo)
type APIInfoer ¶
APIInfoer is an interface that guarantees the existance of a variable through its setters and getters. Every CRUD operation uses this login session context
type APIResponse ¶
type APIResponse struct {
Response interface{} `json:"response"`
}
type APIResponseWithSummary ¶
type APIResponseWithSummary struct { Response interface{} `json:"response"` Summary struct { Count uint64 `json:"count"` } `json:"summary"` }
type AlertsResponse ¶
type AlertsResponse interface {
// GetAlerts retrieves an array of alerts that were generated over the course of handling an endpoint.
GetAlerts() tc.Alerts
}
type ChangeLogger ¶
type Deleter ¶
type Deleter interface { // Delete returns any user error, any system error, and the HTTP error code to be returned if there was an error. Delete() (error, error, int) APIInfoer Identifier }
type GenericCreator ¶
type GenericDeleter ¶
type GenericOptionsDeleter ¶
type GenericOptionsDeleter interface { GetType() string APIInfo() *APIInfo DeleteKeyOptions() map[string]dbhelpers.WhereColumnInfo DeleteQueryBase() string }
GenericOptionsDeleter can use any key listed in DeleteKeyOptions() to delete a resource.
type GenericReader ¶
type GenericUpdater ¶
type Identifier ¶
type Identifier interface { // Getters and Setters for key data // The current common case is a single numerical id SetKeys(map[string]interface{}) GetKeys() (map[string]interface{}, bool) // GetType gives the name of the implementing struct GetType() string // GetAuditName returns the name of an object instance. If no name is availible, the id should be returned. "unknown" is the final case GetAuditName() string // This should define the key getters and setters GetKeyFieldsInfo() []KeyFieldInfo }
type KeyFieldInfo ¶
type MultipleCreator ¶
type MultipleCreator interface {
AllowMultipleCreates() bool
}
MultipleCreator indicates whether an object using the shared handlers allows an array of objects in the POST
type OptionsDeleter ¶
type OptionsDeleter interface { // OptionsDelete returns any user error, any system error, and the HTTP error code to be returned if there was an // error. OptionsDelete() (error, error, int) APIInfoer Identifier DeleteKeyOptions() map[string]dbhelpers.WhereColumnInfo }
OptionsDeleter calls the OptionsDelete() generic CRUD function, unlike Deleter, which calls Delete().
type ParseValidator ¶
ParseValidator objects can make use of api.Parse to handle parsing and validating at the same time.
TODO: Rework validation to be able to return system-level errors
type Tenantable ¶
type Tenantable interface {
IsTenantAuthorized(user *auth.CurrentUser) (bool, error)
}