Пример #1
0
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)
		},
	}
}
Пример #2
0
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)
		},
	}
}
Пример #5
0
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()
		},
	}
}
Пример #6
0
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
}
Пример #7
0
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()
		},
	}
}