Skip to content

Commit

Permalink
BUDA job submission: add access control
Browse files Browse the repository at this point in the history
and unify access control web and remote job submission
  • Loading branch information
davidpanderson committed Nov 26, 2024
1 parent 40f8fd8 commit 413e168
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 64 deletions.
60 changes: 41 additions & 19 deletions html/inc/submit_util.inc
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,41 @@ function job_file_name($md5) {
return "jf_$md5";
}

// does user have submit permissions?
// can user upload files?
//
function submit_permissions($user) {
return BoincUserSubmit::lookup_userid($user->id);
function has_file_access($user) {
$us = BoincUserSubmit::lookup_userid($user->id);
if (!$us) return false;
return true;
}

// does user have submit permissions for given app?
// can user submit to given app?
//
function submit_permissions_app($user, $app) {
return BoincUserSubmitApp::lookup("user_id=$user->id and app_id=$app->id");
function has_submit_access($user, $app_id) {
$us = BoincUserSubmit::lookup_userid($user->id);
if (!$us) return false;
if ($us->submit_all) return true;
$usa = BoincUserSubmitApp::lookup("user_id=$user->id and app_id=$app_id");
if (!$usa) return false;
return true;
}

// can user administer given app (or all apps if zero)?
//
function has_admin_access($user, $app_id) {
$us = BoincUserSubmit::lookup_userid($user->id);
if (!$us) return false;
if ($us->admin_all) return true;
$usa = BoincUserSubmitApp::lookup("user_id=$user->id and app_id=$app_id");
if (!$usa) return false;
return $usa->manage;
}

// check whether user has permissions for a remote job submission
// or job file request.
// $r is a request message that includes an 'authenticator' field
// $app is the app being submitted to (or null if file op)
// returns [user, UserSubmit], or give XML error
// returns user, or give XML error and quit
//
function check_remote_submit_permissions($r, $app) {
$auth = (string)$r->authenticator;
Expand All @@ -84,21 +102,25 @@ function check_remote_submit_permissions($r, $app) {
log_write("bad authenticator");
xml_error(-1, "bad authenticator");
}
$user_submit = submit_permissions($user);
if (!$user_submit) {
log_write("no submit access");
xml_error(-1, "no submit access");
}
if ($app && !$user_submit->submit_all) {
$usa = submit_permissions_app($user, $app);
if (!$usa) {
log_write("no app submit access");
xml_error(-1, "no app submit access");

// check access
//
if ($app) {
if (!has_submit_access($user, $app->id)) {
log_write("no submit access");
xml_error(-1, "no submit access");
}
} else {
if (!has_file_access($user)) {
log_write("no file access");
xml_error(-1, "no file access");
}
}
return array($user, $user_submit);
return $user;
}

// remove all of user's permissions
//
function delete_remote_submit_user($user) {
BoincUserSubmit::delete_user($user->id);
BoincUserSubmitApp::delete_user($user->id);
Expand Down Expand Up @@ -165,7 +187,7 @@ function wus_nsent($wus) {
}

// get the physical names of a result's output files.
/
//
function get_outfile_phys_names($result) {
$names = [];
$xml = "<a>".$result->xml_doc_out."</a>";
Expand Down
15 changes: 13 additions & 2 deletions html/user/buda.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ function show_app($dir) {
}
end_table();
echo "<p>";
show_button("buda.php?action=variant_form&app=$dir", 'Add variant');
show_button_small("buda.php?action=variant_form&app=$dir", 'Add variant');
echo "<p>";
show_button_small(
"buda.php?action=app_delete&app=$dir", "Delete science app '$dir'"
Expand Down Expand Up @@ -289,7 +289,8 @@ function app_delete() {

function app_form() {
page_head('Create Docker app');
form_start();
form_start('buda.php');
form_input_hidden('action', 'app_action');
form_input_text('Name', 'name');
form_submit('OK');
form_end();
Expand Down Expand Up @@ -321,7 +322,17 @@ function view_file() {
echo "</pre>\n";
}

// check access.
// Anyone with submit access to BUDA can add/delete apps and variants.
// Might want to refine this at some point

$user = get_logged_in_user();
$buda_app = BoincApp::lookup("name='buda'");
if (!$buda_app) error_page('no buda app');
if (!has_submit_access($user, $buda_app->id)) {
error_page('no access');
}

$action = get_str('action', true);
switch ($action) {
case 'app_form':
Expand Down
24 changes: 14 additions & 10 deletions html/user/buda_submit.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,14 @@ function parse_batch_dir($batch_dir, $variant_desc) {
return $batch_desc;
}

function create_batch($user, $njobs, $boinc_app, $app, $variant) {
function create_batch($user, $njobs, $app, $variant) {
global $buda_app;
$now = time();
$batch_name = sprintf('buda_%d_%d', $user->id, $now);
$description = "$app ($variant)";
$batch_id = BoincBatch::insert(sprintf(
"(user_id, create_time, logical_start_time, logical_end_time, est_completion_time, njobs, fraction_done, nerror_jobs, state, completion_time, credit_estimate, credit_canonical, credit_total, name, app_id, project_state, description, expire_time) values (%d, %d, 0, 0, 0, %d, 0, 0, %d, 0, 0, 0, 0, '%s', %d, 0, '%s', 0)",
$user->id, $now, $njobs, BATCH_STATE_INIT, $batch_name, $boinc_app->id,
$user->id, $now, $njobs, BATCH_STATE_INIT, $batch_name, $buda_app->id,
$description
));
return BoincBatch::lookup_id($batch_id);
Expand Down Expand Up @@ -178,8 +179,10 @@ function stage_input_files($batch_dir, $batch_desc, $batch_id) {
}

function create_jobs(
$variant_desc, $batch_desc, $batch_id, $boinc_app, $batch_dir_name
$variant_desc, $batch_desc, $batch_id, $batch_dir_name
) {
global $buda_app;

// get list of names of app files
//
$app_file_names = $variant_desc->dockerfile_phys;
Expand All @@ -203,7 +206,7 @@ function create_jobs(
}
$cmd = sprintf(
'cd ../..; bin/create_work --appname %s --batch %d --stdin --command_line "--dockerfile %s --verbose" --wu_template %s --result_template %s',
$boinc_app->name, $batch_id, $variant_desc->dockerfile,
$buda_app->name, $batch_id, $variant_desc->dockerfile,
"buda_batches/$batch_dir_name/template_in",
"buda_batches/$batch_dir_name/template_out"
);
Expand Down Expand Up @@ -298,10 +301,6 @@ function create_templates($variant_desc, $batch_dir) {
}

function handle_submit($user) {
$boinc_app = BoincApp::lookup("name='buda'");
if (!$boinc_app) {
error_page("No buda app found");
}
$app = get_str('app');
if (!is_valid_filename($app)) die('bad arg');
$variant = get_str('variant');
Expand All @@ -324,15 +323,15 @@ function handle_submit($user) {
create_templates($variant_desc, $batch_dir);

$batch = create_batch(
$user, count($batch_desc->jobs), $boinc_app, $app, $variant
$user, count($batch_desc->jobs), $app, $variant
);

// stage input files and record the physical names
//
stage_input_files($batch_dir, $batch_desc, $batch->id);

create_jobs(
$variant_desc, $batch_desc, $batch->id, $boinc_app, $batch_dir_name
$variant_desc, $batch_desc, $batch->id, $batch_dir_name
);

// mark batch as in progress
Expand All @@ -347,6 +346,11 @@ function handle_submit($user) {
}

$user = get_logged_in_user();
$buda_app = BoincApp::lookup("name='buda'");
if (!$buda_app) error_page('no buda app');
if (!has_submit_access($user, $buda_app->id)) {
error_page('no access');
}
$action = get_str('action', true);
if ($action == 'submit') {
handle_submit($user);
Expand Down
29 changes: 12 additions & 17 deletions html/user/submit.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ function show_all_link($batches, $state, $limit, $user, $app) {
}

function show_in_progress($batches, $limit, $user, $app) {
echo "<h3>Batches in progress</h3>\n";
$first = true;
$n = 0;
foreach ($batches as $batch) {
Expand All @@ -66,7 +67,6 @@ function show_in_progress($batches, $limit, $user, $app) {
$n++;
if ($first) {
$first = false;
echo "<h2>Batches in progress</h2>\n";
if ($limit) {
show_all_link($batches, BATCH_STATE_IN_PROGRESS, $limit, $user, $app);
}
Expand Down Expand Up @@ -95,7 +95,7 @@ function show_in_progress($batches, $limit, $user, $app) {
);
}
if ($first) {
echo "<p>No in-progress batches.\n";
echo "<p>None.\n";
} else {
end_table();
}
Expand Down Expand Up @@ -273,20 +273,11 @@ function handle_toggle_loc($user) {
handle_main($user);
}

function check_admin_access($user, $app_id) {
// show links for everything the user has admin access to
//
function handle_admin($user) {
$user_submit = BoincUserSubmit::lookup_userid($user->id);
if (!$user_submit) error_page("no access");
if ($app_id) {
if (!$user_submit->manage_all) {
$usa = BoincUserSubmitApp::lookup("user_id = $user->id and app_id=$app_id");
if (!$usa) error_page("no access");
}
} else {
if (!$user_submit->manage_all) error_page("no access");
}
}

function handle_admin() {
if (!$user_submit) error_page('no access');
page_head("Administer job submission");
if ($user_submit->manage_all) {
echo "<li>All applications<br>
Expand Down Expand Up @@ -326,9 +317,11 @@ function handle_admin() {

function handle_admin_app($user) {
$app_id = get_int("app_id");
check_admin_access($user, $app_id);
$app = BoincApp::lookup_id($app_id);
if (!$app) error_page("no such app");
if (!has_admin_access($user, $app_id)) {
error_page('no access');
}

page_head("Administer batches for $app->user_friendly_name");
$batches = BoincBatch::enum("app_id = $app_id order by id desc");
Expand Down Expand Up @@ -745,7 +738,9 @@ function handle_show_all($user) {
} else {
// admin looking at batches
//
check_admin_access($user, $appid);
if (!has_admin_access($user, $appid)) {
error_page('no access');
}
if ($appid) {
$app = BoincApp::lookup_id($appid);
if (!$app) error_page("no such app");
Expand Down
Loading

0 comments on commit 413e168

Please sign in to comment.