Last active
March 1, 2021 23:05
-
-
Save typhartez/b8de5abc4db9b87a268327de1e2d77b6 to your computer and use it in GitHub Desktop.
Authorization reusable script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Access reusable script: define authorizations from an access control list notecard | |
| // Typhaine Artez 2021 | |
| // Under Creative Commons License Attribution-NonCommercial-ShareAlike 4.0 International | |
| // | |
| // Sample .access notecard (/* and */ are not part of the notecard content): | |
| /* | |
| # Authorization notecard. Empty lines or lines starting with # are ignored | |
| # Without configuration, only the owner is allowed to use | |
| # mode = group to enable everyone wearing the same group tag than the object | |
| # mode = all to enable everyone | |
| mode = group | |
| mode = all | |
| # Each line starts with allow or deny, the value determine who is concerned, | |
| # with one of the following formats: | |
| # @grid-name | |
| # Everyone in that grid | |
| # Firstname Lastname | |
| # This avatar matching Firstname Lastname (any grid, case insensitive) | |
| # 7a60dc25-0884-4474-9b0f-bf5844d34d80 | |
| # The avatar with this UUID | |
| deny = @bad-grid.com:8002 | |
| deny = 7a60dc25-0884-4474-9b0f-bf5844d34d80 | |
| deny = Obvious Griefer | |
| allow = Typhaine Artez | |
| */ | |
| //////////////////////////////////////////////////////////////////////////////////////////////////// | |
| list acls; // authorization list (first item is mode ("O"=owner, "G"=group, "A"=all) | |
| // followed by pairs of items: "A" for allow, "D" for deny, then the access definition | |
| key nckey; // .access notecard (for automatic reload on notecard change) | |
| integer ncline; // parse notecard | |
| //////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // Load Access Control List from notecard | |
| // Returns TRUE if some data need to be read | |
| integer reloadACLs(string data) { | |
| if (EOF == data) { | |
| llOwnerSay("Authorizations loaded."); | |
| return FALSE; | |
| } | |
| if ("--START--" == data) { | |
| nckey = llGetInventoryKey(".access"); | |
| if (NULL_KEY != nckey) { | |
| acls = ["O"]; // by default, owner only | |
| ncline = 0; | |
| llGetNotecardLine(".access", ncline); | |
| return TRUE; | |
| } | |
| // no ACLs used | |
| acls = ["A"]; // by default, everyone | |
| return FALSE; | |
| } | |
| if ("" != data && 0 != llSubStringIndex(data, "#")) { | |
| // read data | |
| integer sep = llSubStringIndex(data, "="); | |
| if (~sep) { | |
| string kw = llToLower(llStringTrim(llGetSubString(data, 0, sep-1), STRING_TRIM)); | |
| string val = llToLower(llStringTrim(llGetSubString(data, sep+1, -1), STRING_TRIM)); | |
| if ("mode" == kw) { | |
| if ("all" == val) val = "A"; | |
| else if ("group" == val) val = "G"; | |
| else if ("owner" == val) val = "O"; | |
| else val = ""; | |
| if ("" != val) acls = llListReplaceList(acls, [val], 0, 0); | |
| } | |
| else if ("allow" == kw) acls += ["A", val]; | |
| else if ("deny" == kw) acls += ["D", val]; | |
| else llOwnerSay("Warning: unrecognized line: " + data); | |
| } | |
| } | |
| // read next line | |
| llGetNotecardLine(".access", ++ncline); | |
| return TRUE; | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // Returns TRUE if user key is allowed to operate | |
| integer isAuthorized(key id) { | |
| if (llGetOwner() == id) return TRUE; // owner always allowed | |
| string mode = llList2String(acls, 0); | |
| string type; | |
| string auth; | |
| string name = llToLower(osReplaceString(osReplaceString(llKey2Name(id), " ?@.*$", "", 1, 0), "\\.", " ", -1, 0)); | |
| integer pos; | |
| integer n = llGetListLength(acls) - 2; | |
| for (; 0 < n; n -= 2) { | |
| type = llList2String(acls, n); | |
| auth = llList2String(acls, n+1); | |
| // check agent key, the faster | |
| if (osIsUUID(auth) && id == (key)auth) return ("A" == type); | |
| // normalize name first last (all lower case, without grid suffix, no dots) | |
| auth = osReplaceString(osReplaceString(auth, " ?@.*$", "", 1, 0), "\\.", " ", -1, 0); | |
| if (-1 != ~llSubStringIndex(name, auth)) return ("A" == type); | |
| } | |
| // not matched, check mode | |
| if ("A" == mode || ("G" == mode && llSameGroup(id))) return TRUE; | |
| return FALSE; // owner only | |
| } | |
| //////////////////////////////////////////////////////////////////////////////////////////////////// | |
| default { | |
| changed(integer c) { | |
| if (CHANGED_OWNER & c) llResetScript(); | |
| if ((CHANGED_INVENTORY & c) && (llGetInventoryKey(".access") != nckey)) reloadACLs("--START--"); | |
| } | |
| state_entry() { | |
| reloadACLs("--START--"); | |
| } | |
| touch_start(integer n) { | |
| if (!isAuthorized(llDetectedKey(0))) { | |
| llOwnerSay("sorry, you cannot do that"); | |
| } | |
| } | |
| dataserver(key id, string data) { | |
| if (!reloadACLs(data)) { | |
| llOwnerSay("> Default allow " + llList2String(["owner only", "same group", "everyone"], | |
| llListFindList(["O","G","A"], [llList2String(acls, 0)]))); | |
| integer n = llGetListLength(acls) - 2; | |
| for (; 0 < n; n -= 2) llOwnerSay("> " + | |
| llList2String(["Allow ", "Deny "], llListFindList(["A","D"], [llList2String(acls, n)])) | |
| + llList2String(acls, n+1)); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment