// Only called when doing update or delete. // At inserting, user.OkayToDoAction is sufficient. // This needs additional action: you can only update or delete a given comment only if it's yours (under a certain level). func CanModifyComment(db *mgo.Database, inp map[string][]string, correction_level int, user_id bson.ObjectId, user_level int) error { rule := map[string]interface{}{ "content_id": "must", "comment_id": "must", "type": "must", } dat, err := extract.New(rule).Extract(inp) if err != nil { return err } // Even if he has the required level, and he is below correction_level, he can't modify other people's comment, only his owns. // So we query here the comment and check who is the owner of it. if user_level < correction_level { content_id_str := basic.StripId(dat["content_id"].(string)) comment_id_str := basic.StripId(dat["comment_id"].(string)) auth, err := findCommentAuthor(db, content_id_str, comment_id_str) if err != nil { return err } if auth.Hex() != user_id.Hex() { return fmt.Errorf("You are not the rightous owner of the comment.") } } return nil }
// Creates nonexisting tags if needed and pushes the tag ids into the content, and increments the tag counters. func addTags(db *mgo.Database, dat map[string]interface{}, id string, mod, typ string) { content := map[string]interface{}{} if mod != "insert" { content = find(db, basic.StripId(id)) } tags_i, _ := dat[Tag_fieldname_displayed] delete(dat, Tag_fieldname_displayed) tags := tags_i.(string) // Example: "Cars, Bicycles" tags_sl := strings.Split(tags, ",") tags_sl = stripEmpty(tags_sl) switch mod { case "insert": existing_ids, to_insert_slugs := separateTags(db, tags_sl) inserted_ids := insertTags(db, to_insert_slugs) all_ids := mergeIds(existing_ids, inserted_ids) inc(db, all_ids, typ) dat[Tag_fieldname] = all_ids case "update": existing_ids, to_insert_slugs := separateTags(db, tags_sl) inserted_ids := insertTags(db, to_insert_slugs) old_ids := toIdSlice(content[Tag_fieldname].([]interface{})) new_ids := mergeIds(existing_ids, inserted_ids) inc_ids := diffIds(new_ids, old_ids) inc(db, inc_ids, typ) addToSet(db, content["_id"].(bson.ObjectId), new_ids) default: panic("Bad mode at addTags.") } }
// Implementation of versioning is in basic.InudVersion. func ChangeHead(db *mgo.Database, ev ifaces.Event, inp map[string][]string, non_versioned_fields []string) error { rule := map[string]interface{}{ "version_id": "must", "id": "must", } dat, err := extract.New(rule).Extract(inp) if err != nil { return err } version_id_str := basic.StripId(dat["version_id"].(string)) version_id := bson.ObjectIdHex(version_id_str) var v interface{} err = db.C(Cname + "_version").Find(bson.M{"_id": version_id}).One(&v) if err != nil { return err } revert_to := v.(bson.M) id := patterns.ToIdWithCare(dat["id"].(string)) for _, v := range non_versioned_fields { delete(revert_to, v) } revert_to["points_to"] = revert_to["_id"] delete(revert_to, "id") return db.C(Cname).Update(bson.M{"_id": id}, bson.M{"$set": revert_to}) }
func update(db *mgo.Database, ev ifaces.Event, rule map[string]interface{}, dat map[string][]string, user_id bson.ObjectId, fixvals map[string]interface{}) error { rule["id"] = "must" rule["type"] = "must" rule["draft_id"] = "must" upd_dat, extr_err := extract.New(rule).Extract(dat) if extr_err != nil { return extr_err } id := upd_dat["id"].(string) typ := upd_dat["type"].(string) basic.DateAndAuthor(rule, upd_dat, user_id, true) upd_dat["type"] = typ _, has_tags := upd_dat[Tag_fieldname_displayed] if has_tags { addTags(db, upd_dat, id, "update", typ) } basic.Slug(rule, upd_dat) mergeMaps(upd_dat, fixvals) err := basic.InudVersion(db, ev, upd_dat, Cname, "update", id) if err != nil { return err } _, has_fulltext := rule["fulltext"] id_bson := bson.ObjectIdHex(basic.StripId(id)) if has_fulltext { saveFulltext(db, id_bson) } return nil }
// Removes tag(s) from a given content, so the content will no longer belong to that category(s) (tag(s)). // Pulls one or more tag ids from a content and decrements the tag counters. func PullTags(db *mgo.Database, content_id string, tag_ids []string) error { content_id = basic.StripId(content_id) content := find(db, content_id) typ := content["type"].(string) if content == nil { return fmt.Errorf("Cant find content when pulling tags.") } tag_objectids := content[Tag_fieldname].([]interface{}) cache := createMObjectId(toIdSlice(tag_objectids)) to_pull := []bson.ObjectId{} for _, v := range tag_ids { tag_id := basic.StripId(v) tag_objectid := bson.ObjectIdHex(tag_id) if _, has := cache[tag_objectid]; has { to_pull = append(to_pull, tag_objectid) } } dec(db, to_pull, typ) q := m{"_id": content["_id"].(bson.ObjectId)} upd := m{"$pullAll": m{Tag_fieldname: to_pull}} return db.C(Cname).Update(q, upd) }