// 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, ), ) }
// 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, ), ) }
// 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, ), ) }
// 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)) }
// 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() }
// 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), ) }
// 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() }
// 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() }
// 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()) }