Skip to content

Commit

Permalink
Merge pull request #2504 from drshawnkwang/sak-useroptin-dbaddconsent
Browse files Browse the repository at this point in the history
User Opt-in consent
  • Loading branch information
TheAspens committed Oct 25, 2018
2 parents 6fae8ec + 01ed6b7 commit 4198df0
Show file tree
Hide file tree
Showing 31 changed files with 1,158 additions and 35 deletions.
33 changes: 33 additions & 0 deletions db/boinc_db.cpp
Expand Up @@ -112,6 +112,7 @@ void BADGE_USER::clear() {memset(this, 0, sizeof(*this));}
void BADGE_TEAM::clear() {memset(this, 0, sizeof(*this));}
void CREDIT_USER::clear() {memset(this, 0, sizeof(*this));}
void CREDIT_TEAM::clear() {memset(this, 0, sizeof(*this));}
void CONSENT_TYPE::clear() {memset(this, 0, sizeof(*this));}

DB_PLATFORM::DB_PLATFORM(DB_CONN* dc) :
DB_BASE("platform", dc?dc:&boinc_db){}
Expand Down Expand Up @@ -193,6 +194,8 @@ DB_CREDIT_USER::DB_CREDIT_USER(DB_CONN* dc) :
DB_BASE("credit_user", dc?dc:&boinc_db){}
DB_CREDIT_TEAM::DB_CREDIT_TEAM(DB_CONN* dc) :
DB_BASE("credit_team", dc?dc:&boinc_db){}
DB_CONSENT_TYPE::DB_CONSENT_TYPE(DB_CONN* dc) :
DB_BASE("consent_type", dc?dc:&boinc_db){}

DB_ID_TYPE DB_PLATFORM::get_id() {return id;}
DB_ID_TYPE DB_APP::get_id() {return id;}
Expand All @@ -212,6 +215,7 @@ DB_ID_TYPE DB_FILE::get_id() {return id;}
DB_ID_TYPE DB_FILESET::get_id() {return id;}
DB_ID_TYPE DB_SCHED_TRIGGER::get_id() {return id;}
DB_ID_TYPE DB_VDA_FILE::get_id() {return id;}
DB_ID_TYPE DB_CONSENT_TYPE::get_id() {return id;}

void DB_PLATFORM::db_print(char* buf){
sprintf(buf,
Expand Down Expand Up @@ -2865,4 +2869,33 @@ void DB_CREDIT_TEAM::db_parse(MYSQL_ROW &r) {
credit_type = atoi(r[i++]);
}

void DB_CONSENT_TYPE::db_print(char *buf) {
sprintf(buf,
"id=%lu, "
"shortname='%s', "
"description='%s', "
"enabled=%d, "
"project_specific=%d, "
"privacypref=%d, ",
id,
shortname,
description,
enabled,
project_specific,
privacypref
);
}

void DB_CONSENT_TYPE::db_parse(MYSQL_ROW &r) {
int i=0;
clear();
id = atol(r[i++]);
strcpy2(shortname, r[i++]);
strcpy2(description, r[i++]);
enabled = atoi(r[i++]);
project_specific = atoi(r[i++]);
privacypref = atoi(r[i++]);
}


const char *BOINC_RCSID_ac374386c8 = "$Id$";
8 changes: 8 additions & 0 deletions db/boinc_db.h
Expand Up @@ -568,4 +568,12 @@ struct DB_CREDIT_TEAM : public DB_BASE, public CREDIT_TEAM {
void db_parse(MYSQL_ROW&);
};

struct DB_CONSENT_TYPE : public DB_BASE, public CONSENT_TYPE {
DB_CONSENT_TYPE(DB_CONN* p=0);
DB_ID_TYPE get_id();
void db_print(char *);
void db_parse(MYSQL_ROW &row);
};


#endif
10 changes: 10 additions & 0 deletions db/boinc_db_types.h
Expand Up @@ -849,4 +849,14 @@ struct CREDIT_TEAM {
void clear();
};

struct CONSENT_TYPE {
DB_ID_TYPE id;
char shortname[256];
char description[256];
int enabled;
int project_specific;
int privacypref;
void clear();
};

#endif
18 changes: 18 additions & 0 deletions db/constraints.sql
Expand Up @@ -181,3 +181,21 @@ alter table post_ratings
alter table sent_email
add index sent_email_userid(userid);
-- for delete account

alter table private_messages
add index userid(userid);

alter table consent
add index userid_ctid_timestamp(userid, consent_type_id, consent_time),
add index consent_timestamp(consent_time),
add index flag_ctid(consent_flag, consent_type_id);

alter table consent
add foreign key(consent_type_id)
references consent_type(id)
on update cascade
on delete restrict;
-- explicit delete restrict on this foreign key

alter table consent_type
add index consent_name(shortname);
9 changes: 9 additions & 0 deletions db/content.sql
@@ -0,0 +1,9 @@
/*
This file contants inital content for any tables.
The table must be first defined in schema.sql before any content
is added!
*/
insert into consent_type (shortname, description, enabled, project_specific, privacypref)
values ('ENROLL', 'General terms-of-use for this BOINC project.', 0, 0, 0),
('STATSEXPORT', 'Do you consent to exporting your data to BOINC statistics aggregation Web sites?', 0, 0, 1);
41 changes: 39 additions & 2 deletions db/schema.sql
Expand Up @@ -41,6 +41,8 @@
-- fields ending with id (but not _id) are treated specially
-- by the Python code (db_base.py)

-- Put initial content of any table in content.sql, and not in this file.

create table platform (
id integer not null auto_increment,
create_time integer not null,
Expand Down Expand Up @@ -625,8 +627,7 @@ create table private_messages (
opened tinyint not null default 0,
subject varchar(255) not null,
content text not null,
primary key(id),
key userid (userid)
primary key(id)
) engine=MyISAM;

create table credited_job (
Expand Down Expand Up @@ -804,3 +805,39 @@ create table host_deleted (
primary key (hostid)
) engine=InnoDB;

create table consent (
id integer not null auto_increment,
userid integer not null,
consent_type_id integer not null,
consent_time integer not null,
consent_flag tinyint not null,
consent_not_required tinyint not null,
source varchar(255) not null,
primary key (id)
) engine=InnoDB;

-- @todo - change 'protect' to 'project_specific'
create table consent_type (
id integer not null auto_increment,
shortname varchar(255) not null,
description varchar(255) not null,
enabled integer not null,
project_specific integer not null,
privacypref integer not null,
primary key (id)
) engine=InnoDB;

-- SQL View representing the latest consent state of users for all
-- consent_types. Used in sched/db_dump and Web site preferences to
-- determine if a user has consented to a particular consent type.
create view latest_consent as
SELECT userid,
consent_type_id,
consent_flag
FROM consent
WHERE NOT EXISTS
(SELECT *
FROM consent AS filter
WHERE consent.userid = filter.userid
AND consent.consent_type_id = filter.consent_type_id
AND filter.consent_time > consent.consent_time);
42 changes: 42 additions & 0 deletions html/inc/account.inc
Expand Up @@ -20,6 +20,8 @@
// - forms for create / login
// - function to make login token

include_once("../inc/consent.inc");

// If have recent token, return it.
// Else make login token, store in user record, return token
//
Expand Down Expand Up @@ -114,6 +116,23 @@ function create_account_form($teamid, $next_url) {
"postal_code"
);
}

// Add terms of use to Web form. User must agree by checking the checkbox.
list($checkct, $ctid) = check_consent_type(CONSENT_TYPE_ENROLL);
if ($checkct and check_termsofuse()) {
$terms_of_use = trim(file_get_contents(TERMSOFUSE_FILE));
if ($terms_of_use) {
panel(tra('Terms of Use'), function() use($terms_of_use) {
echo nl2br($terms_of_use);
}
);
$myitems = array(
array("agree_to_terms_of_use", "", false),
);
form_checkboxes(tra("Do you agree to the terms of use above?"), $myitems, 'tabindex="0"');
}
}

}

function login_form($next_url) {
Expand Down Expand Up @@ -141,4 +160,27 @@ function login_form($next_url) {
form_end();
}

function user_agreetermsofuse_form($next_url) {
form_start(secure_url_base()."/user_agreetermsofuse_action.php", "post");
form_input_hidden("next_url", $next_url);

$terms_of_use = trim(file_get_contents(TERMSOFUSE_FILE));
if ($terms_of_use) {
panel(tra('Terms of Use'), function() use($terms_of_use) {
echo nl2br($terms_of_use);
}
);
$myitems = array(
array("agree_to_terms_of_use", "", false),
);
form_checkboxes(tra("Do you agree to the terms of use above?"), $myitems, 'tabindex="0"');
}
else {
// error - no terms of use for user to agree to!
}

form_submit(tra("I agree"));
form_end();
}

?>
80 changes: 80 additions & 0 deletions html/inc/boinc_db.inc
Expand Up @@ -878,6 +878,86 @@ class BoincHostDeleted {

}

class BoincConsent {
static function lookup($clause) {
$db = BoincDb::get();
return $db->lookup('consent', 'BoincConsent', $clause);
}

static function enum($where_clause) {
$db = BoincDb::get();
return $db->enum('consent', 'BoincConsent', $where_clause);
}

static function insert ($clause) {
$db = BoincDb::get();
return $db->insert('consent', $clause);
}

static function update ($clause) {
$db = BoincDb::get();
return $db->update_aux('consent', $clause);
}

static function delete($clause) {
$db = BoincDb::get();
return $db->delete_aux('consent', $clause);
}

static function delete_for_user($user_id) {
$db = BoincDb::get();
$db->delete_aux('consent', "userid=$user_id");
return $db->affected_rows();
}

}

class BoincConsentType {
static function lookup($clause) {
$db = BoincDb::get();
return $db->lookup('consent_type', 'BoincConsentType', $clause);
}

static function enum($where_clause, $order_clause=null) {
$db = BoincDb::get();
return $db->enum('consent_type', 'BoincConsentType', $where_clause, $order_clause);
}

static function insert ($clause) {
$db = BoincDb::get();
return $db->insert('consent_type', $clause);
}

static function update ($clause) {
$db = BoincDb::get();
return $db->update_aux('consent_type', $clause);
}

function delete() {
$db = BoincDb::get();
return $db->delete($this, 'consent_type');
}

function delete_aux($clause) {
$db = BoincDb::get();
return $db->delete_aux('consent_type', $clause);
}

}

// Class to interface with SQL View latest_consent. Only read
// operations permitted.
class BoincLatestConsent {
static function lookup($clause) {
$db = BoincDb::get();
return $db->lookup('latest_consent', 'BoincLatestConsent', $clause);
}

static function enum($where_clause, $order_clause=null) {
$db = BoincDb::get();
return $db->enum('latest_consent', 'BoincLatestConsent', $where_clause, $order_clause);
}
}

// DEPRECATED: use BoincDb::escape_string where possible
//
Expand Down

0 comments on commit 4198df0

Please sign in to comment.