func (o *message) Methods() map[string]func(he.Request) he.Response { return map[string]func(he.Request) he.Response{ "GET": func(req he.Request) he.Response { return rfc7231.StatusOK(o) }, } }
func (o *captcha) Methods() map[string]func(he.Request) he.Response { return map[string]func(he.Request) he.Response{ "GET": func(req he.Request) he.Response { return rfc7231.StatusOK(o) }, "POST": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) type postfmt struct { Value string `json:"value"` Expiration time.Time `json:"password"` } var entity postfmt httperr := safeDecodeJSON(req.Entity, &entity) if httperr != nil { return *httperr } o := (*captcha)(backend.NewCaptcha(db)) if o == nil { return rfc7231.StatusForbidden(he.NetPrintf("Captcha generation failed")) } else { ret := rfc7231.StatusOK(o) return ret } }, "PUT": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) var newCaptcha captcha httperr := safeDecodeJSON(req.Entity, &newCaptcha) if httperr != nil { return *httperr } *o = newCaptcha o.backend().Save(db) return rfc7231.StatusOK(o) }, /* "PATCH": func(req he.Request) he.Response { panic("TODO: API: (*captcha).Methods()[\"PATCH\"]") }, */ } }
func (grp *groupSubscriptions) Methods() map[string]func(he.Request) he.Response { return map[string]func(he.Request) he.Response{ "GET": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) grp.values = grp.backend().GetSubscriberIDs(db) return rfc7231.StatusOK(grp) }, } }
func (usr *userSubscriptions) Methods() map[string]func(he.Request) he.Response { return map[string]func(he.Request) he.Response{ "GET": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) usr.groupID = req.URL.Query().Get("group_id") usr.values = usr.backend().GetFrontEndSubscriptions(db) return rfc7231.StatusOK(usr) }, "POST": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) sess := req.Things["session"].(*backend.Session) type postfmt struct { GroupID string `json:"group_id"` Medium string `json:"medium,omitempty"` Address string `json:"address,omitempty"` } var entity postfmt httperr := safeDecodeJSON(req.Entity, &entity) if httperr != nil { return *httperr } entity.GroupID = strings.ToLower(entity.GroupID) var address *backend.UserAddress if entity.Medium == "" && entity.Address == "" { address = &usr.Addresses[0] for _, addr := range usr.Addresses { if addr.SortOrder < address.SortOrder { address = &addr } } } else { for _, addr := range usr.Addresses { if addr.Medium == entity.Medium && addr.Address == entity.Address { address = &addr break } } } if address == nil { return rfc7231.StatusConflict(he.NetPrintf("You don't have that address")) } backend.NewSubscription(db, address.ID, entity.GroupID, sess != nil && sess.UserID == usr.ID) return rfc7231.StatusCreated(usr, entity.GroupID+":"+address.Medium+":"+address.Address, req) }, } }
func (o *group) Methods() map[string]func(he.Request) he.Response { return map[string]func(he.Request) he.Response{ "GET": func(req he.Request) he.Response { var enum Enumerategroup enum = EnumerateGroup(o) return rfc7231.StatusOK(he.NetJSON{Data: enum}) }, "PUT": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) var newGroup group httperr := safeDecodeJSON(req.Entity, &newGroup) if httperr != nil { return *httperr } if o.ID != newGroup.ID { return rfc7231.StatusConflict(he.NetPrintf("Cannot change group id")) } *o = newGroup o.backend().Save(db) return rfc7231.StatusOK(o) }, "PATCH": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) sess := req.Things["session"].(*backend.Session) subscribed := backend.IsSubscribed(db, sess.UserID, *o.backend()) if !backend.IsAdmin(db, sess.UserID, *o.backend()) { if o.JoinPublic == 1 { if subscribed == 0 { return rfc7231.StatusForbidden(he.NetPrintf("Unauthorized user")) } if o.JoinConfirmed == 1 && subscribed == 1 { return rfc7231.StatusForbidden(he.NetPrintf("Unauthorized user")) } if o.JoinMember == 1 { return rfc7231.StatusForbidden(he.NetPrintf("Unauthorized user")) } } } enum := EnumerateGroup(o) var newGroup Enumerategroup patch, ok := req.Entity.(jsonpatch.Patch) if !ok { return rfc7231.StatusUnsupportedMediaType(he.NetPrintf("PATCH request must have a patch media type")) } err := patch.Apply(enum, &newGroup) if err != nil { return rfc7231.StatusConflict(he.NetPrintf("%v", err)) } if o.ID != newGroup.Groupname { return rfc7231.StatusConflict(he.NetPrintf("Cannot change group id")) } *o = RenumerateGroup(newGroup) o.backend().Save(db) return rfc7231.StatusOK(o) }, "DELETE": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) sess := req.Things["session"].(*backend.Session) if !backend.IsAdmin(db, sess.UserID, *o.backend()) { return rfc7231.StatusForbidden(he.NetPrintf("Unauthorized user")) } o.backend().Delete(db) return rfc7231.StatusNoContent() }, } }
func newDirGroups() dirGroups { r := dirGroups{} r.methods = map[string]func(he.Request) he.Response{ "GET": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) sess := req.Things["session"].(*backend.Session) var groups []backend.Group type getfmt struct { visibility string } var entity getfmt httperr := safeDecodeJSON(req.Entity, &entity) if httperr != nil { entity.visibility = "subscribed" } if sess == nil { groups = []backend.Group{} } else if entity.visibility == "subscribed" { groups = backend.GetGroupsByMember(db, *backend.GetUserByID(db, sess.UserID)) } else { //groups = GetAllGroups(db) groups = backend.GetPublicAndSubscribedGroups(db, *backend.GetUserByID(db, sess.UserID)) } type EnumerateGroup struct { Groupname string `json:"groupname"` Post map[string]string `json:"post"` Join map[string]string `json:"join"` Read map[string]string `json:"read"` Existence map[string]string `json:"existence"` Subscriptions []backend.Subscription `json:"subscriptions"` } data := make([]EnumerateGroup, len(groups)) for i, grp := range groups { var enum EnumerateGroup enum.Groupname = grp.ID exist := [...]int{grp.ExistencePublic, grp.ExistenceConfirmed} enum.Existence = backend.ReadExist(exist) read := [...]int{grp.ReadPublic, grp.ReadConfirmed} enum.Read = backend.ReadExist(read) post := [...]int{grp.PostPublic, grp.PostConfirmed, grp.PostMember} enum.Post = backend.PostJoin(post) join := [...]int{grp.JoinPublic, grp.JoinConfirmed, grp.JoinMember} enum.Join = backend.PostJoin(join) enum.Subscriptions = grp.Subscriptions data[i] = enum } return rfc7231.StatusOK(he.NetJSON{Data: data}) }, "POST": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) type Response1 struct { Groupname string `json:"groupname"` Post map[string]string `json:"post"` Join map[string]string `json:"join"` Read map[string]string `json:"read"` Existence map[string]string `json:"existence"` } var entity Response1 httperr := safeDecodeJSON(req.Entity, &entity) if httperr != nil { return *httperr } if entity.Groupname == "" { return rfc7231.StatusUnsupportedMediaType(he.NetPrintf("groupname can't be emtpy")) } grp := backend.NewGroup( db, entity.Groupname, backend.Reverse(entity.Existence), backend.Reverse(entity.Read), backend.Reverse(entity.Post), backend.Reverse(entity.Join), ) sess := req.Things["session"].(*backend.Session) address := backend.GetAddressesByUserAndMedium(db, sess.UserID, "noop")[0] backend.NewSubscription(db, address.ID, grp.ID, true) if grp == nil { return rfc7231.StatusConflict(he.NetPrintf("a group with that name already exists")) } else { return rfc7231.StatusCreated(r, grp.ID, req) } }, } return r }
func (usr *user) Methods() map[string]func(he.Request) he.Response { return map[string]func(he.Request) he.Response{ "GET": func(req he.Request) he.Response { var addresses []backend.UserAddress for _, addr := range usr.Addresses { if addr.Medium != "noop" && addr.Medium != "admin" { addresses = append(addresses, addr) } } usr.Addresses = addresses return rfc7231.StatusOK(usr) }, "PUT": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) sess := req.Things["session"].(*backend.Session) if sess.UserID != usr.ID { return rfc7231.StatusForbidden(he.NetPrintf("Unauthorized user")) } var newUser user httperr := safeDecodeJSON(req.Entity, &newUser) if httperr != nil { return *httperr } if usr.ID != newUser.ID { return rfc7231.StatusConflict(he.NetPrintf("Cannot change user id")) } // TODO: this won't play nice with the // password hash (because it's private), or // with addresses (because the (private) IDs // need to be made to match up) *usr = newUser usr.backend().Save(db) return rfc7231.StatusOK(usr) }, "PATCH": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) sess := req.Things["session"].(*backend.Session) if sess.UserID != usr.ID { return rfc7231.StatusForbidden(he.NetPrintf("Unauthorized user")) } patch, ok := req.Entity.(jsonpatch.Patch) if !ok { return rfc7231.StatusUnsupportedMediaType(he.NetPrintf("PATCH request must have a patch media type")) } httperr := usr.patchPassword(&patch) if httperr != nil { return *httperr } var newUser user err := patch.Apply(usr, &newUser) if err != nil { return rfc7231.StatusConflict(he.ErrorToNetEntity(409, err)) } if usr.ID != newUser.ID { return rfc7231.StatusConflict(he.NetPrintf("Cannot change user id")) } if newUser.PwHash == nil || len(newUser.PwHash) == 0 { newUser.PwHash = usr.PwHash } *usr = newUser usr.backend().Save(db) return rfc7231.StatusOK(usr) }, "DELETE": func(req he.Request) he.Response { db := req.Things["db"].(*periwinkle.Tx) usr.backend().Delete(db) return rfc7231.StatusNoContent() }, } }