diff --git a/admin/common.inc.php b/admin/common.inc.php deleted file mode 100644 index 06ac97e..0000000 --- a/admin/common.inc.php +++ /dev/null @@ -1,7 +0,0 @@ -smarty_assign('category', DataUtilities::titleCase(basename(__DIR__))); diff --git a/admin/consumers-control-panel.php b/admin/consumers-control-panel.php deleted file mode 100644 index 826e84c..0000000 --- a/admin/consumers-control-panel.php +++ /dev/null @@ -1,79 +0,0 @@ -getMySQL()), - true // wicked confusing _not_ to autoenable - ); - - /* pre-fill secret if not editing an existing consumer */ - if (empty($key)) { - $consumer->secret = LTI_Data_Connector::getRandomString(32); - } - - return $consumer; -} - -/* load requested consumer (or create new if none requested) */ -$consumer = createConsumer($toolbox, $key); - -/* what are we asked to do with this consumer? */ -switch ($action) { - case 'update': - case 'insert': { - $consumer->name = $name; - $consumer->secret = $secret; - $consumer->enabled = $enabled; - if (!$consumer->save()) { - $toolbox->smarty_addMessage( - 'Error saving consumer', - 'There was an error attempting to save your new or updated consumer information to the database.', - NotificationMessage::ERROR - ); - } - break; - } - case 'delete': { - $consumer->delete(); - break; - } - case 'select': { - $toolbox->smarty_assign('key', $key); - break; - } -} - -/* - * if action was anything other than 'select', create a new empty consumer to - * fill the form with - */ -if ($action && $action !== 'select') { - $consumer = createConsumer($toolbox); -} - -/* display a list of consumers */ -$consumers = $toolbox->lti_getConsumers(); -$toolbox->smarty_assign([ - 'consumers' => $consumers, - 'consumer' => $consumer, - 'formAction' => $_SERVER['PHP_SELF'], - 'appUrl' => $toolbox->config('APP_URL') -]); -$toolbox->smarty_display(basename(__FILE__, '.php') . '.tpl'); diff --git a/admin/index.php b/admin/index.php deleted file mode 100644 index 3726f45..0000000 --- a/admin/index.php +++ /dev/null @@ -1,6 +0,0 @@ -smarty_assign('formAction', $_SERVER['PHP_SELF']); - $toolbox->smarty_display('oauth.tpl'); - exit; -} elseif (empty($_SESSION[CANVAS_INSTANCE_URL]) && !empty($_REQUEST['url'])) { - $_SESSION[CANVAS_INSTANCE_URL] = $_REQUEST['url']; -} - -$canvas = $toolbox->config('TOOL_CANVAS_API'); -$provider = new CanvasLMS([ - 'clientId' => $canvas['key'], - 'clientSecret' => $canvas['secret'], - 'purpose' => $toolbox->config('TOOL_NAME'), - 'redirectUri' => DataUtilities::URLfromPath(__FILE__), - 'canvasInstanceUrl' => $_SESSION[CANVAS_INSTANCE_URL] -]); - -/* if we don't already have an authorization code, let's get one! */ -if (!isset($_GET['code'])) { - $authorizationUrl = $provider->getAuthorizationUrl(); - $_SESSION[OAUTH_STATE] = $provider->getState(); - header("Location: $authorizationUrl"); - exit; - -/* check that the passed state matches the stored state to mitigate cross-site request forgery attacks */ -} elseif (empty($_GET['state']) || $_GET['state'] !== $_SESSION[OAUTH_STATE]) { - unset($_SESSION[OAUTH_STATE]); - exit('Invalid state'); - -} else { - /* acquire and save our token (using our existing code) */ - $canvas = $toolbox->config('TOOL_CANVAS_API'); - $canvas['url'] = $_SESSION[CANVAS_INSTANCE_URL]; - $canvas['token'] = $provider->getAccessToken('authorization_code', ['code' => $_GET['code']])->getToken(); - - /* pass back the newly-acquired token in session data */ - $_SESSION['TOOL_CANVAS_API'] = $canvas; - - /* return to what we were doing before we had to authenticate */ - header("Location: {$_SESSION['oauth-return']}"); - unset($_SESSION[OAUTH_STATE]); - unset($_SESSION['oauth-return']); - exit; -} diff --git a/composer.json b/composer.json index 170bef9..ff99437 100644 --- a/composer.json +++ b/composer.json @@ -29,8 +29,7 @@ } ], "require": { - "smtech/stmarks-reflexive-canvas-lti": "~0.1", - "smtech/oauth2-canvaslms": "~1.0", + "smtech/stmarks-reflexive-canvas-lti": "~0.2", "battis/data-utilities": "~0.1", "roderik/pwgen-php": "~0.1" }, diff --git a/composer.lock b/composer.lock index 0241ae5..3f170d3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "a27f893cdcf19f89091e781361f1bbbf", - "content-hash": "4f547057f1ef27e1ccebb76122a06d71", + "hash": "9dc2ab12ca3f757787f8ac019c11b3b6", + "content-hash": "e2d5cf18f33cc5a63e47022373c45b98", "packages": [ { "name": "battis/appmetadata", @@ -315,16 +315,16 @@ }, { "name": "bower-asset/bootstrap-datepicker-1.x", - "version": "v1.6.1", + "version": "v1.6.2", "source": { "type": "git", "url": "https://github.com/eternicode/bootstrap-datepicker.git", - "reference": "f4df9ac6679b15b12157324c556e0da1c628af6e" + "reference": "0735231af58a6f4e0f576978c6d5cd0c2247c6d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/eternicode/bootstrap-datepicker/zipball/f4df9ac6679b15b12157324c556e0da1c628af6e", - "reference": "f4df9ac6679b15b12157324c556e0da1c628af6e", + "url": "https://api.github.com/repos/eternicode/bootstrap-datepicker/zipball/0735231af58a6f4e0f576978c6d5cd0c2247c6d8", + "reference": "0735231af58a6f4e0f576978c6d5cd0c2247c6d8", "shasum": "" }, "require": { @@ -449,16 +449,16 @@ }, { "name": "fxp/composer-asset-plugin", - "version": "v1.2.0", + "version": "v1.2.1", "source": { "type": "git", "url": "https://github.com/fxpio/composer-asset-plugin.git", - "reference": "8d74bc7c714aadbda54622c216b2e7bf786595cb" + "reference": "d7d189e8ffac26a2e39e26a9c75e1fc5c2e2b98d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fxpio/composer-asset-plugin/zipball/8d74bc7c714aadbda54622c216b2e7bf786595cb", - "reference": "8d74bc7c714aadbda54622c216b2e7bf786595cb", + "url": "https://api.github.com/repos/fxpio/composer-asset-plugin/zipball/d7d189e8ffac26a2e39e26a9c75e1fc5c2e2b98d", + "reference": "d7d189e8ffac26a2e39e26a9c75e1fc5c2e2b98d", "shasum": "" }, "require": { @@ -501,7 +501,7 @@ "npm", "package" ], - "time": "2016-07-01 12:04:16" + "time": "2016-08-03 07:44:07" }, { "name": "guzzlehttp/guzzle", @@ -834,16 +834,16 @@ }, { "name": "myclabs/php-enum", - "version": "1.4.1", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/myclabs/php-enum.git", - "reference": "07da9d1a7469941ae05b046193fac4c83bdb0d7e" + "reference": "e83e992a5b5a0858ef7adbc9239a749d71fb6979" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/php-enum/zipball/07da9d1a7469941ae05b046193fac4c83bdb0d7e", - "reference": "07da9d1a7469941ae05b046193fac4c83bdb0d7e", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/e83e992a5b5a0858ef7adbc9239a749d71fb6979", + "reference": "e83e992a5b5a0858ef7adbc9239a749d71fb6979", "shasum": "" }, "require": { @@ -874,7 +874,7 @@ "keywords": [ "enum" ], - "time": "2015-07-22 16:14:03" + "time": "2016-08-01 15:48:47" }, { "name": "pear/log", @@ -1319,21 +1319,22 @@ }, { "name": "smtech/stmarks-reflexive-canvas-lti", - "version": "v0.1", + "version": "v0.2", "source": { "type": "git", "url": "https://github.com/smtech/stmarks-reflexive-canvas-lti.git", - "reference": "06497222d29efbcdb89b6f053e92ce18ded8142d" + "reference": "292025b07e79ab488e92fd565846cb0142fa0595" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/smtech/stmarks-reflexive-canvas-lti/zipball/06497222d29efbcdb89b6f053e92ce18ded8142d", - "reference": "06497222d29efbcdb89b6f053e92ce18ded8142d", + "url": "https://api.github.com/repos/smtech/stmarks-reflexive-canvas-lti/zipball/292025b07e79ab488e92fd565846cb0142fa0595", + "reference": "292025b07e79ab488e92fd565846cb0142fa0595", "shasum": "" }, "require": { "battis/data-utilities": "~0.1", "battis/simplecache": "~1.0", + "smtech/oauth2-canvaslms": "~1.0", "smtech/reflexive-canvas-lti": "~1.0", "smtech/stmarkssmarty": "~1.0" }, @@ -1354,7 +1355,7 @@ } ], "description": "A toolbox for managing LTI authentication and tool provider development (with St. Mark's templating)", - "time": "2016-08-01 15:10:04" + "time": "2016-08-05 03:10:32" }, { "name": "smtech/stmarkssmarty", diff --git a/consumers.php b/consumers.php new file mode 100644 index 0000000..895cf0e --- /dev/null +++ b/consumers.php @@ -0,0 +1,8 @@ +interactiveConsumersControlPanel(); diff --git a/index.php b/index.php index 92bc20a..07dc49f 100644 --- a/index.php +++ b/index.php @@ -8,12 +8,13 @@ define('ACTION_CONFIG', 'config'); define('ACTION_INSTALL', 'install'); +define('ACTION_CONSUMERS', 'consumers'); define('ACTION_UNSPECIFIED', false); /* store any requested actions for future handling */ $action = (empty($_REQUEST['action']) ? - ACTION_UNSPECIFIED : - strtolower($_REQUEST['action']) + ACTION_UNSPECIFIED : + strtolower($_REQUEST['action']) ); /* action requests only come from outside the LTI! */ @@ -23,71 +24,60 @@ /* authenticate LTI launch request, if present */ if ($toolbox->lti_isLaunching()) { - $_SESSION = []; /* clear all session data */ - $toolbox->lti_authenticate(); - exit; + $_SESSION = []; /* clear all session data */ + $toolbox->lti_authenticate(); + exit; } /* if authenticated LTI launch, redirect to appropriate placement view */ if (!empty($_SESSION[ToolProvider::class]['canvas']['account_id'])) { - $_SESSION[ACCOUNT_ID] = $_SESSION[ToolProvider::class]['canvas']['account_id']; - header("Location: account/"); - exit; + $_SESSION[ACCOUNT_ID] = $_SESSION[ToolProvider::class]['canvas']['account_id']; + header("Location: account/"); + exit; } elseif (!empty($_SESSION[ToolProvider::class]['canvas']['course_id'])) { - $_SESSION[COURSE_ID] = $_SESSION[ToolProvider::class]['canvas']['course_id']; - header('Location: course/'); - exit; + $_SESSION[COURSE_ID] = $_SESSION[ToolProvider::class]['canvas']['course_id']; + header('Location: course/'); + exit; /* if not authenticated, default to showing credentials */ } else { - $action = (empty($action) ? - ACTION_CONFIG : - $action - ); + $action = (empty($action) ? + ACTION_CONFIG : + $action + ); } /* process any actions */ switch ($action) { - /* reset cached install data from config file */ - case ACTION_INSTALL: { - $_SESSION['toolbox'] = Toolbox::fromConfiguration(CONFIG_FILE, true); - $toolbox =& $_SESSION['toolbox']; + /* reset cached install data from config file */ + case ACTION_INSTALL: { + $_SESSION['toolbox'] = Toolbox::fromConfiguration(CONFIG_FILE, true); + $toolbox =& $_SESSION['toolbox']; - /* patch in newly-acquired token via oauth, if present */ - if (!empty($_SESSION['TOOL_CANVAS_API'])) { - $toolbox->config('TOOL_CANVAS_API', $_SESSION['TOOL_CANVAS_API']); - unset($_SESSION['TOOL_CANVAS_API']); - } + /* test to see if we can connect to the API */ + try { + $toolbox->getAPI(); + } catch (ConfigurationException $e) { - /* test to see if we can connect to the API */ - try { - $toolbox->getAPI(); - } catch (ConfigurationException $e) { + /* if there isn't an API token in config.xml, are there OAuth credentials? */ + if ($e->getCode() === ConfigurationException::CANVAS_API_INCORRECT) { + $toolbox->interactiveGetAccessToken('This tool requires access to the Canvas APIs by an administrative user. This API access is used to query student analytics data that is presented on the Advisor Dashboard. Please enter the URL of your Canvas instance below (e.g. https://canvas.instructure.com -- the URL that you would enter to log in to Canvas). If you are not already logged in, you will be asked to log in. After logging in, you will be asked to authorize this tool.

If you are already logged, but not logged in as an administrative user, please log out now, so that you may log in as administrative user to authorize this tool.'); + exit; + } else { /* no (understandable) API credentials available -- doh! */ + throw $e; + } + } - /* if there isn't an API token in config.xml, are there OAuth credentials? */ - $canvas = $toolbox->config('TOOL_CANVAS_API'); - if ($e->getCode() === ConfigurationException::CANVAS_API_INCORRECT && - !empty($canvas['key']) && - !empty($canvas['secret']) - ) { - /* if so, request an API access token interactively */ - header('Location: ' . $toolbox->config('APP_URL') . "/admin/oauth.php?oauth-return={$_SERVER['REQUEST_URI']}"); - exit; - } else { /* no (understandable) API credentials available -- doh! */ - throw $e; - } - } + /* finish by opening consumers control panel */ + header('Location: consumers.php'); + exit; + } - /* finish by opening consumers control panel */ - header("Location: admin/"); - exit; - } - - /* show LTI configuration XML file */ - case ACTION_CONFIG: { - header('Content-type: application/xml'); - echo $toolbox->saveConfigurationXML(); - exit; - } + /* show LTI configuration XML file */ + case ACTION_CONFIG: { + header('Content-type: application/xml'); + echo $toolbox->saveConfigurationXML(); + exit; + } } diff --git a/templates/consumers-control-panel.tpl b/templates/consumers-control-panel.tpl deleted file mode 100644 index 42eb33d..0000000 --- a/templates/consumers-control-panel.tpl +++ /dev/null @@ -1,105 +0,0 @@ -{assign var="formLabelWidth" value=$formLabelWidth|Default: 4} -{extends file="subpage.tpl"} - -{block name="subcontent"} - -

- - - - - - - - - - - {if count($consumers) > 0} - {foreach $consumers as $_consumer} - {if empty($key) || (!empty($key) && $key != $_consumer->getKey())} - {$selected = false} - {else} - {$selected = true} - {/if} - - - - - - {if !$selected} - - {/if} - - {/foreach} - {else} - - - - {/if} - -
NameConsumer KeyShared SecretEnabled
{$_consumer->name}{$_consumer->getKey()}{$_consumer->secret} -
- enabled}checked="checked"{/if} readonly /> -
-
-
-
- - - -
-
-
No consumers registered yet.
-
-
-
-
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
-
-
- -
-
-
- -
-
- - {if !empty($key)} - - {/if} - -
-
-
-
- -
-

To install this LTI, users should choose configuration type By URL and provide their consumer key and secret above. They should point their installer at:

-

{$appUrl}?action=config

-
- -{/block} diff --git a/templates/navigation-menu.tpl b/templates/navigation-menu.tpl deleted file mode 100644 index 0b1a578..0000000 --- a/templates/navigation-menu.tpl +++ /dev/null @@ -1,7 +0,0 @@ -{if isset($ltiUser)} - -{/if} \ No newline at end of file diff --git a/templates/oauth-form.tpl b/templates/oauth-form.tpl deleted file mode 100644 index 6ef41a8..0000000 --- a/templates/oauth-form.tpl +++ /dev/null @@ -1,14 +0,0 @@ -{extends file="form.tpl"} - -{block name="form-content"} - -
- - - - -
- - {assign var="formButton" value="Log In"} - -{/block} diff --git a/templates/oauth.tpl b/templates/oauth.tpl deleted file mode 100644 index 5d3ce9d..0000000 --- a/templates/oauth.tpl +++ /dev/null @@ -1,15 +0,0 @@ -{extends file="page.tpl"} - -{block name="content"} - - - -
-

This tool requires access to the Canvas APIs. You can provide this access either by editing your config.xml file to include the URL of your Canvas API and a valid API access token, or by interactively authenticating to Canvas to issue an API token directly right now.

-
- - {include file="oauth-form.tpl"} - -{/block}