Skip to content

Instantly share code, notes, and snippets.

@rjindael
Last active September 28, 2023 06:09
Show Gist options
  • Save rjindael/a28de43c365435dfc5054ddcdbaa3149 to your computer and use it in GitHub Desktop.
Save rjindael/a28de43c365435dfc5054ddcdbaa3149 to your computer and use it in GitHub Desktop.
/*
* Check if a user can perform an action (with its value in "flag") of a specific roleset (named with "roleset".)
* Optionally, may check for if the user is a superadmin (with "shouldWeCareIfThisUserIsSuperadmin") as if the user
* is a superadmin, this function will return true no matter what since superadmins have every permission.
*/
bool may(string roleset, string flag, bool shouldWeCareIfThisUserIsSuperadmin) {
// (1). Because users that are superadmin has every permission regardless of their roleset permission, check for that.
if (!shouldWeCareIfThisUserIsSuperadmin && this.isSuperAdmin()) {
return true;
}
// (2). Check if the user has the permission.
/*
* The ampersand (&) is the bitwise AND operator that we apply to the flag (e.g. Catalog::MAY_UPLOAD_LIMITEDS, an int) and the overall roleset integer.
* The roleset integer is just a big arbitrary number, like 123456. We don't really care about its content, but what I'll call its "bitwise ability."
*
* Think of the roleset integer as a huge array of true/false values, like [true, false, false, true, true, false, true, true, true, false, true, ...]
* The permission flag itself is sort of the position within the array (i.e. hugeArray[flag], flag being the integer position in said hugeArray) that
* holds the true/false value. Knowing the contents of the array and the exact position for each true false value, we can condense it into one big integer
* (the roleset integer) and use the bitwise AND operator to check if the position of the flag is true (any positive non-zero number) or false (zero.)
*
* However, flags can't be just anything. They follow this pattern: 1, 4, 8, 16, 32, 64, 128, 256, 512, 1024, etc.
* An easier way (than writing out all the numbers) is to just use the bitwise operator "<<", called the bitwise left shift.
* It has a wide variety of purposes, but we can use it for simple multiplication/exponential multiplication.
* Thus, 1 << 0, 1 << 1, 1 << 2, 1 << 3, would all equal to 1, 4, 8, 16, respectively.
*/
if ((this.getRolesetInteger(roleset) & flag) != 0) {
return true;
} else {
return false;
}
}
/*
* Grant a certain permission (with its value in "flag") to a specific roleset (named with "roleset".)
*/
void allow(string roleset, string flag) {
int rolesetInteger = this.getRolesetInteger(roleset);
this.setRolesetInteger(roleset, rolesetInteger & flag);
// If you would like to add multiple flags at once, you could use the pipe symbol (|) which is the bitwise OR operator.
// Example: rolesetInteger | flag1 | flag2 | flag3
}
/*
* Revoke a certain permission (with its value in "flag") from a specific roleset (named with "roleset".)
*/
void disallow(string roleset, string flag) {
int rolesetInteger = this.getRolesetInteger(roleset);
this.setRolesetInteger(roleset, rolesetInteger & ~flag); // The tilde symbol here (~) here means "NOT", essentially the bitwise opposite of the specified integer.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment