Skip to content

Commit

Permalink
session ids, audit notes, etags
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Duggan committed May 28, 2015
1 parent e4285b0 commit 275d56e
Show file tree
Hide file tree
Showing 18 changed files with 97 additions and 66 deletions.
3 changes: 3 additions & 0 deletions lib/Tuba.pm
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ sub startup {
my $c = shift;
$c->res->headers->header('Access-Control-Allow-Origin' => '*');
$c->res->headers->header('X-API-Version' => $Tuba::VERSION );
if (my $id = $c->session('id')) {
$c->res->headers->etag(qq["$id"]) if $c->req->method =~ /^(POST|PUT)$/;
}
} );
$app->hook(before_dispatch => sub {
# Remove path when behind a proxy (see Mojolicious::Guides::Cookbook).
Expand Down
6 changes: 3 additions & 3 deletions lib/Tuba/Activity.pm
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ sub normalize_form_parameter {
}
if ($obj) {
my $pub = $obj->get_publication(autocreate => 1);
$pub->save(audit_user => $c->user) unless $pub->id;
$pub->save(audit_user => $c->audit_user, audit_note => $c->audit_note) unless $pub->id;
return $pub->id;
}
return $value;
Expand Down Expand Up @@ -83,12 +83,12 @@ sub update_rel {
if (my $new = $c->param('new_publication')) {
my $obj = $c->str_to_obj($new);
my $pub = $obj->get_publication(autocreate => 1);
$pub->save(audit_user => $c->user) unless $pub->id;
$pub->save(audit_user => $c->audit_user, audit_note => $c->audit_note) unless $pub->id;
my $methodology = Methodology->new(
activity_identifier => $activity->identifier,
publication_id => $pub->id
);
$methodology->save(audit_user => $c->user)
$methodology->save(audit_user => $c->audit_user, audit_note => $c->audit_note)
or return $c->update_error($methodology->error);
}
for my $id ($c->param('delete_publication')) {
Expand Down
2 changes: 1 addition & 1 deletion lib/Tuba/Array.pm
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ sub update_rel {
if (my $new = $c->param('new_table')) {
my $img = $c->Tuba::Search::autocomplete_str_to_object($new);
$object->add_tables($img);
$object->save(audit_user => $c->user) or do {
$object->save(audit_user => $c->audit_user, audit_note => $c->audit_note) or do {
$c->flash(error => $object->error);
return $c->update_rel_form(@_);
};
Expand Down
10 changes: 8 additions & 2 deletions lib/Tuba/Auth.pm
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use JSON::XS;
use Mojo::JSON;
use Time::Duration qw/ago/;
use Tuba::Log;
use Tuba::Util qw/new_uuid/;
use Data::Dumper;

my $key_expiration = 60 * 60 * 24 * 30;
Expand Down Expand Up @@ -63,8 +64,10 @@ sub _validate_api_key {
}
my $verify = b(Mojo::JSON::encode_json([$user,$secret,$create_time]))->hmac_sha1_sum;
if ($verify eq $hash) {
logger->debug("Valid api key for $user, created ".ago(time - $create_time));
my $id = new_uuid();
logger->debug("Valid api key for $user, created ".ago(time - $create_time)."session id : $id");
$c->session(user => $user);
$c->session(id => $id);
return 1;
} else {
logger->warn("Invalid key for $user");
Expand Down Expand Up @@ -114,7 +117,7 @@ sub _google_secrets {
state $google_secrets;
return if $google_secrets && $google_secrets eq 'none';
return $google_secrets->{web} if $google_secrets;
my $secrets_file = $c->config->{auth}{google_secrets_file};
my $secrets_file = $c->config->{auth}{google_secrets_file} or return;
if ($secrets_file and !-e $secrets_file) {
$c->app->log->warn("could not open google_secrets_file $secrets_file");
$google_secrets = 'none';
Expand Down Expand Up @@ -176,6 +179,9 @@ sub _login_ok {
my $user = shift;
$c->app->log->info("Log in ok for $user");
$c->session(user => $user);
my $id = new_uuid();
$c->app->log->info("Session id: $id");
$c->session(id => $id);
my $dest = $c->param('destination') || $c->flash('destination') || 'index';
$dest =~ s/^http(s)?://;
return $c->redirect_to($dest);
Expand Down
8 changes: 4 additions & 4 deletions lib/Tuba/Book.pm
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,23 @@ sub update {
url => $book->url,
publication_year => $book->year
);
$report->save(audit_user => $c->user) or do {
$report->save(audit_user => $c->audit_user, audit_note => $c->audit_note) or do {
return $c->update_error($report->error);
};
my $pub = $book->get_publication;
if ($pub) {
my $report_pub = $report->get_publication(autocreate => 1);
$report_pub->save(audit_user => $c->user);
$report_pub->save(audit_user => $c->audit_user, audit_note => $c->audit_note);
my $refs = References->get_objects(query => [ child_publication_id => $pub->id ] );
for my $ref (@$refs) {
$ref->child_publication_id($report_pub->id);
my $attrs = $ref->attrs; # workaround : call inflate trigger explicitly
$ref->save(audit_user => $c->user) or return $c->update_error($ref->error);
$ref->save(audit_user => $c->audit_user, audit_note => $c->audit_note) or return $c->update_error($ref->error);
}
my $subs = Subpubrefs->get_objects(query => [ publication_id => $report_pub->id ]);
for my $sub (@$subs) {
$sub->publication_id($report_pub->id);
$sub->save(audit_user => $c->user) or return $c->update_error($sub->error);
$sub->save(audit_user => $c->audit_user, audit_note => $c->audit_note) or return $c->update_error($sub->error);
}
}
$book->delete;
Expand Down
49 changes: 30 additions & 19 deletions lib/Tuba/Controller.pm
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ sub create {
$obj{$col->name} = defined($got) && length($got) ? $got : undef;
}
}
my $audit_note = delete($obj{audit_note});
my $audit_note = $c->audit_note(delete($obj{audit_note}));
if (exists($obj{report_identifier}) && $c->stash('report_identifier')) {
$obj{report_identifier} = $c->stash('report_identifier');
}
Expand Down Expand Up @@ -644,7 +644,7 @@ sub update_prov {
$c->stash(object => $object);
$c->stash(meta => $object->meta);
my $pub = $object->get_publication(autocreate => 1);
$pub->save(changes_only => 1, audit_user => $c->user); # might be new.
$pub->save(changes_only => 1, audit_user => $c->user, audit_note => $c->audit_note); # might be new.
$c->stash(publication => $pub);
$c->stash->{template} = 'update_prov_form';

Expand All @@ -653,7 +653,7 @@ sub update_prov {
my $other_pub = Publication->new(id => $delete)->load(speculative => 1);
my $map = PublicationMap->new(child => $pub->id, parent => $delete, relationship => $rel);
$map->load(speculative => 1) or return $c->update_error("could not find relationship");
$map->delete(audit_user => $c->user) or return $c->update_error($map->error);
$map->delete(audit_user => $c->user, audit_note => $c->audit_note) or return $c->update_error($map->error);
$c->stash(info => "Deleted $rel ".($other_pub ? $other_pub->stringify : ""));
return $c->render;
}
Expand All @@ -677,7 +677,7 @@ sub update_prov {
if (my $parent_uri = $json->{parent_uri}) {
my $parent = $c->uri_to_obj($parent_uri) or return $c->update_error("Couldn't find $parent_uri");
$parent_pub = $parent->get_publication(autocreate => 1) or return $c->update_error("$parent_uri is not a publication");
$parent_pub->save(audit_user => $c->user) unless $parent_pub->id;
$parent_pub->save(audit_user => $c->user, audit_note => $c->audit_note) unless $parent_pub->id;
$rel = $json->{parent_rel} or return $c->update_error("Missing parent_rel");
$note = $json->{note};
$activity_identifier = $json->{activity};
Expand All @@ -686,7 +686,7 @@ sub update_prov {
my $parent_str = $c->param('parent') or return $c->render;
my $parent = $c->_text_to_object($parent_str) or return $c->render(error => 'cannot parse publication');
$parent_pub = $parent->get_publication(autocreate => 1);
$parent_pub->save(changes_only => 1, audit_user => $c->user) or return $c->render(error => $pub->error);
$parent_pub->save(changes_only => 1, audit_user => $c->user, audit_note => $c->audit_note) or return $c->render(error => $pub->error);
$rel = $c->param('parent_rel') or return $c->render(error => "Please select a relationship");
$note = $c->param('note');
$activity_identifier = $c->param('activity');
Expand All @@ -713,7 +713,7 @@ sub update_prov {
activity_identifier => $activity_identifier,
);
$map->load(speculative => 1);
$map->save(audit_user => $c->user) or return $c->update_error($map->error);
$map->save(audit_user => $c->user, audit_note => $c->audit_note) or return $c->update_error($map->error);
$c->stash(info => "Saved $rel : ".$parent_pub->stringify);
return $c->redirect_without_error('update_prov_form');
}
Expand Down Expand Up @@ -785,7 +785,7 @@ sub update_files {
my $pub = $object->get_publication(autocreate => 1) or
return $c->update_error( "Sorry, file uploads have only been implemented for publications.");
unless ($pub->id) {
$pub->save(audit_user => $c->user)
$pub->save(audit_user => $c->user, audit_note => $c->audit_note)
or return $c->update_error($pub->error);
}

Expand Down Expand Up @@ -832,12 +832,12 @@ sub update_files {
$new->port($remote_url->port) if $remote_url->port;
$new_file->location($new->to_string);
$new_file->file($remote_url->path);
$new_file->save(audit_user => $c->user);
$new_file->save(audit_user => $c->user, audit_note => $c->audit_user);
logger->info("saving remote asset ".$remote_url);
}
if (my $landing_page = ($json->{landing_page} || $c->param('landing_page')) ) {
$new_file->landing_page($landing_page);
$new_file->save(audit_user => $c->user);
$new_file->save(audit_user => $c->user, audit_note => $c->audit_note);
}
}

Expand Down Expand Up @@ -874,7 +874,7 @@ sub update_files {
}
if ($existing_file) {
my $entry = PublicationFileMap->new(publication => $pub->id, file => $existing_file->identifier);
$entry->save(audit_user => $c->user) or return $c->update_error($entry->error);
$entry->save(audit_user => $c->user, audit_note => $c->audit_note) or return $c->update_error($entry->error);
$c->stash(message => 'Saved changes.');
return $c->redirect_without_error('update_files_form');
}
Expand Down Expand Up @@ -911,7 +911,7 @@ sub update_contributors {
my $obj = $c->_this_object or return $c->reply->not_found;
$c->stash(tab => 'update_contributors_form');
my $pub = $obj->get_publication(autocreate => 1);
$pub->save(audit_user => $c->user) unless $pub->id;
$pub->save(audit_user => $c->user, audit_note => $c->audit_note) unless $pub->id;

my $json = $c->req->json || {};

Expand All @@ -933,7 +933,7 @@ sub update_contributors {
$map->load(speculative => 1) or return $c->update_error("bad pub/contributor map ids");
next if $map->sort_key && $map->sort_key == $sort_key;
$map->sort_key($sort_key);
$map->save(audit_user => $c->user) or return $c->update_error("could not save ".$map->error);
$map->save(audit_user => $c->user, audit_note => $c->audit_note) or return $c->update_error("could not save ".$map->error);
$c->flash(info => "Saved changes");
}
}
Expand Down Expand Up @@ -974,18 +974,18 @@ sub update_contributors {
logger->debug("Found contributor person ".($person // 'undef').' org '.($organization) // 'undef');
logger->debug("json : ".Dumper($json));
} else {
$contributor->save(audit_user => $c->user)
$contributor->save(audit_user => $c->user, audit_note => $c->audit_note)
or return $c->update_error($contributor->error);
};

$pub->save(audit_user => $c->user) or return $c->update_error($contributor->error);
$pub->save(audit_user => $c->user, audit_note => $c->audit_note) or return $c->update_error($contributor->error);
my $map = Tuba::DB::Object::PublicationContributorMap->new(
publication_id => $pub->id,
contributor_id => $contributor->id
);
$map->load(speculative => 1);
$map->reference_identifier($reference_identifier);
$map->save(audit_user => $c->user) or return $c->update_error($map->error);
$map->save(audit_user => $c->user, audit_note => $c->audit_note) or return $c->update_error($map->error);
$c->flash(info => "Saved changes.");
return $c->redirect_without_error('update_contributors_form');
}
Expand All @@ -1000,7 +1000,7 @@ sub _update_pub_many {
my $pwhat = $dwhat.'s';
my $mwhat = "Tuba::DB::Object::Publication${what}Map";

$pub->save(audit_user => $c->user) unless $pub->id;
$pub->save(audit_user => $c->user, audit_note => $c->audit_note) unless $pub->id;
if (my $json = $c->req->json) {
my $delete_extra = delete $json->{_delete_extra};
$json = [ $json ] if ref($json) eq 'HASH';
Expand All @@ -1014,7 +1014,7 @@ sub _update_pub_many {
$pub->$method($kw);
delete $to_delete{$kw->identifier};
}
$pub->save(audit_user => $c->user);
$pub->save(audit_user => $c->user, audit_note => $c->audit_note);
if ($delete_extra) {
for my $extra (keys %to_delete) {
$mwhat->new(
Expand Down Expand Up @@ -1060,7 +1060,7 @@ sub update_rel {
my $next = $object->uri($c,{tab => 'update_rel_form'});

my $pub = $object->get_publication(autocreate => 1);
$pub->save(audit_user => $c->user) unless $pub->id;
$pub->save(audit_user => $c->user, audit_note => $c->audit_note) unless $pub->id;

# Update generic many-many relationships for all publication types.
for my $what (qw/GcmdKeyword Region/) {
Expand All @@ -1072,7 +1072,7 @@ sub update_rel {
my $kwd = $cwhat->new_from_autocomplete($new);
my $add_method = "add_${dwhat}s";
$pub->$add_method($kwd);
$pub->save(audit_user => $c->user) or do {
$pub->save(audit_user => $c->user, audit_note => $c->audit_note) or do {
$c->flash(error => $object->error);
return $c->redirect_to($next);
};
Expand Down Expand Up @@ -1200,6 +1200,7 @@ sub update {
my $audit_note = $c->stash('audit_note');
$audit_note ||= (delete $json->{audit_note}) if $json;
$audit_note ||= $c->param('audit_note');
$audit_note = $c->audit_note($audit_note);
for my $col ($object->meta->columns) {
my $param = $json ? $json->{$col->name} : $c->req->param($col->name);
$param = $computed->{$col->name} if exists($computed->{$col->name});
Expand Down Expand Up @@ -1440,5 +1441,15 @@ sub redirect_without_error {
);
}

sub audit_note {
my $c = shift;
my $custom = shift;
my $id = $c->session('id') or die "no session id";
return join ':', $c->session('id'), ($custom || ());
}

sub audit_user {
return shift->user;
}

1;
27 changes: 19 additions & 8 deletions lib/Tuba/DB/Object.pm
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,8 @@ sub update_primary_key {
# %changes should just be source_column -> new_value.
my $table = $object->meta->table;
my $db = $object->db;
my $dbh = $db->dbh or die $db->error;
$db->do_transaction( sub {
$db->dbh->do("set local audit.username = ?",{},$audit_user);
$db->dbh->do("set local audit.note = ?",{},$audit_note) if $audit_note;
my %non_pk_changes = %changes;
my %pk_changes;
for (keys %pk) {
Expand All @@ -114,9 +113,11 @@ sub update_primary_key {
for (keys %non_pk_changes) {
$object->$_($non_pk_changes{$_});
}
$dbh->do("set local audit.username = ?",{},$audit_user);
$dbh->do("set local audit.note = ?",{},$audit_note) if $audit_note;
$object->save(audit_user => $audit_user, audit_note => $audit_note);

my $dbis = DBIx::Simple->new($db->dbh);
my $dbis = DBIx::Simple->new($dbh);
$dbis->update(qq["$table"], \%pk_changes, \%pk) or die $dbis->error;
} ) or do {
$object->error($db->error) unless $object->error;
Expand All @@ -143,6 +144,7 @@ sub _am_recursing { # am I recursing?
sub save {
my $self = shift;
my %args = @_;
Carp::confess("weird args") if @_ % 2;
my $status;
# This function will be called several times during a nested save (e.g. $figure->add_image(..) ).
# But %args are not propogated. So, store $audit_info in a package var which we use
Expand All @@ -158,11 +160,20 @@ sub save {
$_audit_user = $audit_user;
$_audit_note = $audit_note;
$self->meta->error_mode('fatal');
$status = $self->db->do_transaction( sub {
$self->db->dbh->do("set local audit.username = ?",{},$audit_user);
$self->db->dbh->do("set local audit.note = ?",{},$audit_note) if $audit_note;
$self->SUPER::save(%args);
} );
my $dbh = $self->db->dbh;
my $state = $dbh->ping;
return 0 if $state==4; # in failed transaction
if ($state==3) { # already in a transaction
$dbh->do("set local audit.username = ?",{},$audit_user);
$dbh->do("set local audit.note = ?",{},$audit_note) if $audit_note;
$status = $self->SUPER::save(%args);
} else { # not in a transaction
$status = $self->db->do_transaction( sub {
$dbh->do("set local audit.username = ?",{},$audit_user);
$dbh->do("set local audit.note = ?",{},$audit_note) if $audit_note;
$status = $self->SUPER::save(%args);
});
}
unless ($status) {
logger->warn("save failed, obj error : ".($self->error || 'none'));
logger->warn("save failed, db error : ".($self->db->error || 'none'));
Expand Down
2 changes: 1 addition & 1 deletion lib/Tuba/Dataset.pm
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ sub update_rel {
$add->{dataset_identifier} = $dataset->identifier;
my $obj = InstrumentMeasurement->new( %$add );
$obj->load(speculative => 1);
$obj->save(audit_user => $c->user) or return $c->update_error($obj->error);
$obj->save(audit_user => $c->audit_user, audit_note => $c->audit_note) or return $c->update_error($obj->error);
} else {
warn "no json";
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Tuba/Exterm.pm
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ sub create {
# NB: forms are handled through lexicon/rel
return $c->update_error("missing JSON to add exterm");
}
$term->save(audit_user => $c->user) or return $c->update_error($term->error);
$term->save(audit_user => $c->audit_user, audit_note => $c->audit_note) or return $c->update_error($term->error);
$c->stash(_this_object => $term);
return $c->redirect_without_error('create_form');
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Tuba/Figure.pm
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,13 @@ sub update_rel {
if (my $new = $c->param('new_image')) {
my $img = $c->Tuba::Search::autocomplete_str_to_object($new);
$object->add_images($img);
$object->save(audit_user => $c->user) or return $c->update_error($object->error);
$object->save(audit_user => $c->audit_user, audit_note => $c->audit_note) or return $c->update_error($object->error);
}
if (my $new = $json->{add_image_identifier}) {
my $img = Image->new(identifier => $new)->load(speculative => 1)
or return $c->update_error("Image $new not found");
$object->add_images($img);
$object->save(audit_user => $c->user) or return $c->update_error($object->error);
$object->save(audit_user => $c->audit_user, audit_note => $c->audit_note) or return $c->update_error($object->error);
}

my $report_identifier = $c->stash('report_identifier');
Expand Down
2 changes: 1 addition & 1 deletion lib/Tuba/Image.pm
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ sub update_rel {
if (my $new = $c->param('new_figure')) {
my $img = $c->Tuba::Search::autocomplete_str_to_object($new);
$object->add_figures($img);
$object->save(audit_user => $c->user) or do {
$object->save(audit_user => $c->audit_user, audit_note => $c->audit_note) or do {
$c->flash(error => $object->error);
return $c->update_rel_form(@_);
};
Expand Down
Loading

0 comments on commit 275d56e

Please sign in to comment.