parsav  Diff

Differences From Artifact [763fd9ba8a]:

To Artifact [69369cc5c2]:


    12     12   	relation = lib.enum {
    13     13   		'follow', 'mute', 'block'
    14     14   	};
    15     15   	credset = lib.set {
    16     16   		'pw', 'otp', 'challenge', 'trust'
    17     17   	};
    18     18   	privset = lib.set {
    19         -		'post', 'edit', 'acct', 'upload', 'censor', 'admin'
           19  +		'post', 'edit', 'acct', 'upload', 'censor', 'admin', 'invite'
    20     20   	};
    21     21   	powerset = lib.set {
    22     22   		-- user powers -- default on
    23     23   		'login', 'visible', 'post', 'shout',
    24     24   		'propagate', 'upload', 'acct', 'edit';
    25     25   
    26     26   		-- admin powers -- default off
    27     27   		'purge', 'config', 'censor', 'suspend',
    28     28   		'cred', 'elevate', 'demote', 'rebrand', -- modify site's brand identity
    29         -		'herald' -- grant serverwide epithets
           29  +		'herald', -- grant serverwide epithets
           30  +		'invite' -- *unlimited* invites
    30     31   	};
    31     32   	prepmode = lib.enum {
    32     33   		'full','conf','admin'
    33     34   	}
    34     35   }
    35     36   
    36     37   m.privmap = {}
................................................................................
    52     53   
    53     54   struct m.source
    54     55   
    55     56   struct m.rights {
    56     57   	rank: uint16 -- lower = more powerful except 0 = regular user
    57     58   	-- creating staff automatically assigns rank immediately below you
    58     59   	quota: uint32 -- # of allowed tweets per day; 0 = no limit
           60  +	invites: intptr -- # of people left this user can invite
    59     61   	
    60     62   	powers: m.powerset
    61     63   }
    62     64   
    63     65   terra m.rights_default()
    64         -	var pow: m.powerset pow:fill()
    65         -	(pow.purge << false)
    66         -	(pow.config << false)
    67         -	(pow.censor << false)
    68         -	(pow.suspend << false)
    69         -	(pow.elevate << false)
    70         -	(pow.demote << false)
    71         -	(pow.cred << false)
    72         -	(pow.rebrand << false)
    73         -	return m.rights { rank = 0, quota = 1000, powers = pow; }
           66  +	var pow: m.powerset pow:clear()
           67  +	(pow.login     << true)
           68  +	(pow.visible   << true)
           69  +	(pow.post      << true)
           70  +	(pow.shout     << true)
           71  +	(pow.propagate << true)
           72  +	(pow.upload    << true)
           73  +	(pow.acct      << true)
           74  +	(pow.edit      << true)
           75  +	return m.rights { rank = 0, quota = 1000, invites = 0, powers = pow; }
    74     76   end
    75     77   
    76     78   struct m.actor {
    77     79   	id: uint64
    78     80   	nym: str
    79     81   	handle: str
    80     82   	origin: uint64
................................................................................
   191    193   		var bytes = bits / 8
   192    194   		var hexchs = bytes * 2
   193    195   		var segs = hexchs / 4
   194    196   		var seps = segs - 1
   195    197   		var maxsz = hexchs + seps + 1
   196    198   	else return nil end
   197    199   end
          200  +
          201  +struct m.kompromat {
          202  +-- The Evidence
          203  +	id: uint64
          204  +	perp: uint64 -- whodunnit
          205  +	desc: str
          206  +	post: uint64 -- the post in question, if any
          207  +	reporter: uint64 -- 0 = originated automatically by the System itself
          208  +	resolution: str -- null for unresolved
          209  +	-- as proto: set resolution to empty string to search for resolved incidents
          210  +}
          211  +
          212  +struct m.sanction {
          213  +	id: uint64
          214  +	issuer: uint64
          215  +	scope: uint64
          216  +	nature: uint16
          217  +	victim: uint64
          218  +	autoexpire: bool  expire: m.timepoint
          219  +	timedreview: bool review: m.timepoint
          220  +	reason: str
          221  +	context: str
          222  +}
   198    223   
   199    224   struct m.auth {
          225  +-- a credential record
   200    226   	aid: uint64
   201    227   	uid: uint64
   202    228   	aname: str
   203    229   	netmask: m.inet
   204    230   	privs: m.privset
   205    231   	blacklist: bool
   206    232   }
................................................................................
   209    235   struct m.backend { id: rawstring
   210    236   	open: &m.source -> &opaque
   211    237   	close: &m.source -> {}
   212    238   	dbsetup: &m.source -> bool -- creates the schema needed to call conprep (called only once per database e.g. with `parsav db init`)
   213    239   	conprep: {&m.source, m.prepmode.t} -> {} -- prepares queries and similar tasks that require the schema to already be in place
   214    240   	obliterate_everything: &m.source -> bool -- wipes everything parsav-related out of the database
   215    241   
          242  +	tx_enter: &m.source -> bool
          243  +	tx_complete: &m.source -> bool
          244  +	-- these two functions are special, in that they should be called
          245  +	-- directly on a specific backend, rather than passed down to the
          246  +	-- backends by the server; that is pathological behavior that will
          247  +	-- not have the desired effect
          248  +
   216    249   	conf_get: {&m.source, rawstring} -> lib.mem.ptr(int8)
   217    250   	conf_set: {&m.source, rawstring, rawstring} -> {}
   218    251   	conf_reset: {&m.source, rawstring} -> {}
   219    252   
   220    253   	actor_create: {&m.source, &m.actor} -> uint64
   221    254   	actor_save_privs: {&m.source, &m.actor} -> {}
   222    255   	actor_fetch_xid: {&m.source, lib.mem.ptr(int8)} -> lib.mem.ptr(m.actor)
................................................................................
   273    306   	auth_purge_pw: {&m.source, uint64, rawstring} -> {}
   274    307   	auth_purge_otp: {&m.source, uint64, rawstring} -> {}
   275    308   	auth_purge_trust: {&m.source, uint64, rawstring} -> {}
   276    309   
   277    310   	post_save: {&m.source, &m.post} -> {}
   278    311   	post_create: {&m.source, &m.post} -> uint64
   279    312   	post_enum_author_uid: {&m.source, uint64, m.range} -> lib.mem.ptr(lib.mem.ptr(m.post))
          313  +	post_attach_ctl: {&m.source, uint64, uint64, bool} -> {}
          314  +		-- attaches or detaches an existing database artifact
          315  +			-- post id: uint64
          316  +			-- artifact id: uint64
          317  +			-- detach: bool
          318  +	artifact_instantiate: {&m.source, lib.mem.ptr(uint8), lib.mem.ptr(int8)} -> uint64
          319  +		-- instantiate an artifact in the database, either installing a new
          320  +		-- artifact or returning the id of an existing artifact with the same hash
          321  +			-- artifact: bytea
          322  +			-- mime:     pstring
          323  +	artifact_quicksearch: {&m.source, lib.mem.ptr(uint8)} -> {uint64,bool}
          324  +		-- checks whether a hash is already in the database without uploading
          325  +		-- the entire file to the database server
          326  +			-- hash: bytea
          327  +				--> artifact id (0 if null), suppressed?
          328  +	artifact_expropriate: {&m.source, uint64, uint64, lib.mem.ptr(int8)} -> {}
          329  +		-- claims an existing artifact for the user's own collection
          330  +			-- uid:         uint64
          331  +			-- artifact id: uint64
          332  +			-- description: pstring
          333  +	artifact_disclaim: {&m.source, uint64, uint64} -> {}
          334  +		-- a user disclaims their ownership stake in an artifact, removing it from
          335  +		-- the database entirely if they were the only owner, and removing their
          336  +		-- description of it either way
          337  +			-- uid:         uint64
          338  +			-- artifact id: uint64
          339  +	artifact_excise: {&m.source, uint64, bool} -> {}
          340  +		-- (admin action) forcibly excise an artifact from the database, deleting
          341  +		-- all links to it and removing it from users' collections. if "blacklist,"
          342  +		-- the artifact will be banned and attempts to upload it in the future
          343  +		-- will fail, triggering a report. mainly intended for dealing with spam,
          344  +		-- IP violations, That Which Shall Not Be Named, and various other infohazards.
          345  +			-- artifact id: uint64
          346  +			-- blacklist:   bool
          347  +
          348  +	nkvd_report_issue: {&m.source, &m.kompromat} -> {}
          349  +		-- an incidence of Badthink has been detected. report it immediately
          350  +		-- to the Supreme Soviet
          351  +	nkvd_reports_enum: {&m.source, &m.kompromat} -> lib.mem.ptr(m.kompromat)
          352  +		-- search through the Archives
          353  +			-- proto: kompromat (null for all records, or a prototype describing the records to return)
          354  +	nkvd_sanction_issue:  {&m.source, &m.sanction} -> uint64
          355  +	nkvd_sanction_vacate: {&m.source, uint64} -> {}
          356  +	nkvd_sanction_enum_target: {&m.source, uint64} -> {}
          357  +	nkvd_sanction_enum_issuer: {&m.source, uint64} -> {}
          358  +	nkvd_sanction_review: {&m.source, m.timepoint} -> {}
          359  +
   280    360   	convo_fetch_xid: {&m.source,rawstring} -> lib.mem.ptr(m.post)
   281         -	convo_fetch_uid: {&m.source,uint64} -> lib.mem.ptr(m.post)
          361  +	convo_fetch_cid: {&m.source,uint64} -> lib.mem.ptr(m.post)
   282    362   
   283    363   	timeline_actor_fetch_uid: {&m.source, uint64, m.range} -> lib.mem.ptr(lib.mem.ptr(m.post))
   284    364   	timeline_instance_fetch: {&m.source, m.range} -> lib.mem.ptr(lib.mem.ptr(m.post))
   285    365   }
   286    366   
   287    367   struct m.source {
   288    368   	backend: &m.backend