Search Apps Documentation Source Content File Folder Download Copy Actions Download

member_grouping_options.gno

1.93 Kb · 49 lines
 1package commondao
 2
 3// MemberGroupingOption configures member groupings.
 4type MemberGroupingOption func(MemberGrouping)
 5
 6// SECURITY XXX: UseStorageFactory captures a caller-supplied factory
 7// that returns the MemberStorage used to track who is a DAO member.
 8// A malicious factory can return a MemberStorage impl that lies about
 9// membership — always-true (everyone is a member, votes pass trivially)
10// or always-false (legitimate members are locked out). This isn't a
11// cur-leak; it's a behavior-substitution risk on the data layer the
12// DAO's voting and proposal logic depends on.
13// Fix: document that the factory must come from trusted code (a
14// hardcoded constructor in the DAO realm itself), and never accept
15// a UseStorageFactory option from external-realm input. Or restrict
16// to a canonical-impl allowlist (type-switch on known MemberStorage
17// types) in commondao itself.
18//
19// UseStorageFactory assigns a custom member storage creation function to the grouping.
20// Creation function is called each time a member group is added, with the name of the
21// group as the only argument, to create a storage where the new group stores its members.
22func UseStorageFactory(fn func(group string) MemberStorage) MemberGroupingOption {
23	if fn == nil {
24		panic("storage factory function must not be nil")
25	}
26
27	return func(g MemberGrouping) {
28		grouping, ok := g.(*memberGrouping)
29		if !ok {
30			panic("storage factory not supported by member grouping")
31		}
32
33		grouping.createStorage = fn
34	}
35}
36
37// WithGroups creates multiple members groups.
38// To use a custom member storage factory to create the groups make sure that this option
39// comes after the `UseStorageFactory()` option, otherwise groups are created using the
40// default factory which is `commondao.NewMemberStorage()`.
41func WithGroups(names ...string) MemberGroupingOption {
42	return func(g MemberGrouping) {
43		for _, name := range names {
44			if _, err := g.Add(name); err != nil {
45				panic(err)
46			}
47		}
48	}
49}