Exemplo n.º 1
0
// Update handles PUT
func (ctl *EventController) Update(c *models.Context) {
	_, itemTypeID, itemID, status, err := c.GetItemTypeAndItemID()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	// Validate inputs
	m, status, err := models.GetEvent(c.Site.ID, itemID, c.Auth.ProfileID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}
	err = c.Fill(&m)
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("The post data is invalid: %v", err.Error()),
			http.StatusBadRequest,
		)
		return
	}

	// Start Authorisation
	perms := models.GetPermission(
		models.MakeAuthorisationContext(
			c, 0, itemTypeID, itemID),
	)
	if !perms.CanUpdate {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}
	// End Authorisation

	// Populate where applicable from auth and context
	m.Meta.EditedByNullable = sql.NullInt64{Int64: c.Auth.ProfileID, Valid: true}
	m.Meta.EditedNullable = pq.NullTime{Time: time.Now(), Valid: true}

	status, err = m.Update(c.Site.ID, c.Auth.ProfileID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	audit.Replace(
		c.Site.ID,
		h.ItemTypes[h.ItemTypeEvent],
		m.ID,
		c.Auth.ProfileID,
		time.Now(),
		c.IP,
	)

	c.RespondWithSeeOther(
		fmt.Sprintf(
			"%s/%d",
			h.APITypeEvent,
			m.ID,
		),
	)
}
Exemplo n.º 2
0
// Update handles PUT
func (ctl *ProfileController) Update(c *models.Context) {
	_, itemTypeID, itemID, status, err := c.GetItemTypeAndItemID()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	m, status, err := models.GetProfile(c.Site.ID, itemID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	err = c.Fill(&m)
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("The post data is invalid: %v", err.Error()),
			http.StatusBadRequest,
		)
		return
	}

	// Start Authorisation
	perms := models.GetPermission(
		models.MakeAuthorisationContext(
			c, 0, itemTypeID, itemID),
	)
	if !perms.CanUpdate {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}
	// End Authorisation

	// Populate site and user ID from goweb context
	m.SiteID = c.Site.ID

	status, err = m.Update()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	audit.Replace(
		c.Site.ID,
		h.ItemTypes[h.ItemTypeProfile],
		m.ID,
		c.Auth.ProfileID,
		time.Now(),
		c.IP,
	)

	c.RespondWithSeeOther(
		fmt.Sprintf(
			"%s/%d",
			h.APITypeProfile,
			m.ID,
		),
	)
}
Exemplo n.º 3
0
// Update handles PUT
func (ctl *AttributeController) Update(c *models.Context) {
	_, itemTypeID, itemID, status, err := c.GetItemTypeAndItemID()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	key := c.RouteVars["key"]

	// Exception from normal model is that we don't attempt to fetch before
	// we update. We will be doing an upsert (update or insert) rather than
	// a pure update. As such, the item may not exist before we update it and
	// we allow that to be resolved later. This works in this case as the data
	// structure is simple and we don't care about extended metadata
	m := models.AttributeType{}
	m.Key = key
	m.Number = sql.NullFloat64{Float64: math.MaxFloat64}

	err = c.Fill(&m)
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("The post data is invalid: %v", err.Error()),
			http.StatusBadRequest,
		)
		return
	}

	perms := models.GetPermission(models.MakeAuthorisationContext(c, 0, itemTypeID, itemID))
	if !perms.CanUpdate {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}

	status, err = m.Update(itemTypeID, itemID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	audit.Replace(
		c.Site.ID,
		h.ItemTypes[h.ItemTypeAttribute],
		m.ID,
		c.Auth.ProfileID,
		time.Now(),
		c.IP,
	)

	c.RespondWithSeeOther(
		fmt.Sprintf(
			"%s/%s",
			fmt.Sprintf(h.APITypeAttribute, c.RouteVars["type"], itemID),
			key,
		),
	)
}
Exemplo n.º 4
0
// Update handles PUT
func (ctl *SiteController) Update(c *models.Context) {
	_, _, itemID, status, err := c.GetItemTypeAndItemID()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	m, status, err := models.GetSite(itemID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	// Use the user ID to check, since the current context is a different site (the root site)
	// than the site the owner profile is associated with.
	owner, status, err := models.GetProfileSummary(m.ID, m.OwnedByID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	if owner.UserID != c.Auth.UserID {
		c.RespondWithErrorMessage(
			fmt.Sprintf("You must be the owner of the site to update it"),
			http.StatusForbidden,
		)
		return
	}

	err = c.Fill(&m)
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("The post data is invalid: %v", err.Error()),
			http.StatusBadRequest,
		)
		return
	}

	status, err = m.Update()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	audit.Replace(
		c.Site.ID,
		h.ItemTypes[h.ItemTypeSite],
		m.ID,
		c.Auth.ProfileID,
		time.Now(),
		c.IP,
	)

	c.RespondWithSeeOther(fmt.Sprintf("%s/%d", h.APITypeSite, m.ID))
}
Exemplo n.º 5
0
// UpdateMany handles PUT for the collection
func (ctl *AttributesController) UpdateMany(c *models.Context) {
	_, itemTypeID, itemID, status, err := c.GetItemTypeAndItemID()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	ems := []models.AttributeType{}

	err = c.Fill(&ems)
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("The post data is invalid: %v", err.Error()),
			http.StatusBadRequest,
		)
		return
	}

	for _, v := range ems {
		if strings.Trim(v.Key, " ") == "" {
			c.RespondWithErrorMessage(
				"key must be supplied with every attribute when updating multiple attributes",
				http.StatusBadRequest,
			)
			return
		}
	}

	perms := models.GetPermission(models.MakeAuthorisationContext(c, 0, itemTypeID, itemID))
	if !perms.CanUpdate {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}

	status, err = models.UpdateManyAttributes(itemTypeID, itemID, ems)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	for _, m := range ems {
		audit.Replace(
			c.Site.ID,
			h.ItemTypes[h.ItemTypeAttribute],
			m.ID,
			c.Auth.ProfileID,
			time.Now(),
			c.IP,
		)
	}

	c.RespondWithOK()
}
Exemplo n.º 6
0
// Update handles PUT
func (ctl *AttendeeController) Update(c *models.Context) {
	// Verify ID is a positive integer
	eventID, err := strconv.ParseInt(c.RouteVars["event_id"], 10, 64)
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("The supplied event_id ('%s') is not a number.", c.RouteVars["event_id"]),
			http.StatusBadRequest,
		)
		return
	}

	m := models.AttendeeType{}

	err = c.Fill(&m)
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("The post data is invalid: %v", err.Error()),
			http.StatusBadRequest,
		)
		return
	}

	// Start Authorisation
	perms := models.GetPermission(
		models.MakeAuthorisationContext(
			c, 0, h.ItemTypes[h.ItemTypeEvent], eventID),
	)
	if !perms.CanUpdate {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}

	if perms.IsOwner || perms.IsModerator || perms.IsSiteOwner {
		if m.ProfileID != c.Auth.ProfileID && m.RSVP == "yes" {
			c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
			return
		}
	} else {
		if m.ProfileID != c.Auth.ProfileID {
			c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
			return
		}
	}
	_, status, err := models.GetProfileSummary(c.Site.ID, m.ProfileID)
	if err != nil {
		c.RespondWithErrorMessage(h.NoAuthMessage, status)
		return
	}
	// End Authorisation

	// Populate where applicable from auth and context
	t := time.Now()
	m.EventID = eventID
	m.Meta.CreatedByID = c.Auth.ProfileID
	m.Meta.Created = t
	m.Meta.EditedByNullable = sql.NullInt64{Int64: c.Auth.ProfileID, Valid: true}
	m.Meta.EditedNullable = pq.NullTime{Time: t, Valid: true}

	status, err = m.Update(c.Site.ID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	if m.RSVP == "yes" {
		go models.SendUpdatesForNewAttendeeInAnEvent(c.Site.ID, m)
	}

	audit.Replace(
		c.Site.ID,
		h.ItemTypes[h.ItemTypeAttendee],
		m.ID,
		c.Auth.ProfileID,
		time.Now(),
		c.IP,
	)

	c.RespondWithSeeOther(
		fmt.Sprintf("%s/%d", fmt.Sprintf(h.APITypeAttendee, m.EventID), m.ProfileID),
	)
}
Exemplo n.º 7
0
// Delete handles DELETE
func (ctl *AttendeeController) Delete(c *models.Context) {
	// Validate inputs
	eventID, err := strconv.ParseInt(c.RouteVars["event_id"], 10, 64)
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("The supplied event_id ('%s') is not a number.", c.RouteVars["event_id"]),
			http.StatusBadRequest,
		)
		return
	}

	profileID, err := strconv.ParseInt(c.RouteVars["profile_id"], 10, 64)
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("The supplied profile_id ('%s') is not a number.", c.RouteVars["profile_id"]),
			http.StatusBadRequest,
		)
		return
	}

	attendeeID, status, err := models.GetAttendeeID(eventID, profileID)
	if err != nil {
		c.RespondWithOK()
		return
	}

	// Start Authorisation
	perms := models.GetPermission(
		models.MakeAuthorisationContext(
			c, 0, h.ItemTypes[h.ItemTypeAttendee], attendeeID),
	)
	if !perms.CanDelete {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}
	// End Authorisation

	m, status, err := models.GetAttendee(c.Site.ID, attendeeID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	// Delete resource
	status, err = m.Delete(c.Site.ID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	audit.Replace(
		c.Site.ID,
		h.ItemTypes[h.ItemTypeAttendee],
		attendeeID,
		c.Auth.ProfileID,
		time.Now(),
		c.IP,
	)

	c.RespondWithOK()
}
Exemplo n.º 8
0
// UpdateMany handles PUT on the collection
func (ctl *AttendeesController) UpdateMany(c *models.Context) {
	// Verify event_id is a positive integer
	eventID, err := strconv.ParseInt(c.RouteVars["event_id"], 10, 64)
	if err != nil {
		glog.Errorln(err.Error())
		c.RespondWithErrorMessage(
			fmt.Sprintf("The supplied event ID ('%s') is not a number.", c.RouteVars["event_id"]),
			http.StatusBadRequest,
		)
		return
	}

	ems := []models.AttendeeType{}

	err = c.Fill(&ems)
	if err != nil {
		glog.Errorln(err.Error())
		c.RespondWithErrorMessage(
			fmt.Sprintf("The post data is invalid: %v", err.Error()),
			http.StatusBadRequest,
		)
		return
	}

	// Start : Authorisation
	perms := models.GetPermission(
		models.MakeAuthorisationContext(
			c, 0, h.ItemTypes[h.ItemTypeEvent], eventID),
	)

	if !perms.CanCreate {
		c.RespondWithErrorDetail(
			e.New(c.Site.ID, c.Auth.ProfileID, "attendees.go::UpdateMany", e.NoCreate, "Not authorized to create attendee: CanCreate false"),
			http.StatusForbidden,
		)
		return
	}
	// Everyone can set self to any status.  Event/site owners can set people to any status apart from 'attending'.
	// Also check that profile exists on site.
	if perms.IsOwner || perms.IsModerator || perms.IsSiteOwner {
		for _, m := range ems {
			if m.ProfileID != c.Auth.ProfileID && m.RSVP == "yes" {
				c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
				return
			}
			_, status, err := models.GetProfileSummary(c.Site.ID, m.ProfileID)
			if err != nil {
				c.RespondWithErrorMessage(h.NoAuthMessage, status)
				return
			}
		}
	} else {
		for _, m := range ems {
			if m.ProfileID != c.Auth.ProfileID {
				c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
				return
			}
			_, status, err := models.GetProfileSummary(c.Site.ID, m.ProfileID)
			if err != nil {
				c.RespondWithErrorMessage(h.NoAuthMessage, status)
				return
			}
		}
	}
	// End : Authorisation

	t := time.Now()
	// Populate where applicable from auth and context
	for i := range ems {
		ems[i].EventID = eventID
		ems[i].Meta.CreatedByID = c.Auth.ProfileID
		ems[i].Meta.Created = t
		ems[i].Meta.EditedNullable = pq.NullTime{Time: t, Valid: true}
		ems[i].Meta.EditedByNullable = sql.NullInt64{Int64: c.Auth.ProfileID, Valid: true}
	}

	status, err := models.UpdateManyAttendees(c.Site.ID, ems)
	if err != nil {
		glog.Error(err)
		c.RespondWithErrorDetail(err, status)
		return
	}
	for _, m := range ems {
		if m.RSVP == "yes" {
			go models.SendUpdatesForNewAttendeeInAnEvent(c.Site.ID, m)

			// The new attendee should be following the event now
			go models.RegisterWatcher(
				m.ProfileID,
				h.UpdateTypes[h.UpdateTypeEventReminder],
				m.EventID,
				h.ItemTypes[h.ItemTypeEvent],
				c.Site.ID,
			)
		}

		audit.Replace(
			c.Site.ID,
			h.ItemTypes[h.ItemTypeAttendee],
			m.ID,
			c.Auth.ProfileID,
			time.Now(),
			c.IP,
		)
	}

	c.RespondWithOK()
}
Exemplo n.º 9
0
// Update handles PUT
func (ctl *RoleController) Update(c *models.Context) {
	// Validate inputs
	var microcosmID int64
	if sid, exists := c.RouteVars["microcosm_id"]; exists {
		id, err := strconv.ParseInt(sid, 10, 64)
		if err != nil {
			c.RespondWithErrorMessage("microcosm_id in URL is not a number", http.StatusBadRequest)
			return
		}

		microcosmID = id
	}

	roleID, err := strconv.ParseInt(c.RouteVars["role_id"], 10, 64)
	if err != nil {
		c.RespondWithErrorMessage("microcosm_id in URL is not a number", http.StatusBadRequest)
		return
	}

	m, status, err := models.GetRole(c.Site.ID, microcosmID, roleID, c.Auth.ProfileID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	err = c.Fill(&m)
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("The post data is invalid: %v", err.Error()),
			http.StatusBadRequest,
		)
		return
	}

	// Authorisation
	perms := models.GetPermission(
		models.MakeAuthorisationContext(c, microcosmID, h.ItemTypes[h.ItemTypeMicrocosm], microcosmID),
	)
	if microcosmID > 0 {
		// Related to a Microcosm
		if !perms.IsModerator && !c.Auth.IsSiteOwner {
			c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
			return
		}
	} else {
		// Default role for the site
		if !c.Auth.IsSiteOwner {
			c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
			return
		}
	}

	// Populate where applicable from auth and context
	m.Meta.EditedByNullable = sql.NullInt64{Int64: c.Auth.ProfileID, Valid: true}
	m.Meta.EditedNullable = pq.NullTime{Time: time.Now(), Valid: true}

	status, err = m.Update(c.Site.ID, c.Auth.ProfileID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	audit.Replace(
		c.Site.ID,
		h.ItemTypes[h.ItemTypeRole],
		m.ID,
		c.Auth.ProfileID,
		time.Now(),
		c.IP,
	)

	c.RespondWithSeeOther(m.GetLink())
}