1

In c# it is quite common to find the following Enum structure

[Flags] public enum Permission { Read = 1 << 1, Create = 1 << 2, Update = 1 << 3, Destroy = 1 << 4 } 

which allows you to join enums like this: Permission.Read|Permission.Create

I am now faced with a different sort of requirement, and the solutions I have come up with are problematic IMO.

I need to allow some sort of enum implementation to multiple types of premissions - some contradicting, and some aren't

and I want the following sort of functionality

[Flags] public enum Permission { Read1 = 1, Read2 = 2, Read3 = 3, Write1 = 10, Write2 = 20, Write3 = 30, Update1 = 100, Update2 = 200, Update3 = 300, Destory = 1000, Other = 10000, SomethingElse = 100000, } 

when this won't work Permission.Read1|Permission.Read2 mainly because it means a user now has a reading permission level 3

besides using different bit flag for each Permission (which will require my db to hold a much larger integer than a INT for a very bad reason), or having a different enum (and column) per permission (which will limit my flexibility with the permissions) , and having no form of compile time verification (I guess I can create some sort of a workarroundish runtime verification) do you have any other idea?

3
  • Is it a different type of permission or is it a different object that the permission is on? ie. Read1 is read on object type XXX, Read2 on YYY, and Read3 ... etc? Commented Aug 23, 2016 at 16:36
  • This structure is mainly for illustration. The actual permission reguards to a level of permission for different resources as in Read1..3 is for object xxx and Write1..3 is for object YYY Commented Aug 23, 2016 at 16:41
  • 2
    Then you should change the structure. If it were a type it would have 2 properties: PermissionFlags, ObjectType (same for a table in a relational database, 2 columns). ObjectType would be the thing that the permission applies to. Keep your permissions as generic as possible. I doubt that there is a solution that would enable you to catch illegal combinations of permissions at compile time, you would have to create run-time validation and/or add validation logic in the database. Commented Aug 23, 2016 at 16:43

1 Answer 1

1

Your db doesn't need to store bigger than int. 32bits can accommodate lot more values for unique bit flags. Following hex values are unique binary bit flags. Read1 | Read2 won't equal Read3

[Flags] public enum Permission { Read1 = 0x00000001, Read2 = 0x00000002, Read3 = 0x00000004, Write1 = 0x00000008, Write2 = 0x00000010, Write3 = 0x00000020, Update1 = 0x00000040, Update2 = 0x00000080, Update3 = 0x00000100, Destory = 0x00000400, Other = 0x00000800, SomethingElse = 0x00001000, } 

You can probably organize these better by blocking certain bit blocks as Read, Write etc. E.g. you can block Read to be blocked for first 8 bits, write for next 8 bits so on and so forth. That way, you can accommodate future changes and also use bit masking effectively.

Sign up to request clarification or add additional context in comments.

1 Comment

It does limit me to a certain amount of permission types though - and since this is a new system I can't be sure it will stay that way. Since I can safely assume there won't be more than 10 permissions per action - and each user has only one action required - using more than a 16 bit integer seems wasteful to me - even though I can settle for a 32 bit integer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.