aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--avatar.php24
-rw-r--r--lib/avatar.php13
-rw-r--r--lib/notsquareexception.php12
-rw-r--r--lib/public/avatar.php4
-rw-r--r--settings/css/settings.css2
-rw-r--r--settings/js/personal.js62
-rw-r--r--settings/personal.php2
-rw-r--r--settings/templates/personal.php1
8 files changed, 94 insertions, 26 deletions
diff --git a/avatar.php b/avatar.php
index a54aad3b2a6..c860ad9e369 100644
--- a/avatar.php
+++ b/avatar.php
@@ -36,26 +36,40 @@ if ($_SERVER['REQUEST_METHOD'] === "GET") {
// Select an image from own files
if (isset($_POST['path'])) {
- //SECURITY TODO does this fully eliminate directory traversals?
$path = stripslashes($_POST['path']);
$avatar = OC::$SERVERROOT.'/data/'.$user.'/files'.$path;
}
+
+ if (isset($_POST['crop'])) {
+ $crop = json_decode($_POST['crop'], true);
+ if (!isset($path)) {
+ // TODO get path to temporarily saved uploaded-avatar
+ }
+ $image = new \OC_Image($avatar);
+ $image->crop($x, $y, $w, $h);
+ $avatar = $image->data();
+ }
+
// Upload a new image
- elseif (!empty($_FILES)) {
+ if (!empty($_FILES)) {
$files = $_FILES['files'];
if ($files['error'][0] === 0) {
$avatar = file_get_contents($files['tmp_name'][0]);
unlink($files['tmp_name'][0]);
+ // TODO make the tmp_name reusable, if the uploaded avatar is not square
}
- } else {
- OC_JSON::error();
}
try {
\OC_Avatar::set($user, $avatar);
OC_JSON::success();
+ } catch (\OC\NotSquareException $e) {
+ $tmpname = \OC_Util::generate_random_bytes(10);
+ // TODO Save the image temporarily here
+ // TODO add a cronjob that cleans up stale tmpimages
+ OC_JSON::error(array("data" => array("message" => "notsquare", "tmpname" => $tmpname) ));
} catch (\Exception $e) {
- OC_JSON::error(array("data" => array ("message" => $e->getMessage()) ));
+ OC_JSON::error(array("data" => array("message" => $e->getMessage()) ));
}
} elseif ($_SERVER['REQUEST_METHOD'] === "DELETE") {
$user = OC_User::getUser();
diff --git a/lib/avatar.php b/lib/avatar.php
index 86be0ea2635..9ab905c852e 100644
--- a/lib/avatar.php
+++ b/lib/avatar.php
@@ -26,7 +26,7 @@ class OC_Avatar {
$ext = 'png';
} else {
return false;
- }
+ }
$avatar = new OC_Image($view->file_get_contents('avatar.'.$ext));
$avatar->resize($size);
@@ -38,7 +38,8 @@ class OC_Avatar {
* @param $user string user to set the avatar for
* @param $data mixed imagedata or path to set a new avatar
* @throws Exception if the provided file is not a jpg or png image
- * @throws Exception if the provided image is not valid, or not a square
+ * @throws Exception if the provided image is not valid
+ * @throws \OC\NotSquareException if the image is not square
* @return true on success
*/
public static function set ($user, $data) {
@@ -52,9 +53,13 @@ class OC_Avatar {
throw new \Exception($l->t("Unknown filetype"));
}
- if (!( $img->valid() && ($img->height() === $img->width()) )) {
+ if (!$img->valid()) {
$l = \OC_L10N::get('lib');
- throw new \Exception($l->t("Invalid image, or the provided image is not square"));
+ throw new \Excpeption($l->t("Invalid image"));
+ }
+
+ if (!($img->height() === $img->width())) {
+ throw new \OC\NotSquareException();
}
$view->unlink('avatar.jpg');
diff --git a/lib/notsquareexception.php b/lib/notsquareexception.php
new file mode 100644
index 00000000000..03dba8fb25f
--- /dev/null
+++ b/lib/notsquareexception.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * Copyright (c) 2013 Christopher Schäpers <christopher@schaepers.it>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC;
+
+class NotSquareException extends \Exception {
+}
diff --git a/lib/public/avatar.php b/lib/public/avatar.php
index 768d292346f..55eff57d161 100644
--- a/lib/public/avatar.php
+++ b/lib/public/avatar.php
@@ -12,8 +12,4 @@ class Avatar {
public static function get ($user, $size = 64) {
return \OC_Avatar::get($user, $size);
}
-
- public static function getMode () {
- return \OC_Avatar::getMode();
- }
}
diff --git a/settings/css/settings.css b/settings/css/settings.css
index e6ced0e375a..a2c3eaf6263 100644
--- a/settings/css/settings.css
+++ b/settings/css/settings.css
@@ -21,6 +21,8 @@ input#openid, input#webdav { width:20em; }
input#identity { width:20em; }
#email { width: 17em; }
+#avatar .warning { width: 350px; }
+
.msg.success{ color:#fff; background-color:#0f0; padding:3px; text-shadow:1px 1px #000; }
.msg.error{ color:#fff; background-color:#f00; padding:3px; text-shadow:1px 1px #000; }
diff --git a/settings/js/personal.js b/settings/js/personal.js
index dd2d15052d1..eaf90636d35 100644
--- a/settings/js/personal.js
+++ b/settings/js/personal.js
@@ -45,17 +45,57 @@ function changeDisplayName(){
}
function selectAvatar (path) {
- $.post(OC.filePath('', '', 'avatar.php'), {path: path}, function(data) {
- if (data.status === "success") {
- updateAvatar();
- } else {
- OC.dialogs.alert(data.data.message, t('core', "Error"));
- }
- });
+ $.post(OC.filePath('', '', 'avatar.php'), {path: path}, avatarResponseHandler);
}
function updateAvatar () {
- $('#avatar img').attr('src', $('#avatar img').attr('src') + '#');
+ $avatarimg = $('#avatar img');
+ $avatarimg.attr('src', $avatarimg.attr('src') + '#');
+}
+
+function showAvatarCropper() {
+ OC.dialogs.message('', t('settings', 'Crop'), undefined, OCdialogs.OK_BUTTON, sendCropData);
+ var $dialog = $('#oc-dialog-'+(OC.dialogs.dialogs_counter-1)+'-content');
+ var cropper = new Image();
+ $(cropper).load(function() {
+ $(this).attr('id', 'cropper');
+ $('#oc-dialog-'+(OC.dialogs.dialogs_counter-1)+'-content').html(this);
+ $(this).Jcrop({
+ onChange: saveCoords,
+ onSelect: saveCoords,
+ aspectRatio: 1
+ });
+ }).attr('src', OC.filePath('', '', 'avatar.php')+"?user="+OC.currentUser+"&size=512&tmp="+$('#avatar').data('tmpname'));
+}
+
+function sendCropData() {
+ var tmp = $('#avatar').data('tmpname');
+ var cropperdata = $('#cropper').data();
+ var data = {
+ x: cropperdata.x,
+ y: cropperdata.y,
+ w: cropperdata.w,
+ h: cropperdata.h
+ };
+ $.post(OC.filePath('', '', 'avatar.php'), {tmp:tmp, crop: data}, avatarResponseHandler);
+}
+
+function saveCoords(c) {
+ $('#cropper').data(c);
+}
+
+function avatarResponseHandler(data) {
+ $warning = $('#avatar .warning');
+ $warning.hide();
+ if (data.status === "success") {
+ updateAvatar();
+ } else if (data.data.message === "notsquare") {
+ $('#avatar').data('tmpname', data.data.tmpname);
+ showAvatarCropper();
+ } else {
+ $warning.show();
+ $warning.text(data.data.message);
+ }
}
$(document).ready(function(){
@@ -149,11 +189,7 @@ $(document).ready(function(){
var uploadparms = {
done: function(e, data) {
- if (data.result.status === "success") {
- updateAvatar();
- } else {
- OC.dialogs.alert(data.result.data.message, t('core', "Error"));
- }
+ avatarResponseHandler(data.result);
}
};
diff --git a/settings/personal.php b/settings/personal.php
index d109d33e4bd..33c78c0467f 100644
--- a/settings/personal.php
+++ b/settings/personal.php
@@ -16,6 +16,8 @@ OC_Util::addStyle( 'settings', 'settings' );
OC_Util::addScript( '3rdparty', 'chosen/chosen.jquery.min' );
OC_Util::addStyle( '3rdparty', 'chosen' );
\OC_Util::addScript('files', 'jquery.fileupload');
+\OC_Util::addScript('3rdparty/Jcrop', 'jquery.Jcrop.min');
+\OC_Util::addStyle('3rdparty/Jcrop', 'jquery.Jcrop.min');
OC_App::setActiveNavigationEntry( 'personal' );
$storageInfo=OC_Helper::getStorageInfo();
diff --git a/settings/templates/personal.php b/settings/templates/personal.php
index 7cd5361a924..5db28779b55 100644
--- a/settings/templates/personal.php
+++ b/settings/templates/personal.php
@@ -88,6 +88,7 @@ if($_['passwordChangeSupported']) {
<legend><strong><?php p($l->t('Profile Image')); ?></strong></legend>
<img src="<?php print_unescaped(link_to('', 'avatar.php').'?user='.OC_User::getUser().'&size=128'); ?>"><br>
<em><?php p($l->t('Has to be square and either PNG or JPG')); ?></em><br>
+ <div class="warning hidden"></div>
<div class="inlineblock button" id="uploadavatarbutton"><?php p($l->t('Upload new')); ?></div>
<input type="file" class="hidden" name="files[]" id="uploadavatar">
<div class="inlineblock button" id="selectavatar"><?php p($l->t('Select new from files')); ?></div>