Commit d7018426 authored by Cecilia Vela Gurovic's avatar Cecilia Vela Gurovic Committed by Robert Lyon

Bug 1660237: removed old mobile api

removed code from htdocs/api/module/ files and replace it with a json reply error message.
removed the 'allowmobileuploads' config variable since it is only used by the old mobile api.
removed the 'mobileuploadtoken' values in usr_account_preferences since they are only used by old mobile api. The new mahara mobile uses external_tokens table to store its access tokens.

behatnotneeded

Change-Id: I02e94079fc83aa6a81534b70446f7e8ab2ebd7a4
parent 4b7752ac
......@@ -178,14 +178,6 @@ function accountprefs_validate(Pieform $form, $values) {
}
}
if (get_config('allowmobileuploads')) {
foreach ($values['mobileuploadtoken'] as $k => $text) {
if (strlen($text) > 0 && !preg_match('/^[a-zA-Z0-9 !@#$%^&*()\-_=+\[{\]};:\'",<\.>\/?]{6,}$/', $text)) {
$form->set_error('mobileuploadtoken', get_string('badmobileuploadtoken', 'account'));
}
}
}
plugin_account_prefs_validate($form, $values);
}
......@@ -223,14 +215,6 @@ function accountprefs_submit(Pieform $form, $values) {
$oldgroupsideblockmaxgroups = $USER->get_account_preference('groupsideblockmaxgroups');
$oldgroupsideblocksortby = $USER->get_account_preference('groupsideblocksortby');
if (get_config('allowmobileuploads')) {
// Make sure the mobile token is formatted / saved correctly
$values['mobileuploadtoken'] = array_filter($values['mobileuploadtoken']);
$new_token_pref = empty($values['mobileuploadtoken']) ? null : ('|' . join('|', $values['mobileuploadtoken']) . '|');
$USER->set_account_preference('mobileuploadtoken', $new_token_pref);
unset($values['mobileuploadtoken']);
}
// Set user account preferences
foreach ($expectedprefs as $eprefkey => $epref) {
if (isset($values[$eprefkey]) && $values[$eprefkey] !== get_account_preference($USER->get('id'), $eprefkey)) {
......
......@@ -677,13 +677,6 @@ $siteoptionform = array(
'defaultvalue' => get_config('licenseallowcustom'),
'disabled' => in_array('licenseallowcustom', $OVERRIDDEN),
),
'allowmobileuploads' => array(
'type' => 'switchbox',
'title' => get_string('allowmobileuploads1', 'admin'),
'description' => get_string('allowmobileuploadsdescription1', 'admin'),
'defaultvalue' => get_config('allowmobileuploads'),
'disabled' => in_array('allowmobileuploads', $OVERRIDDEN),
),
'wysiwyg' => array(
'type' => 'select',
'title' => get_string('wysiwyg', 'admin'),
......@@ -802,7 +795,7 @@ function siteoptions_submit(Pieform $form, $values) {
'recaptchaonregisterform', 'recaptchapublickey', 'recaptchaprivatekey', 'loggedinprofileviewaccess', 'disableexternalresources',
'proxyaddress', 'proxyauthmodel', 'proxyauthcredentials', 'smtphosts', 'smtpport', 'smtpuser', 'smtppass', 'smtpsecure',
'noreplyaddress', 'homepageinfo', 'showprogressbar', 'showonlineuserssideblock', 'onlineuserssideblockmaxusers',
'registerterms', 'licensemetadata', 'licenseallowcustom', 'allowmobileuploads', 'creategroups', 'createpublicgroups', 'allowgroupcategories', 'wysiwyg',
'registerterms', 'licensemetadata', 'licenseallowcustom', 'creategroups', 'createpublicgroups', 'allowgroupcategories', 'wysiwyg',
'staffreports', 'staffstats', 'userscandisabledevicedetection', 'watchlistnotification_delay',
'masqueradingreasonrequired', 'masqueradingnotified', 'searchuserspublic',
'eventloglevel', 'eventlogexpiry', 'eventlogenhancedsearch', 'sitefilesaccess', 'exporttoqueue', 'defaultmultipleblogs',
......
......@@ -2,9 +2,9 @@
/**
*
* @package mahara
* @subpackage api
* @author Alan McNatty <alan@catalyst.net.nz>, Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @subpackage mobile
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @copyright For copyright information on Mahara, please see the README file distributed with this software.
*
*/
......
......@@ -2,9 +2,9 @@
/**
*
* @package mahara
* @subpackage api
* @author Alan McNatty <alan@catalyst.net.nz>, Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @subpackage mobile
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @copyright For copyright information on Mahara, please see the README file distributed with this software.
*
*/
......@@ -15,124 +15,6 @@ define('JSON', 1);
define('NOSESSKEY', 1);
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
safe_require('artefact', 'file');
safe_require('artefact', 'blog');
require_once('lib.php');
$json = array('time' => time());
if (!get_config('allowmobileuploads')) {
mobile_api_json_reply( array('fail' => get_string('mobileuploadnotenabled', 'auth') ) );
}
$token = trim(param_variable('token', ''));
if ($token == '') {
mobile_api_json_reply( array('fail' => get_string('mobileuploadtokennotset', 'auth') ) );
}
$username = trim(param_variable('username', ''));
if ($username == '') {
mobile_api_json_reply( array('fail' => get_string('mobileuploadusernamenotset', 'auth') ) );
}
$USER = new User();
try {
$USER->find_by_mobileuploadtoken($token, $username);
}
catch (AuthUnknownUserException $e) {
mobile_api_json_reply( array('fail' => get_string('mobileuploadtokennotfound', 'auth') ) );
}
// Add in bits of sync data - let's start with notifications
$lastsync = param_integer('lastsync', 0);
$notification_types_sql = '';
$notification_types = explode(",", trim(param_variable('notifications', '')));
if (count($notification_types) > 0) {
$notification_types_sql = ' a.name IN (' . join(',', array_map('db_quote',$notification_types)) . ')';
}
$activity_arr = get_records_sql_array("
SELECT n.id, n.subject, n.message
FROM {notification_internal_activity} n
INNER JOIN {activity_type} a ON n.type=a.id
WHERE $notification_types_sql
AND n.read=0
AND " . db_format_tsfield('ctime', '') . " >= ?
AND n.usr= ? ",
array($lastsync, $USER->id)
);
if (count($activity_arr) > 0) {
$json['activity'] = $activity_arr;
}
// OK - let's add tags
$tags_arr = array();
$tagsort = param_alpha('ts', null) != 'freq' ? 'alpha' : 'freq';
foreach (get_my_tags(null, false, $tagsort) as $tag) {
$tags_arr[] = array("id" => $tag->tag, "tag" => $tag->tag);
}
if (count($tags_arr) > 0) {
$json['tags'] = $tags_arr;
}
// OK - let's add journals (and journal posts)
$blogs_arr = array();
$blogs = (object) array(
'offset' => param_integer('offset', 0),
'limit' => param_integer('limit', 10),
);
$blogposts_arr = array();
$blogposts = array();
list($blogs->count, $blogs->data) = ArtefactTypeBlog::get_blog_list($blogs->limit, $blogs->offset);
foreach ($blogs->data as $blog) {
if (!$blog->locked) {
$blogs_arr[] = array("id" => $blog->id, "blog" => $blog->title);
$blogposts = ArtefactTypeBlogpost::get_posts($blog->id, $blogs->limit, $blogs->offset, null);
foreach ($blogposts['data'] as $blogpost) {
if (!$blogpost->locked) {
$blogposts_arr[] = array("id" => $blogpost->id, "blogpost" => $blogpost->title);
}
}
}
}
if (count($blogs_arr) > 0) {
$json['blogs'] = $blogs_arr;
}
if (count($blogposts_arr) > 0) {
$json['blogposts'] = $blogposts_arr;
}
// OK - let's add folders
$folders_arr = array();
$folders = ArtefactTypeFile::get_my_files_data(0, $USER->id, null, null, array("artefacttype" => array("folder")));
foreach ($folders as $folder) {
if ( ! $folder->locked ) {
$folders_arr[] = array("id" => $folder->id, "folder" => $folder->title);
}
}
if (count($folders_arr) > 0) {
$json['folders'] = $folders_arr;
}
// Here we need to create a new hash - update our own store of it and return it to the handset
mobile_api_json_reply(array('success' => $USER->refresh_mobileuploadtoken($token), 'sync' => $json));
mobile_api_json_reply( array('fail' => get_string('deprecatedmobileapp', 'admin') ) );
......@@ -2,158 +2,19 @@
/**
*
* @package mahara
* @subpackage api
* @author Alan McNatty <alan@catalyst.net.nz>, Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @subpackage mobile
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @copyright For copyright information on Mahara, please see the README file distributed with this software.
*
*/
define('INTERNAL', 1);
define('PUBLIC', 1);
define('SECTION_PLUGINTYPE', 'artefact');
define('SECTION_PLUGINNAME', 'blog');
define('JSON', 1);
define('NOSESSKEY', 1);
define('INTERNAL', 1);
define('PUBLIC', 1);
define('JSON', 1);
define('NOSESSKEY', 1);
$json = array();
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
require_once('lib.php');
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
safe_require('artefact', 'file');
safe_require('artefact', 'blog');
require_once('lib.php');
if (!get_config('allowmobileuploads')) {
mobile_api_json_reply(array('fail' => get_string('mobileuploadnotenabled', 'auth')));
}
$token = trim(param_variable('token', ''));
if ($token == '') {
mobile_api_json_reply(array('fail' => get_string('mobileuploadtokennotset', 'auth')));
}
$username = trim(param_variable('username', ''));
if ($username == '') {
mobile_api_json_reply(array('fail' => get_string('mobileuploadusernamenotset', 'auth')));
}
// Starting the creation of our artefact (file) object
$data = new StdClass;
$USER = new User();
try {
$USER->find_by_mobileuploadtoken($token, $username);
}
catch (AuthUnknownUserException $e) {
mobile_api_json_reply(array('fail' => get_string('mobileuploadtokennotfound', 'auth')));
}
$data->owner = $USER->get('id'); // id of owner
$folder = trim(param_variable('foldername', ''));
if ($folder) {
$artefact = ArtefactTypeFolder::get_folder_by_name($folder, null, $data->owner);
if ($artefact) {
$data->parent = $artefact->id;
if ($data->parent == 0) {
$data->parent = null;
}
}
else {
$fd = (object) array(
'owner' => $data->owner,
'title' => $folder,
'parent' => null,
);
$f = new ArtefactTypeFolder(0, $fd);
$f->commit();
$data->parent = $f->get('id');
}
}
else {
$data->parent = null;
}
// Check for Journal ID to add a post to
$blog = param_integer('blog', 0);
$blogpost = param_integer('blogpost', 0);
$draft = param_alpha('draft', '');
$allowcomments = param_alpha('allowcomments', '');
// Check for artefact attributes title, description (or entry), tags, etc
$title = param_variable('title', '');
$description = param_variable('description', '');
$tags = explode(",", param_variable('tags', ''));
// -- Now check for files to upload --
$artefact_id = ''; // our resulting artefact id on creation
if ($_FILES) {
$file_title = $title;
if ($blog || !$title) { // set the filename to be the title of the artefact
$file_title = basename($_FILES['userfile']['name']);
}
try {
$data->title = ArtefactTypeFileBase::get_new_file_title($file_title, $data->parent, $data->owner);
if (!$blog) { // only set a description if it's an artefact upload
$data->description = $description;
}
$data->tags = $tags;
$artefact_id = ArtefactTypeFile::save_uploaded_file('userfile', $data);
}
catch (QuotaExceededException $e) {
mobile_api_json_reply(array('fail' => get_string('uploadexceedsquota', 'artefact.file')));
}
catch (UploadException $e) {
mobile_api_json_reply(array('fail' => get_string('uploadoffilefailed', 'artefact.file', $file_title)));
}
}
// -- Next create a blog entry --
$postobj = ''; // our resulting blog post object on creation
if ($blog) {
if (!get_record('artefact', 'id', $blog, 'owner', $USER->get('id'))) {
// Blog security is also checked closer to when blogs are added, this
// check ensures that malicious users do not even see the screen for
// adding a post to a blog that is not theirs
mobile_api_json_reply(array('fail' => get_string('youarenottheownerofthisblog', 'artefact.blog')));
}
$postobj = new ArtefactTypeBlogPost(null, null);
$postobj->set('title', $title);
$postobj->set('description', $description);
$postobj->set('tags', $tags);
$postobj->set('published', !$draft);
$postobj->set('allowcomments', (int) $allowcomments);
$postobj->set('parent', $blog);
$postobj->set('owner', $USER->id);
$postobj->commit();
$blogpost = $postobj->get('id');
}
else if ($blogpost) {
$postobj = new ArtefactTypeBlogPost($blogpost);
$postobj->check_permission();
if ($postobj->get('locked')) {
mobile_api_json_reply(array('fail' => get_string('submittedforassessment', 'view')));
}
}
if ($blogpost) {
$json['id'] = $blogpost;
}
// Check to see if we're creating a journal entry
// -- Finally attach the file to the blog post once uploaded and --
if ($artefact_id && $postobj) {
// If we created or matched a blog post and created an artefact
// attach the artefact to the blog.
$postobj->attach($artefact_id);
}
// Here we need to create a new hash - update our own store of it and return it to the handset
mobile_api_json_reply(array('success' => $USER->refresh_mobileuploadtoken($token), 'sync' => $json));
mobile_api_json_reply( array('fail' => get_string('deprecatedmobileapp', 'admin') ) );
<?php
/**
*
* @package mahara
* @subpackage artefact-file
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @copyright For copyright information on Mahara, please see the README file distributed with this software.
*
*/
define('INTERNAL', 1);
define('PUBLIC', 1);
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
safe_require('artefact', 'file');
if (!get_config('allowmobileuploads')) {
JSONResponse('fail', 'Mobile uploads disabled');
}
$token = '';
try {
$token = param_variable('token');
$token = trim($token);
}
catch (ParameterException $e) { }
if ($token == '') {
JSONResponse('fail', 'Auth token cannot be blank');
}
$username = '';
try {
$username = trim(param_variable('username'));
}
catch (ParameterException $e) { }
if ($username == '') {
JSONResponse('fail', 'Username cannot be blank');
}
$data = new StdClass;
$USER = new User();
try {
$USER->find_by_mobileuploadtoken($token, $username);
}
catch (AuthUnknownUserException $e) {
JSONResponse('fail', 'Invalid user token');
}
$data->owner = $USER->get('id'); // id of owner
$folder = '';
try {
$folder = param_variable('foldername');
$folder = trim($folder);
if ($folder) {
// TODO: create if doesn't exist - note assumes it is a base folder (hence null parent)
$artefact = ArtefactTypeFolder::get_folder_by_name($folder, null, $data->owner); // id of folder you're putting the file into
if ($artefact) {
$data->parent = $artefact->id;
if ($data->parent == 0) {
$data->parent = null;
}
}
else {
$fd = (object) array(
'owner' => $data->owner,
'title' => $folder,
'parent' => null,
);
$f = new ArtefactTypeFolder(0, $fd);
$f->commit();
$data->parent = $f->get('id');
}
}
else {
$data->parent = null;
}
}
catch (ParameterException $e) {
$data->parent = null;
}
// Set title
$title = '';
try {
$title = param_variable('title');
}
catch (ParameterException $e) {
// Default ot the name given with the post
$title = $_FILES['userfile']['name'];
}
$title = $title ? basename($title) : get_string('file', 'artefact.file');
$data->title = ArtefactTypeFileBase::get_new_file_title($title, $data->parent, $data->owner);
// Set description
try {
$data->description = param_variable('description');
}
catch (ParameterException $e) { }
// Set tags
try {
$data->tags = explode(" ", param_variable('tags'));
}
catch (ParameterException $e) { }
if (get_config('licensemetadata')) {
// Set licensing information
try {
$license = license_coalesce(null,
param_variable('license'), param_variable('license_other', null));
$licensor = param_variable('licensor');
$licensorurl = param_variable('licensorurl');
}
catch (ParameterException $e) { }
}
try {
$newid = ArtefactTypeFile::save_uploaded_file('userfile', $data);
}
catch (QuotaExceededException $e) {
JSONResponse('fail', 'Quota exceeded');
}
catch (UploadException $e) {
JSONResponse('fail', 'Failed to save file');
}
// Here we need to create a new hash - update our own store of it and return it too the handset
JSONResponse ( "success", $USER->refresh_mobileuploadtoken($token) );
function JSONResponse ( $key, $value ) {
header('Content-Type: application/json');
echo json_encode(array($key => $value));
exit;
}
......@@ -294,63 +294,6 @@ class User {
return $this;
}
/**
* Populates this object with the user record identified by a mobile 'token'
*
* @throws AuthUnknownUserException If the user cannot be found.
*/
public function find_by_mobileuploadtoken($token, $username) {
if (!is_string($token)) {
throw new InvalidArgumentException('Input parameters must be strings to create a User object from token');
}
$sql = 'SELECT
u.*,
' . db_format_tsfield('u.expiry', 'expiry') . ',
' . db_format_tsfield('u.lastlogin', 'lastlogin') . ',
' . db_format_tsfield('u.lastlastlogin', 'lastlastlogin') . ',
' . db_format_tsfield('u.lastaccess', 'lastaccess') . ',
' . db_format_tsfield('u.suspendedctime', 'suspendedctime') . ',
' . db_format_tsfield('u.ctime', 'ctime') . '
FROM
{usr} u
LEFT JOIN {usr_account_preference} p ON u.id = p.usr
WHERE p.field=\'mobileuploadtoken\'
AND p.value ' . db_ilike() . ' \'%|\' || ? || \'|%\' AND u.username = ?
';
$user = get_record_sql($sql, array($token, $username));
if (false == $user) {
throw new AuthUnknownUserException("User with mobile upload token \"$token\" is not known");
}
$this->populate($user);
$this->accountprefs = load_account_preferences($user->id);
return $this;
}
/**
* Refreshes a users mobile 'token' and returns it
*
*/
public function refresh_mobileuploadtoken($old_token) {
$new_token = md5(openssl_random_pseudo_bytes(8));
$old_tokenstring = $this->get_account_preference('mobileuploadtoken');
$tokenarray = explode('|', trim($old_tokenstring, '|'));
foreach ($tokenarray as $k => $v) {
if ( $v == $old_token ) {
$tokenarray[$k] = $new_token;
}
}
$new_tokenstring = empty($tokenarray) ? null : ('|' . join('|', $tokenarray) . '|');
$this->set_account_preference('mobileuploadtoken', $new_tokenstring);
$this->set('lastaccess', time());
$this->commit();
return $new_token;
}
/**
* Set stuff that needs to be initialised once before a user record is created.
*/
......
......@@ -64,9 +64,6 @@ $string['showhomeinfodescription1'] = 'Display information about how to use %s o
$string['showprogressbar'] = 'Profile completion progress bar';
$string['showprogressbardescription'] = 'Display progress bar and tips on how to complete your %s profile.';
$string['mobileuploadtoken'] = 'Mobile upload token';
$string['badmobileuploadtoken'] = 'Sorry that mobile upload token is invalid. Tokens must be at least 6 characters long.';
$string['prefssaved'] = 'Preferences saved';
$string['prefsnotsaved'] = 'Failed to save your preferences.';
......
......@@ -367,6 +367,7 @@ $string['defaultaccountlifetimeupdatedescription'] = 'If default account lifetim
$string['defaultaccountlifetimeupdatenone'] = 'Only for newly created users';
$string['defaultaccountlifetimeupdatesome'] = 'For new users and users without an account lifetime already set (excluding site administrators)';
$string['defaultaccountlifetimeupdateall'] = 'For all user accounts (excluding site administrators)';
$string['deprecatedmobileapp'] = "Sorry, this mobile application has been superseded. You need to use Mahara mobile application instead. Download for android devices https://play.google.com/store/apps/details?id=org.mahara.mobile or for apple devices https://itunes.apple.com/us/app/mahara-mobile/id1172638950";
$string['embeddedcontent'] = 'Embedded content';
$string['embeddedcontentdescription'] = 'If you would like users to be able to embed videos or other outside content into their portfolios, you can choose which sites to trust below.';
$string['Everyone'] = 'Everyone';
......@@ -394,8 +395,6 @@ $string['licensemetadata'] = 'License metadata';
$string['licensemetadatadescription'] = "Request and store license metadata for user-generated content.";
$string['licenseallowcustom1'] = 'Custom licenses';
$string['licenseallowcustomdescription'] = "For license metadata, allow users to enter any URL as the license. If not checked, users will be limited to the licenses configured by the site administrator.";
$string['allowmobileuploads1'] = 'Mobile uploads';
$string['allowmobileuploadsdescription1'] = 'Users can set an authentication token for use with a mobile app for Mahara. Content uploaded with this token will be saved as artefacts.';
$string['recaptchakeysmissing1'] = 'reCAPTCHA is turned on, but it will not function until you also provide a site key and secret key.';
$string['recaptchanotpassed'] = 'The reCAPTCHA wasn\'t entered correctly. Please try it again.';
$string['recaptchaonregisterform'] = 'reCAPTCHA on user registration form';
......
......@@ -74,12 +74,6 @@ $string['duplicateremoteusername'] = 'This external authentication username is a
$string['duplicateremoteusernameformerror'] = 'External authentication usernames must be unique within an authentication method.';
$string['cannotjumpasmasqueradeduser'] = 'You cannot jump to another application whilst masquerading as another user.';
// Error messages for mobile API
$string['mobileuploadnotenabled'] = 'Sorry mobile uploads are not enabled.';
$string['mobileuploadtokennotset'] = 'Your mobile upload token cannot be blank. Please check your mobile application settings and try again.';
$string['mobileuploadusernamenotset'] = 'Your mobile upload username cannot be blank. Please check your mobile application settings and try again.';
$string['mobileuploadtokennotfound'] = 'Sorry that mobile upload token was not found. Please check your site and mobile application settings.';
// Shared warning messages.
$string['warninstitutionregistration'] = '$cfg->usersuniquebyusername is turned on but registration is allowed for an institution. For security reasons all institutions need to have \'Registration allowed\' turned off. To adjust this via the web interface you will need to temporarily set $cfg->usersuniquebyusername = false.';
$string['warninstitutionregistrationinstitutions'] = array(
......
......@@ -5414,5 +5414,14 @@ function xmldb_core_upgrade($oldversion=0) {
add_field($table, $field);
}
}
if ($oldversion < 2017103100) {
// remove allowmobileuploads from config, used only by old mobile api