+(* Permissions and restrictions.
+ *
+ * Use the optional ~restrict parameter to register_script to restrict
+ * who can use the script. For example:
+ * register_script ~restrict:[CanEdit ; CanManageUsers] run
+ *)
+type permissions_t = CanEdit | CanManageUsers | CanManageContacts
+
+(* The "user object". *)
+type user_t = Anonymous (* Not logged in. *)
+ | User of int * string * permissions_t list
+ (* Userid, name, permissions. *)
+
+let test_permission edit_anon perm user =
+ if perm = CanEdit && edit_anon then true
+ else match user with
+ Anonymous -> false
+ | User (_, _, perms) -> List.mem perm perms
+
+let can_edit edit_anon = test_permission edit_anon CanEdit
+let can_manage_users = test_permission false CanManageUsers
+let can_manage_contacts = test_permission false CanManageContacts
+
+(* The "host object". *)
+type host_t = { hostname : string;
+ edit_anon : bool; }
+
+(* Our wrapper around the standard [register_script] function.
+ *
+ * The optional ~restrict and ~anonymous parameters work as follows:
+ *
+ * By default (neither parameter given), anonymous or logged-in users
+ * at any level are permitted to run the script.
+ *
+ * If ~anonymous:false then a user must be logged in to use the script.
+ *
+ * If ~restrict contains a list of permissions (eg. CanEdit, etc.) then
+ * the user must have the ability to do AT LEAST ONE of those actions.
+ * (Note that this does not necessarily imply that the user must be
+ * logged in, because in some circumstances even anonymous users have
+ * the CanEdit permission - very typical for a wiki).
+ *
+ * If ~anonymous:false and ~restrict is given then the user must be
+ * logged in AND have the ability to do AT LEAST ONE of those actions.
+ *)
+let register_script ?(restrict = []) ?(anonymous = true) run =