Tatsuki SUGIURA
sugi****@users*****
2006年 7月 12日 (水) 20:41:55 JST
Index: slashjp/plugins/ResKey/MANIFEST diff -u /dev/null slashjp/plugins/ResKey/MANIFEST:1.1 --- /dev/null Wed Jul 12 20:41:55 2006 +++ slashjp/plugins/ResKey/MANIFEST Wed Jul 12 20:41:55 2006 @@ -0,0 +1,19 @@ +Makefile.PL +MANIFEST +PLUGIN +ResKey.pm +ResKey/Checks/ACL.pm +ResKey/Checks/AL2/AnonNoPost.pm +ResKey/Checks/AL2/NoPost.pm +ResKey/Checks/AL2/NoPostAnon.pm +ResKey/Checks/AL2.pm +ResKey/Checks/Duration.pm +ResKey/Checks/Post.pm +ResKey/Checks/ProxyScan.pm +ResKey/Checks/User.pm +ResKey/Key.pm +example.plx +mysql_dump.sql +mysql_schema.sql +tasks/reskey_purge.pl +templates/data;reskey;default Index: slashjp/plugins/ResKey/Makefile.PL diff -u /dev/null slashjp/plugins/ResKey/Makefile.PL:1.1 --- /dev/null Wed Jul 12 20:41:55 2006 +++ slashjp/plugins/ResKey/Makefile.PL Wed Jul 12 20:41:55 2006 @@ -0,0 +1,10 @@ +use ExtUtils::MakeMaker; + +WriteMakefile( + 'NAME' => 'Slash::ResKey', + 'VERSION_FROM' => 'ResKey.pm', # finds $VERSION +# 'PM' => { +# 'ResKey.pm' => '$(INST_LIBDIR)/ResKey.pm', +# 'ResKey/Checks/User.pm' => '$(INST_LIBDIR)/ResKey/Checks/User.pm', +# }, +); Index: slashjp/plugins/ResKey/PLUGIN diff -u /dev/null slashjp/plugins/ResKey/PLUGIN:1.1 --- /dev/null Wed Jul 12 20:41:55 2006 +++ slashjp/plugins/ResKey/PLUGIN Wed Jul 12 20:41:55 2006 @@ -0,0 +1,8 @@ +# $Id: PLUGIN,v 1.1 2006/07/12 11:41:55 sugi Exp $ +description="Resource Keys" +name=ResKey +mysql_dump=mysql_dump.sql +mysql_schema=mysql_schema.sql +template=templates/data;reskey;default +template=templates/reskey_tag;misc;default +task=tasks/reskey_purge.pl Index: slashjp/plugins/ResKey/ResKey.pm diff -u /dev/null slashjp/plugins/ResKey/ResKey.pm:1.1 --- /dev/null Wed Jul 12 20:41:55 2006 +++ slashjp/plugins/ResKey/ResKey.pm Wed Jul 12 20:41:55 2006 @@ -0,0 +1,253 @@ +# This code is a part of Slash, and is released under the GPL. +# Copyright 1997-2005 by Open Source Technology Group. See README +# and COPYING for more information, or see http://slashcode.com/. +# $Id: ResKey.pm,v 1.1 2006/07/12 11:41:55 sugi Exp $ + +package Slash::ResKey; + +=head1 NAME + +Slash::ResKey - Resource management for Slash + + +=head1 SYNOPSIS + + my $reskey = getObject('Slash::ResKey'); + my $key = $reskey->key('zoo'); + if ($key->create) { ... } + if ($key->touch) { ... } + if ($key->use) { ... } + else { print $key->errstr } + + +=head1 DESCRIPTION + +Slash::ResKey is for managing resources. You get a key object by requesting +a specific sort of resource with the C<key> method, which takes the name +of the resource (an arbitrary string, defined in the database table +C<reskey_resources>). + +Optionally, C<key> takes a hashref of keys "reskey" and "debug". Debug levels +are 0, 1, and 2, with default 0. If you don't include a reskey, it will +be determined automatically from C<getCurrentForm('reskey')>. + +See L<Slash::ResKey::Key> for more info on what to do with an object returned +by <key>. + +=cut + +use warnings; +use strict; + +use Slash; +use Slash::Constants ':reskey'; +use Slash::ResKey::Key; +use Slash::Utility; + +use base 'Slash::DB::Utility'; +use base 'Slash::DB::MySQL'; + +our($AUTOLOAD); +our($VERSION) = ' $Revision: 1.1 $ ' =~ /\$Revision:\s+([^\s]+)/; + +our $DEBUG = 0; + +#======================================================================== +sub new { + my($class, $user) = @_; + my $self = {}; + + my $plugin = getCurrentStatic('plugin'); + return unless $plugin->{'ResKey'}; + + bless($self, $class); + $self->{virtual_user} = $user; + + return $self; +} + +#======================================================================== +sub key { + my($self, $resource, $opts) = @_; + + $opts ||= {}; + $opts->{debug} = $DEBUG unless defined $opts->{debug}; + + return Slash::ResKey::Key->new( + $self->{virtual_user}, + $resource, + $opts->{reskey}, + $opts->{debug}, + $opts + ); +} + +#======================================================================== +# For tasks/reskey_purge.pl +sub purge_old { + my($self) = @_; + + my $count = 0; + + # first, purge all old reskeys + my $timeframe = getCurrentStatic('reskey_timeframe') || 14400; + $count += $self->sqlDelete('reskeys', "create_ts < DATE_SUB(NOW(), INTERVAL $timeframe SECOND)"); + + + # next, purge all reskeys that are used and older than duration_uses + my $uses = $self->sqlSelectAll('rkrid, value', 'reskey_vars', 'name="duration_uses"'); + for (@$uses) { + my($rkrid, $seconds) = @$_; + $count += $self->sqlDelete('reskeys', + "rkrid = $rkrid AND is_alive = 'no' AND " . + "submit_ts IS NOT NULL AND " . + "submit_ts < DATE_SUB(NOW(), INTERVAL $seconds SECOND)" + ); + } + + + # then, delete all used reskeys where duration_uses and + # duration_max-uses are not in use + my $max_uses = $self->sqlSelectAll('rkrid', 'reskey_vars', 'name="duration_max-uses"'); + my %rkids = map { $_->[0] => 1 } (@$uses, @$max_uses); + my $rkid_str = join ', ', keys %rkids; + $count += $self->sqlDelete('reskeys', "rkrid NOT IN ($rkid_str) AND is_alive = 'no'"); + + + # finally, delete orphaned reskey_failures entries + my $rkids = $self->sqlSelectAll('rkf.rkid', + 'reskey_failures AS rkf LEFT JOIN reskeys AS rk ON rk.rkid=rkf.rkid', + 'rk.rkid IS NULL' + ); + + if (@$rkids) { + my $rkid_string = join ',', map { $_->[0] } @$rkids; + $count += $self->sqlDelete('reskey_failures', "rkid IN ($rkid_string)"); + } + + return $count; +} + +1; + +__END__ + + +=head1 SEE ALSO + +Slash(3). + +=head1 VERSION + +$Id: ResKey.pm,v 1.1 2006/07/12 11:41:55 sugi Exp $ + + +=head1 TODO + +=head2 Check Classes + +The default failure value is DEATH, rather than FAILURE, which is non-fatal: +callers can choose to re-display the form on FAILURE, whereas with DEATH +there's no reason to continue, but one must start over with a new form (if +indeed even that). + +=over 4 + +=item User (DONE) + +Admins can be skipped on these checks with a var. Simple checks for: + +=over 4 + +=item karma + +=item seclev + +=item is_subscriber + +=item is_admin + +=back + + +=item Duration + +We need to implement limit modulation. + +=over 4 + +=item min duration between uses (DONE) + +FAILURE + +=item min duration betwen creation and use (DONE) + +FAILURE + +=item max num of uses per time period (DONE) + +FAILURE + +=item max touches per reskey (NA) + +DEATH + +Not doing now, if ever. But will add if we feel a need. + +=item max simultaneous reskeys (NA) + +FAILURE + +I don't think this is necessary, since we've worked out some atomicity problems. + +If we do: report error, or invalidate old reskeys? Which ones? + +=back + + +=item HumanConf + +Still needs implementation. + + +=item AL2 (DONE) + +=over 4 + +=item NoPost + +This user cannot post. + +=item NoPostAnon + +This user cannot post anonymoously. + +=item AnonNoPost + +This user is anonymous -- or is posting anonymously -- and the anonymous user +cannot post. + +=back + + + +=item Proxy Scan (DONE) + +Simple wrapper around the proxy scan code. + + +=item ACL (DONE) + +If an ACL required, make sure user has it (is_admin bypasses this check (by default)). + +If an ACL prohibits access, make sure user does NOT have it (no bypass). + + +=item POST (NA) + +Probably best handled in .pl as we always have, though we could move it if we +felt a need. + + +=back + Index: slashjp/plugins/ResKey/example.plx diff -u /dev/null slashjp/plugins/ResKey/example.plx:1.1 --- /dev/null Wed Jul 12 20:41:55 2006 +++ slashjp/plugins/ResKey/example.plx Wed Jul 12 20:41:55 2006 @@ -0,0 +1,52 @@ +use strict; +use Slash::Test shift; + +my($reskey, $rkey, $rkey1, $rkey2, $rkey3); + +my $debug = 0; + +for (1..1) { + $reskey = getObject('Slash::ResKey'); + $rkey = $reskey->key('pollbooth', { + debug => $debug + }); + handle($rkey->createuse, $rkey); + + print Dumper $rkey; + + + $rkey1 = $reskey->key('comments', { + debug => $debug + }); + + handle($rkey1->create, $rkey1); + handle($rkey1->touch, $rkey1); + + $rkey2 = $reskey->key('comments', { + debug => $debug, + reskey => $rkey1->reskey, + }); + + handle($rkey2->touch, $rkey2); + + handle($rkey1->use, $rkey1); + sleep 5; + + $::form->{reskey} = $rkey1->reskey; + $rkey3 = $reskey->key('comments', { + debug => $debug, + }); + handle($rkey3->use, $rkey3) or print Dumper $rkey3; +} + + +sub handle { + my($success, $this_rkey) = @_; + if ($success) { + printf "%s'd %s\n", ucfirst($this_rkey->type), $this_rkey->reskey; + return 1; + } else { + printf "Error on %s: %s\n", $this_rkey->type, $this_rkey->errstr; + print Dumper $this_rkey; + } +} Index: slashjp/plugins/ResKey/flow.txt diff -u /dev/null slashjp/plugins/ResKey/flow.txt:1.1 --- /dev/null Wed Jul 12 20:41:55 2006 +++ slashjp/plugins/ResKey/flow.txt Wed Jul 12 20:41:55 2006 @@ -0,0 +1,75 @@ +This tersely describes the flow of methods in Slash::ResKey::Key. + +reskey = getObject + +rkey = reskey -> key(RESOURCE_NAME, { reskey => RESKEY, debug => DEBUG }) + get rkey object + + rkey -> create() + rkey -> touch() + rkey -> use() + rkey -> createuse() + main API (generated by _createActionMethod) + + -> fakeUse() + -> getUpdateClauses() + generate SET hashref and WHERE clause for sqlUpdate + + -> check() + -> createCheck() + -> touchCheck() + -> useCheck() + creates a check to execute (generated by _createCheckMethod) + returns method for a given class to execute, looking for + one of the following, in this order, in the given class: + + -> doCheckCreate() + -> doCheckCreateExtra() + -> doCheck() + -> doCheckExtra() + + -> dbCreate() + -> dbTouch() + -> dbUse() + actually perform the create/touch/use in the DB + -> update() + + rkey -> noop + rkey -> success + rkey -> failure + rkey -> death (generated by _createStatusAccessor) + get/set success conditions + + rkey -> errstr + return error string + + rkey -> error (generated by _createAccessor) + returns raw error data + + rkey -> reskey (generated by _createAccessor) + returns reskey string + + rkey -> get + returns the data from the DB row for that reskey + +other methods: + _init + resets stuff in the object + + _save_errors + _restore_errors + for the rare occasion we want to save the errors + before _init blows them away + + getWhereUserClause + set up how to identify the user in the where clause + + getSrcid + get the srcid for the current user + + getResources + get the resources from the DB table + + getChecks + get the checks from the DB table + Index: slashjp/plugins/ResKey/mysql_dump.sql diff -u /dev/null slashjp/plugins/ResKey/mysql_dump.sql:1.1 --- /dev/null Wed Jul 12 20:41:55 2006 +++ slashjp/plugins/ResKey/mysql_dump.sql Wed Jul 12 20:41:55 2006 @@ -0,0 +1,191 @@ +# +# $Id: mysql_dump.sql,v 1.1 2006/07/12 11:41:55 sugi Exp $ +# + +### NOTE: reserved reskey IDs: +# 1..99 main Slash +# 100..199 Ajax +# 200..999 future Slash use +# 1000+ are open for others to use + +### +# NOTE: AnonNoPost means if you are anonymous, you cannot post, if nopost is set +# for the AC uid. NoPostAnon checks the nopostanon check for the given srcid; +# NoPost checks the nopost check for the given srcid. + +### Possible reskey_vars (default is undef/false unless specified): +# adminbypass - 1/0 - If admin, bypass checks for duration, proxy, ACL, and user +# +# user_is_admin - 1/0 - Requires user to be admin +# user_is_subscriber - 1/0 - Requires user to be subscriber +# user_seclev - \d+ - Minimum seclev to use resource +# user_karma - \d+ - Minimum karma to use resource +# +# acl - \s+ - If this ACL present, can use resource +# acl_no - \s+ - If this ACL present, can't use resource +# +# duration_max-failures - \d+ - how many failures per reskey +# duration_max-uses - \d+ - how many uses per timeframe +# duration_uses - \d+ - min duration (in seconds) between uses +# duration_creation-use - \d+ - min duration between (in seconds) creation and use + + +INSERT INTO vars VALUES ('reskey_srcid_masksize', 24, 'which srcid mask size to use for reskeys'); +INSERT INTO vars VALUES ('reskey_timeframe', 14400, 'Default timeframe base to use for max-uses (in seconds)'); + +INSERT INTO reskey_resources VALUES (1, 'comments'); +INSERT INTO reskey_resources VALUES (2, 'zoo'); +INSERT INTO reskey_resources VALUES (3, 'journal'); +INSERT INTO reskey_resources VALUES (4, 'journal-soap'); +INSERT INTO reskey_resources VALUES (5, 'pollbooth'); +INSERT INTO reskey_resources VALUES (6, 'submit'); +INSERT INTO reskey_resources VALUES (7, 'journal-soap-get'); +INSERT INTO reskey_resources VALUES (8, 'bookmark'); + + + + +##### comments +### checks +# all is for all checks for a given resource, which can be overridden with create/touch/use +INSERT INTO reskey_resource_checks VALUES (NULL, 1, 'all', 'Slash::ResKey::Checks::User', 101); +INSERT INTO reskey_resource_checks VALUES (NULL, 1, 'all', 'Slash::ResKey::Checks::ACL', 201); +INSERT INTO reskey_resource_checks VALUES (NULL, 1, 'all', 'Slash::ResKey::Checks::AL2::AnonNoPost', 301); +INSERT INTO reskey_resource_checks VALUES (NULL, 1, 'all', 'Slash::ResKey::Checks::AL2::NoPostAnon', 401); +INSERT INTO reskey_resource_checks VALUES (NULL, 1, 'all', 'Slash::ResKey::Checks::AL2::NoPost', 501); +INSERT INTO reskey_resource_checks VALUES (NULL, 1, 'all', 'Slash::ResKey::Checks::Duration', 601); +INSERT INTO reskey_resource_checks VALUES (NULL, 1, 'use', 'Slash::ResKey::Checks::ProxyScan', 1001); + +# dummy example of how to disable the Slash::ResKey::Checks::User check for "touch" +# (maybe, for example, because the check isn't needed) +#REPLACE INTO reskey_resource_checks VALUES (NULL, 1, 'touch', '', 101); + +### vars +INSERT INTO reskey_vars VALUES (1, 'adminbypass', 1, 'If admin, bypass checks for duration, proxy, and user'); +INSERT INTO reskey_vars VALUES (1, 'acl_no', 'reskey_no_comments', 'If this ACL present, can\'t use resource'); +INSERT INTO reskey_vars VALUES (1, 'user_seclev', 0, 'Minimum seclev to use resource'); +INSERT INTO reskey_vars VALUES (1, 'duration_max-uses', 30, 'how many uses per timeframe'); +INSERT INTO reskey_vars VALUES (1, 'duration_max-failures', 10, 'how many failures per reskey'); +INSERT INTO reskey_vars VALUES (1, 'duration_uses', 120, 'min duration (in seconds) between uses'); +INSERT INTO reskey_vars VALUES (1, 'duration_creation-use', 5, 'min duration between (in seconds) creation and use'); + + + + +##### zoo +### checks +INSERT INTO reskey_resource_checks VALUES (NULL, 2, 'all', 'Slash::ResKey::Checks::User', 101); +INSERT INTO reskey_resource_checks VALUES (NULL, 2, 'all', 'Slash::ResKey::Checks::ACL', 201); +INSERT INTO reskey_resource_checks VALUES (NULL, 2, 'all', 'Slash::ResKey::Checks::AL2::AnonNoPost', 301); +INSERT INTO reskey_resource_checks VALUES (NULL, 2, 'all', 'Slash::ResKey::Checks::AL2::NoPostAnon', 401); +INSERT INTO reskey_resource_checks VALUES (NULL, 2, 'all', 'Slash::ResKey::Checks::AL2::NoPost', 501); +INSERT INTO reskey_resource_checks VALUES (NULL, 2, 'all', 'Slash::ResKey::Checks::Duration', 601); + +### vars +INSERT INTO reskey_vars VALUES (2, 'adminbypass', 1, 'If admin, bypass checks for duration, proxy, and user'); +INSERT INTO reskey_vars VALUES (2, 'acl_no', 'reskey_no_zoo', 'If this ACL present, can\'t use resource'); +INSERT INTO reskey_vars VALUES (2, 'user_seclev', 1, 'Minimum seclev to use resource'); +INSERT INTO reskey_vars VALUES (2, 'duration_max-uses', 30, 'how many uses per timeframe'); +INSERT INTO reskey_vars VALUES (2, 'duration_max-failures', 4, 'how many failures per reskey'); +INSERT INTO reskey_vars VALUES (2, 'duration_uses', 2, 'min duration (in seconds) between uses'); +INSERT INTO reskey_vars VALUES (2, 'duration_creation-use', 2, 'min duration (in seconds) between creation and use'); + + + +##### journal +# note that journal and journal deletion share a reskey. this means if you try +# to delete a few dozen journal entries one at a time, you are screwed. but +# as you can select multiple ones from a list, that should not a problem. +### checks +INSERT INTO reskey_resource_checks VALUES (NULL, 3, 'all', 'Slash::ResKey::Checks::User', 101); +INSERT INTO reskey_resource_checks VALUES (NULL, 3, 'all', 'Slash::ResKey::Checks::ACL', 201); +INSERT INTO reskey_resource_checks VALUES (NULL, 3, 'all', 'Slash::ResKey::Checks::AL2::AnonNoPost', 301); +INSERT INTO reskey_resource_checks VALUES (NULL, 3, 'all', 'Slash::ResKey::Checks::AL2::NoPostAnon', 401); +INSERT INTO reskey_resource_checks VALUES (NULL, 3, 'all', 'Slash::ResKey::Checks::AL2::NoPost', 501); +INSERT INTO reskey_resource_checks VALUES (NULL, 3, 'all', 'Slash::ResKey::Checks::Duration', 601); + +### vars +INSERT INTO reskey_vars VALUES (3, 'adminbypass', 1, 'If admin, bypass checks for duration, proxy, and user'); +INSERT INTO reskey_vars VALUES (3, 'acl_no', 'reskey_no_journal', 'If this ACL present, can\'t use resource'); +INSERT INTO reskey_vars VALUES (3, 'user_seclev', 1, 'Minimum seclev to use resource'); +INSERT INTO reskey_vars VALUES (3, 'duration_max-uses', 30, 'how many uses per timeframe'); +INSERT INTO reskey_vars VALUES (3, 'duration_max-failures', 10, 'how many failures per reskey'); +INSERT INTO reskey_vars VALUES (3, 'duration_uses', 30, 'min duration (in seconds) between uses'); +INSERT INTO reskey_vars VALUES (3, 'duration_creation-use', 2, 'min duration (in seconds) between creation and use'); + + +##### journal-soap +### checks +INSERT INTO reskey_resource_checks VALUES (NULL, 4, 'all', 'Slash::ResKey::Checks::User', 101); +INSERT INTO reskey_resource_checks VALUES (NULL, 4, 'all', 'Slash::ResKey::Checks::ACL', 201); +INSERT INTO reskey_resource_checks VALUES (NULL, 4, 'all', 'Slash::ResKey::Checks::AL2::AnonNoPost', 301); +INSERT INTO reskey_resource_checks VALUES (NULL, 4, 'all', 'Slash::ResKey::Checks::AL2::NoPostAnon', 401); +INSERT INTO reskey_resource_checks VALUES (NULL, 4, 'all', 'Slash::ResKey::Checks::AL2::NoPost', 501); +INSERT INTO reskey_resource_checks VALUES (NULL, 4, 'all', 'Slash::ResKey::Checks::Duration', 601); + +### vars +INSERT INTO reskey_vars VALUES (4, 'adminbypass', 1, 'If admin, bypass checks for duration, proxy, and user'); +#INSERT INTO reskey_vars VALUES (4, 'acl', 'reskey_journal-soap', 'If this ACL present, can use resource'); +INSERT INTO reskey_vars VALUES (4, 'acl_no', 'reskey_no_journal', 'If this ACL present, can\'t use resource'); +#INSERT INTO reskey_vars VALUES (4, 'user_is_subscriber', 1, 'Require user to be subscriber'); +INSERT INTO reskey_vars VALUES (4, 'user_seclev', 1, 'Minimum seclev to use resource'); +INSERT INTO reskey_vars VALUES (4, 'duration_max-uses', 30, 'how many uses per timeframe'); +INSERT INTO reskey_vars VALUES (4, 'duration_max-failures', 10, 'how many failures per reskey'); +INSERT INTO reskey_vars VALUES (4, 'duration_uses', 30, 'min duration (in seconds) between uses'); + + +##### journal-soap-get +### checks +INSERT INTO reskey_resource_checks VALUES (NULL, 7, 'all', 'Slash::ResKey::Checks::User', 101); +INSERT INTO reskey_resource_checks VALUES (NULL, 7, 'all', 'Slash::ResKey::Checks::ACL', 201); +INSERT INTO reskey_resource_checks VALUES (NULL, 7, 'all', 'Slash::ResKey::Checks::Duration', 601); + +### vars +INSERT INTO reskey_vars VALUES (7, 'adminbypass', 1, 'If admin, bypass checks for duration, proxy, and user'); +#INSERT INTO reskey_vars VALUES (7, 'acl', 'reskey_journal-soap', 'If this ACL present, can use resource'); +INSERT INTO reskey_vars VALUES (7, 'acl_no', 'reskey_no_journal', 'If this ACL present, can\'t use resource'); +#INSERT INTO reskey_vars VALUES (7, 'user_is_subscriber', 1, 'Require user to be subscriber'); +INSERT INTO reskey_vars VALUES (7, 'duration_max-failures', 1, 'how many failures per reskey'); + + + +##### pollbooth +### checks +INSERT INTO reskey_resource_checks VALUES (NULL, 5, 'all', 'Slash::ResKey::Checks::User', 101); +INSERT INTO reskey_resource_checks VALUES (NULL, 5, 'use', 'Slash::ResKey::Checks::Post', 151); +INSERT INTO reskey_resource_checks VALUES (NULL, 5, 'all', 'Slash::ResKey::Checks::ACL', 201); +INSERT INTO reskey_resource_checks VALUES (NULL, 5, 'all', 'Slash::PollBooth::ResKey', 251); +INSERT INTO reskey_resource_checks VALUES (NULL, 5, 'all', 'Slash::ResKey::Checks::AL2::AnonNoPost', 301); +INSERT INTO reskey_resource_checks VALUES (NULL, 5, 'all', 'Slash::ResKey::Checks::AL2::NoPostAnon', 401); +INSERT INTO reskey_resource_checks VALUES (NULL, 5, 'all', 'Slash::ResKey::Checks::AL2::NoPost', 501); +INSERT INTO reskey_resource_checks VALUES (NULL, 5, 'all', 'Slash::ResKey::Checks::Duration', 601); + +### vars +INSERT INTO reskey_vars VALUES (5, 'adminbypass', 1, 'If admin, bypass checks for duration, proxy, and user'); +INSERT INTO reskey_vars VALUES (5, 'acl_no', 'reskey_no_pollbooth', 'If this ACL present, can\'t use resource'); +INSERT INTO reskey_vars VALUES (5, 'duration_max-uses', 10, 'how many uses per timeframe'); +INSERT INTO reskey_vars VALUES (5, 'duration_max-failures', 3, 'how many failures per reskey'); +INSERT INTO reskey_vars VALUES (5, 'duration_uses', 10, 'min duration (in seconds) between uses'); +INSERT INTO reskey_vars VALUES (5, 'duration_creation-use', 2, 'min duration (in seconds) between creation and use'); + + + +##### submit +### checks +INSERT INTO reskey_resource_checks VALUES (NULL, 6, 'all', 'Slash::ResKey::Checks::User', 101); +INSERT INTO reskey_resource_checks VALUES (NULL, 6, 'use', 'Slash::ResKey::Checks::Post', 151); +INSERT INTO reskey_resource_checks VALUES (NULL, 6, 'all', 'Slash::ResKey::Checks::ACL', 201); +INSERT INTO reskey_resource_checks VALUES (NULL, 6, 'all', 'Slash::ResKey::Checks::AL2::AnonNoPost', 301); +INSERT INTO reskey_resource_checks VALUES (NULL, 6, 'all', 'Slash::ResKey::Checks::AL2::NoPostAnon', 401); +INSERT INTO reskey_resource_checks VALUES (NULL, 6, 'all', 'Slash::ResKey::Checks::AL2::NoPost', 501); +INSERT INTO reskey_resource_checks VALUES (NULL, 6, 'all', 'Slash::ResKey::Checks::AL2::NoSubmit', 551); +INSERT INTO reskey_resource_checks VALUES (NULL, 6, 'all', 'Slash::ResKey::Checks::Duration', 601); + +### vars +INSERT INTO reskey_vars VALUES (6, 'adminbypass', 1, 'If admin, bypass checks for duration, proxy, and user'); +INSERT INTO reskey_vars VALUES (6, 'acl_no', 'reskey_no_submit', 'If this ACL present, can\'t use resource'); +INSERT INTO reskey_vars VALUES (6, 'duration_max-uses', 20, 'how many uses per timeframe'); +INSERT INTO reskey_vars VALUES (6, 'duration_max-failures', 10, 'how many failures per reskey'); +INSERT INTO reskey_vars VALUES (6, 'duration_uses', 300, 'min duration (in seconds) between uses'); +INSERT INTO reskey_vars VALUES (6, 'duration_creation-use', 20, 'min duration (in seconds) between creation and use'); + Index: slashjp/plugins/ResKey/mysql_schema.sql diff -u /dev/null slashjp/plugins/ResKey/mysql_schema.sql:1.1 --- /dev/null Wed Jul 12 20:41:55 2006 +++ slashjp/plugins/ResKey/mysql_schema.sql Wed Jul 12 20:41:55 2006 @@ -0,0 +1,65 @@ +# +# $Id: mysql_schema.sql,v 1.1 2006/07/12 11:41:55 sugi Exp $ +# + +DROP TABLE IF EXISTS reskeys; +CREATE TABLE reskeys ( + rkid INT NOT NULL AUTO_INCREMENT, + reskey CHAR(20) DEFAULT '' NOT NULL, # unique resource key string + rkrid SMALLINT UNSIGNED NOT NULL, # points to reskey_resources.rkrid + + uid MEDIUMINT UNSIGNED DEFAULT 0 NOT NULL, + srcid_ip BIGINT UNSIGNED DEFAULT 0 NOT NULL, + + failures TINYINT DEFAULT 0 NOT NULL, # number of failures of this key + touches TINYINT DEFAULT 0 NOT NULL, # number of touches (not including failures, or successful uses) of this key + is_alive ENUM('yes', 'no') DEFAULT 'yes' NOT NULL, + + create_ts DATETIME DEFAULT '0000-00-00 00:00:00' NOT NULL, # on create + last_ts DATETIME DEFAULT '0000-00-00 00:00:00' NOT NULL, # last use + submit_ts DATETIME DEFAULT NULL, # on success + + PRIMARY KEY (rkid), + UNIQUE reskey (reskey), + KEY rkrid (rkrid), + KEY uid (uid), + KEY srcid_ip (srcid_ip), + KEY create_ts (create_ts), + KEY last_ts (last_ts), + KEY submit_ts (submit_ts) +) TYPE=InnoDB; + +DROP TABLE IF EXISTS reskey_failures; +CREATE TABLE reskey_failures ( + rkid INT NOT NULL, + failure VARCHAR(255) DEFAULT '' NOT NULL, + PRIMARY KEY (rkid) +) TYPE=InnoDB; + +DROP TABLE IF EXISTS reskey_resources; +CREATE TABLE reskey_resources ( + rkrid SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, + name VARCHAR(64), + PRIMARY KEY (rkrid) +) TYPE=InnoDB; + +DROP TABLE IF EXISTS reskey_resource_checks; +CREATE TABLE reskey_resource_checks ( + rkrcid SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, + rkrid SMALLINT UNSIGNED NOT NULL, + type ENUM('create', 'touch', 'use', 'all') NOT NULL, + class VARCHAR(255), + ordernum SMALLINT UNSIGNED DEFAULT 0, + PRIMARY KEY (rkrcid), + UNIQUE rkrid_name (rkrid, type, class) +) TYPE=InnoDB; + +DROP TABLE IF EXISTS reskey_vars; +CREATE TABLE reskey_vars ( + rkrid SMALLINT UNSIGNED NOT NULL, + name VARCHAR(48) DEFAULT '' NOT NULL, + value TEXT, + description VARCHAR(255), + UNIQUE name_rkrid (name, rkrid) +) TYPE=InnoDB; +