コード例 #1
0
ファイル: menu.go プロジェクト: riseofthetigers/microcosm
// Delete handles DELETE
func (ctl *MenuController) Delete(c *models.Context, siteID int64) {
	// Start :: Auth
	site, status, err := models.GetSite(siteID)
	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(site.ID, site.OwnedByID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	if owner.UserID != c.Auth.UserID {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}
	// End :: Auth

	status, err = models.DeleteMenu(siteID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	c.RespondWithOK()
}
コード例 #2
0
ファイル: ignored.go プロジェクト: riseofthetigers/microcosm
// Update handles PUT
func (ctl *IgnoredController) Update(c *models.Context) {
	m := models.IgnoreType{}
	err := c.Fill(&m)
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("The post data is invalid: %v", err.Error()),
			http.StatusBadRequest,
		)
		return
	}

	if c.Auth.ProfileID < 1 {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}

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

	c.RespondWithOK()
}
コード例 #3
0
ファイル: event.go プロジェクト: riseofthetigers/microcosm
// 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,
		),
	)
}
コード例 #4
0
// Delete handles DELETE
func (ctl *AuthController) Delete(c *models.Context) {

	// Extract access token from request and delete its record
	m, status, err := models.GetAccessToken(c.RouteVars["id"])
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("Error retrieving access token: %v", err.Error()),
			status,
		)
		return
	}

	status, err = m.Delete()
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("Error deleting access token: %v", err.Error()),
			status,
		)
		return
	}

	audit.Delete(
		c.Site.ID,
		h.ItemTypes[h.ItemTypeAuth],
		m.UserID,
		c.Auth.ProfileID,
		time.Now(),
		c.IP,
	)

	c.RespondWithOK()
}
コード例 #5
0
ファイル: user.go プロジェクト: riseofthetigers/microcosm
// Read handles GET
func (ctl *UserController) Read(c *models.Context) {
	_, itemTypeID, itemID, status, err := c.GetItemTypeAndItemID()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

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

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

	if !models.UserIsOnSite(m.ID, c.Site.ID) {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}

	c.RespondWithData(m)
}
コード例 #6
0
// Delete handles DELETE
// Note: This only affects explicitly assigned roles and not roles implicitly
// included by criteria
func (ctl *RoleProfileController) Delete(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("role_id in URL is not a number", http.StatusBadRequest)
		return
	}

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

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

	m := models.RoleProfileType{}
	m.ID = profileID

	// 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
		}
	}

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

	c.RespondWithOK()
}
コード例 #7
0
ファイル: user.go プロジェクト: riseofthetigers/microcosm
// Delete handles DELETE
func (ctl *UserController) Delete(c *models.Context) {
	_, _, itemID, status, err := c.GetItemTypeAndItemID()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

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

	if !models.UserIsOnSite(m.ID, c.Site.ID) {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}

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

	audit.Delete(
		c.Site.ID,
		h.ItemTypes[h.ItemTypeUser],
		itemID,
		c.Auth.ProfileID,
		time.Now(),
		c.IP,
	)

	c.RespondWithOK()
}
コード例 #8
0
// Read handles GET
func (ctl *SiteReservedController) Read(c *models.Context) {
	host, exists := c.RouteVars["subdomain"]
	if !exists {
		c.RespondWithErrorMessage("No subdomain query specified", http.StatusBadRequest)
		return
	}

	reserved, err := models.IsReservedSubdomain(host)
	if err != nil {
		c.RespondWithErrorMessage(err.Error(), http.StatusInternalServerError)
		return
	}

	var responseBody string
	if reserved {
		responseBody = `{"reserved":true}`
		c.ResponseWriter.Header().Set("Content-Length", strconv.Itoa(len(responseBody)))
	} else {
		responseBody = `{"reserved":false}`
		c.ResponseWriter.Header().Set("Content-Length", strconv.Itoa(len(responseBody)))
	}

	c.ResponseWriter.Header().Set("Content-Type", "application/json")
	c.ResponseWriter.Header().Set("Access-Control-Allow-Origin", "*")
	c.ResponseWriter.WriteHeader(http.StatusOK)
	c.ResponseWriter.Write([]byte(responseBody))
}
コード例 #9
0
ファイル: files.go プロジェクト: riseofthetigers/microcosm
// Read handles GET
func (ctl *FileController) Read(c *models.Context) {
	fileHash := c.RouteVars["fileHash"]
	if fileHash == "" {
		c.RespondWithErrorMessage(
			fmt.Sprintf("The supplied file hash cannot be zero characters: %s", c.RouteVars["fileHash"]),
			http.StatusBadRequest,
		)
		return
	}

	fileBytes, headers, _, err := models.GetFile(fileHash)
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("Could not retrieve file: %v", err.Error()),
			http.StatusInternalServerError,
		)
		return
	}

	oneYear := time.Hour * 24 * 365
	nextYear := time.Now().Add(oneYear)
	c.ResponseWriter.Header().Set("Cache-Control", fmt.Sprintf("max-age=%d", oneYear/time.Second))
	c.ResponseWriter.Header().Set("Expires", nextYear.Format(time.RFC1123))

	for h, v := range headers {
		c.ResponseWriter.Header().Set(h, v)
	}

	c.WriteResponse(fileBytes, http.StatusOK)
	return
}
コード例 #10
0
// Read handles GET
func (ctl *AttributeController) Read(c *models.Context) {
	_, itemTypeID, itemID, status, err := c.GetItemTypeAndItemID()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

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

	attributeID, status, err := models.GetAttributeID(itemTypeID, itemID, c.RouteVars["key"])
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

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

	c.RespondWithData(m)
}
コード例 #11
0
// Update handles PUT
func (ctl *ProfileOptionsController) Update(c *models.Context) {
	var m = models.ProfileOptionType{}
	err := c.Fill(&m)
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("The post data is invalid: %v", err.Error()),
			http.StatusBadRequest,
		)
		return
	}

	// Profile ID cannot be changed
	m.ProfileID = c.Auth.ProfileID

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

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

	// Respond
	c.RespondWithSeeOther(
		fmt.Sprintf("/api/v1/profiles/options"),
	)
}
コード例 #12
0
ファイル: site.go プロジェクト: riseofthetigers/microcosm
// Read handles GET either by /site or /sites/{site_id}
func (ctl *SiteController) Read(c *models.Context) {
	// Check whether this site is being accessed by ID
	siteQuery, exists := c.RouteVars["site_id"]
	if exists {
		siteID, err := strconv.ParseInt(siteQuery, 10, 64)
		if err != nil {
			c.RespondWithErrorMessage(
				fmt.Sprintf("The supplied site ID ('%s') is not a number.", siteQuery),
				http.StatusBadRequest,
			)
			return
		}

		site, status, err := models.GetSite(siteID)
		if err != nil {
			c.RespondWithErrorMessage(
				fmt.Sprintf("No site with ID %d found", siteID),
				status,
			)
			return
		}

		c.RespondWithData(site)
		return

	}

	// Site already populated in context, so only fetch permissions
	c.Site.Meta.Permissions = models.GetPermission(
		models.MakeAuthorisationContext(
			c, 0, h.ItemTypes[h.ItemTypeSite], c.Site.ID),
	)
	c.RespondWithData(c.Site)
	return
}
コード例 #13
0
ファイル: profile.go プロジェクト: riseofthetigers/microcosm
// 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,
		),
	)
}
コード例 #14
0
// Delete handles DELETE
func (ctl *AttachmentController) Delete(c *models.Context) {
	itemTypeID, itemID, perms, status, err := ParseItemInfo(c)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	if !perms.IsSiteOwner && !perms.IsModerator && perms.IsOwner {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}

	fileHash := c.RouteVars["fileHash"]
	if fileHash == "" {
		c.RespondWithErrorMessage(
			fmt.Sprintf("The supplied file hash cannot be zero characters: %s", c.RouteVars["fileHash"]),
			http.StatusBadRequest,
		)
		return
	}

	metadata, status, err := models.GetMetadata(fileHash)
	if err != nil {
		if status == http.StatusNotFound {
			c.RespondWithErrorMessage(
				fmt.Sprintf("File does not have a metadata record"),
				http.StatusBadRequest,
			)
			return
		}

		c.RespondWithErrorMessage(
			fmt.Sprintf("Could not retrieve metadata: %v", err.Error()),
			http.StatusBadRequest,
		)
		return
	}

	status, err = models.DeleteAttachment(itemTypeID, itemID, fileHash)
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("Could not remove attachment: %v", err.Error()),
			status,
		)
		return
	}

	// Update attach count on attachment_meta
	metadata.AttachCount = metadata.AttachCount - 1
	status, err = metadata.Update()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	c.RespondWithOK()
}
コード例 #15
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,
		),
	)
}
コード例 #16
0
ファイル: site.go プロジェクト: riseofthetigers/microcosm
// 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))
}
コード例 #17
0
ファイル: events.go プロジェクト: riseofthetigers/microcosm
// ReadMany handles GET
func (ctl *EventsController) ReadMany(c *models.Context) {

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

	// Fetch query string args if any exist
	query := c.Request.URL.Query()

	limit, offset, status, err := h.GetLimitAndOffset(query)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	attending, status, err := h.GetAttending(query)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	ems, total, pages, status, err := models.GetEvents(c.Site.ID, c.Auth.ProfileID, attending, limit, offset)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	// Construct the response
	thisLink := h.GetLinkToThisPage(*c.Request.URL, offset, limit, total)

	m := models.EventsType{}
	m.Events = h.ConstructArray(
		ems,
		h.APITypeEvent,
		total,
		limit,
		offset,
		pages,
		c.Request.URL,
	)
	m.Meta.Links =
		[]h.LinkType{
			h.LinkType{Rel: "self", Href: thisLink.String()},
		}
	m.Meta.Permissions = perms

	c.RespondWithData(m)
}
コード例 #18
0
// Read handles GET
func (ctl *AuthController) Read(c *models.Context) {
	// Extract access token from request and retrieve its metadata
	m, status, err := models.GetAccessToken(c.RouteVars["id"])
	if err != nil {
		c.RespondWithErrorMessage(
			fmt.Sprintf("Error retrieving access token: %v", err.Error()),
			status,
		)
		return
	}
	c.RespondWithData(m)
}
コード例 #19
0
// ReadMany handles GET for the collection
func (ctl *HuddleParticipantsController) ReadMany(c *models.Context) {
	// Validate inputs
	huddleID, err := strconv.ParseInt(c.RouteVars["huddle_id"], 10, 64)
	if err != nil {
		c.RespondWithErrorMessage("huddle_id in URL is not a number", http.StatusBadRequest)
		return
	}

	r, status, err := models.GetHuddle(c.Site.ID, c.Auth.ProfileID, huddleID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

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

	limit, offset, status, err := h.GetLimitAndOffset(c.Request.URL.Query())
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	ems, total, pages, status, err := models.GetHuddleParticipants(c.Site.ID, huddleID, limit, offset)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	// Construct the response
	m := models.HuddleParticipantsType{}
	m.HuddleParticipants = h.ConstructArray(
		ems,
		fmt.Sprintf("%s/participants", r.GetLink()),
		total,
		limit,
		offset,
		pages,
		c.Request.URL,
	)

	c.RespondWithData(m)
}
コード例 #20
0
// Create handles GET
func (ctl *MicrocosmsController) Create(c *models.Context) {
	// Validate inputs
	m := models.MicrocosmType{}
	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.ItemTypeSite], c.Site.ID),
	)
	if !perms.CanCreate {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}
	// End : Authorisation

	// Populate where applicable from auth and context
	m.SiteID = c.Site.ID
	m.Meta.CreatedByID = c.Auth.ProfileID
	m.Meta.Created = time.Now()
	m.OwnedByID = c.Auth.ProfileID

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

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

	c.RespondWithSeeOther(
		fmt.Sprintf(
			"%s/%d",
			h.APITypeMicrocosm,
			m.ID,
		),
	)
}
コード例 #21
0
// Update handles PUT
func (ctl *UpdateOptionController) Update(c *models.Context) {
	_, _, itemID, status, err := c.GetItemTypeAndItemID()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	var exists bool

	m, status, err := models.GetUpdateOptionByUpdateType(c.Auth.ProfileID, itemID)
	if err != nil && status != http.StatusNotFound {
		c.RespondWithErrorDetail(err, status)
		return
	}
	if status == http.StatusOK {
		exists = true
	}

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

	// Profile ID cannot be changed
	m.UpdateTypeID = itemID
	m.ProfileID = c.Auth.ProfileID

	if exists {
		// Update
		status, err = m.Update()
	} else {
		// Create
		status, err = m.Insert()
	}
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	// Respond
	c.RespondWithSeeOther(
		fmt.Sprintf(
			h.APITypeUpdateOptionType,
			m.UpdateTypeID,
		),
	)
}
コード例 #22
0
// Read handles GET
func (ctl *ProfileOptionsController) Read(c *models.Context) {
	if c.Auth.ProfileID < 1 {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}

	m, status, err := models.GetProfileOptions(c.Auth.ProfileID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	c.RespondWithData(m)
}
コード例 #23
0
// ReadMany handles GET for a collection
func (ctl *UpdateOptionsController) ReadMany(c *models.Context) {
	if c.Auth.ProfileID < 1 {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}

	prefs, status, err := models.GetUpdateOptions(c.Site.ID, c.Auth.ProfileID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	c.RespondWithData(prefs)
}
コード例 #24
0
// ReadMany handles GET for the collection
func (ctl *AttachmentsController) ReadMany(c *models.Context) {
	itemTypeID, itemID, perms, status, err := ParseItemInfo(c)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	if !perms.CanRead {
		c.RespondWithErrorMessage(
			h.NoAuthMessage,
			http.StatusForbidden,
		)
		return
	}

	query := c.Request.URL.Query()

	limit, offset, status, err := h.GetLimitAndOffset(query)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	attachments, total, pages, status, err := models.GetAttachments(itemTypeID, itemID, limit, offset)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	thisLink := h.GetLinkToThisPage(*c.Request.URL, offset, limit, total)

	m := models.AttachmentsType{}
	m.Attachments = h.ConstructArray(
		attachments,
		h.APITypeAttachment,
		total,
		limit,
		offset,
		pages,
		c.Request.URL,
	)
	m.Meta.Links =
		[]h.LinkType{
			h.LinkType{Rel: "self", Href: thisLink.String()},
		}
	m.Meta.Permissions = perms

	c.RespondWithData(m)
}
コード例 #25
0
ファイル: sites.go プロジェクト: riseofthetigers/microcosm
// ReadMany handles GET for a collection
func (ctl *SitesController) ReadMany(c *models.Context) {
	limit, offset, status, err := h.GetLimitAndOffset(c.Request.URL.Query())
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	var userID int64

	// Passing ?filter=owned returns sites owned by logged-in user.
	if c.Request.FormValue("filter") == "owned" {
		if c.Auth.UserID == 0 {
			c.RespondWithErrorMessage(
				fmt.Sprintf("You must be logged in to list your own sites"),
				http.StatusForbidden,
			)
			return
		}

		userID = c.Auth.UserID
	}

	// Passing 0 as userID means return all sites.
	ems, total, pages, status, err := models.GetSites(userID, limit, offset)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	thisLink := h.GetLinkToThisPage(*c.Request.URL, offset, limit, total)

	m := models.SitesType{}
	m.Sites = h.ConstructArray(
		ems,
		h.APITypeSite,
		total,
		limit,
		offset,
		pages,
		c.Request.URL,
	)
	m.Meta.Links =
		[]h.LinkType{
			h.LinkType{Rel: "self", Href: thisLink.String()},
		}

	c.RespondWithData(m)
}
コード例 #26
0
// Read handles GET
func (ctl *CommentContextController) Read(c *models.Context) {
	_, itemTypeID, itemID, status, err := c.GetItemTypeAndItemID()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

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

	limit, _, status, err := h.GetLimitAndOffset(c.Request.URL.Query())
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

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

	link, status, err := m.GetPageLink(limit, c.Auth.ProfileID)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	pageURL, err := url.Parse(link.Href)
	if err != nil {
		c.RespondWithErrorMessage(err.Error(), http.StatusInternalServerError)
		return
	}

	queryString := pageURL.Query()
	queryString.Add("comment_id", strconv.FormatInt(m.ID, 10))
	pageURL.RawQuery = queryString.Encode()

	c.RespondWithLocation(pageURL.String())
}
コード例 #27
0
ファイル: whoami.go プロジェクト: riseofthetigers/microcosm
func (wc *WhoAmIController) Read(c *models.Context) {

	if c.Request.Method != "GET" {
		c.RespondWithNotImplemented()
		return
	}

	if c.Auth.UserID < 0 {
		c.RespondWithErrorMessage(
			"Bad access token supplied",
			http.StatusForbidden,
		)
		return
	}

	if c.Auth.UserID == 0 {
		c.RespondWithErrorMessage(
			"You must be authenticated to ask 'who am I?'",
			http.StatusForbidden,
		)
		return
	}

	m, status, err := models.GetProfileSummary(c.Site.ID, c.Auth.ProfileID)
	if err != nil {
		if status == http.StatusNotFound {
			c.RespondWithErrorMessage(
				"You must create a user profile for this site at api/v1/profiles/",
				http.StatusNotFound,
			)
			return
		}

		c.RespondWithErrorMessage(
			fmt.Sprintf("Could not retrieve profile: %v", err.Error()),
			http.StatusInternalServerError,
		)
		return
	}

	location := fmt.Sprintf(
		"%s/%d",
		h.APITypeProfile,
		m.ID,
	)

	if c.Auth.ProfileID > 0 && c.Auth.Method == "query" {
		u, _ := url.Parse(location)
		qs := u.Query()
		qs.Del("access_token")
		qs.Add("access_token", c.Auth.AccessToken.TokenValue)
		u.RawQuery = qs.Encode()
		location = u.String()
	}

	c.ResponseWriter.Header().Set("Location", location)
	c.RespondWithStatus(307)
}
コード例 #28
0
ファイル: comment.go プロジェクト: riseofthetigers/microcosm
// Delete handles DELETE
func (ctl *CommentController) Delete(c *models.Context) {
	_, itemTypeID, itemID, status, err := c.GetItemTypeAndItemID()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

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

	// Partially instantiated type for Id passing
	m, status, err := models.GetCommentSummary(c.Site.ID, itemID)
	if err != nil {
		if status == http.StatusNotFound {
			c.RespondWithOK()
			return
		}

		c.RespondWithErrorDetail(err, status)
		return
	}

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

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

	c.RespondWithOK()
}
コード例 #29
0
ファイル: watchers.go プロジェクト: riseofthetigers/microcosm
// ReadMany handles GET for the collection
func (ctl *WatchersController) ReadMany(c *models.Context) {

	if c.Auth.ProfileID < 1 {
		c.RespondWithErrorMessage(h.NoAuthMessage, http.StatusForbidden)
		return
	}

	query := c.Request.URL.Query()

	limit, offset, status, err := h.GetLimitAndOffset(query)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	ems, total, pages, status, err := models.GetProfileWatchers(
		c.Auth.ProfileID,
		c.Site.ID,
		limit,
		offset,
	)
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

	// Construct the response
	thisLink := h.GetLinkToThisPage(*c.Request.URL, offset, limit, total)

	m := models.WatchersType{}
	m.Watchers = h.ConstructArray(
		ems,
		h.APITypeWatcher,
		total,
		limit,
		offset,
		pages,
		c.Request.URL,
	)
	m.Meta.Links =
		[]h.LinkType{
			h.LinkType{Rel: "self", Href: thisLink.String()},
		}

	c.RespondWithData(m)

}
コード例 #30
0
ファイル: huddle.go プロジェクト: riseofthetigers/microcosm
// Delete handles DELETE
func (ctl *HuddleController) Delete(c *models.Context) {
	_, itemTypeID, itemID, status, err := c.GetItemTypeAndItemID()
	if err != nil {
		c.RespondWithErrorDetail(err, status)
		return
	}

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

	m, status, err := models.GetHuddle(c.Site.ID, c.Auth.ProfileID, itemID)
	if err != nil {
		if status == http.StatusNotFound {
			c.RespondWithOK()
			return
		}

		c.RespondWithErrorDetail(err, status)
		return
	}

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

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

	c.RespondWithOK()
}