diff --git a/public/src/client/account/edit.js b/public/src/client/account/edit.js
index b3c8c0af6a..4b2e0ff93d 100644
--- a/public/src/client/account/edit.js
+++ b/public/src/client/account/edit.js
@@ -203,7 +203,7 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'],
 				if (!url) {
 					return;
 				}
-				socket.emit('user.uploadProfileImageFromUrl', url, function(err, imageUrlOnServer) {
+				socket.emit('user.uploadProfileImageFromUrl', {url: url, uid: ajaxify.variables.get('theirid')}, function(err, imageUrlOnServer) {
 					if (err) {
 						return app.alertError(err.message);
 					}
@@ -300,7 +300,7 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'],
 			} else {
 				if (!passwordsmatch) {
 					app.alertError('[[user:change_password_error_match]]');
-				} 
+				}
 
 				if (!passwordvalid) {
 					app.alertError('[[user:change_password_error]]');
diff --git a/src/controllers/accounts.js b/src/controllers/accounts.js
index 3f5d23653a..78629b50cc 100644
--- a/src/controllers/accounts.js
+++ b/src/controllers/accounts.js
@@ -3,8 +3,6 @@
 var accountsController = {};
 
 var fs = require('fs'),
-	path = require('path'),
-	winston = require('winston'),
 	nconf = require('nconf'),
 	async = require('async'),
 	validator = require('validator'),
@@ -20,8 +18,7 @@ var fs = require('fs'),
 	meta = require('../meta'),
 	plugins = require('../plugins'),
 	languages = require('../languages'),
-	image = require('../image'),
-	file = require('../file'),
+
 	helpers = require('./helpers');
 
 function getUserDataByUserSlug(userslug, callerUID, callback) {
@@ -369,32 +366,10 @@ accountsController.accountSettings = function(req, res, next) {
 
 accountsController.uploadPicture = function (req, res, next) {
 	var userPhoto = req.files.files[0];
-	var uploadSize = parseInt(meta.config.maximumProfileImageSize, 10) || 256;
-	var extension = path.extname(userPhoto.name);
+
 	var updateUid = req.uid;
-	var imageDimension = parseInt(meta.config.profileImageDimension, 10) || 128;
-	var convertToPNG = parseInt(meta.config['profile:convertProfileImageToPNG'], 10) === 1;
 
 	async.waterfall([
-		function(next) {
-			next(userPhoto.size > uploadSize * 1024 ? new Error('[[error:file-too-big, ' + uploadSize + ']]') : null);
-		},
-		function(next) {
-			next(!extension ? new Error('[[error:invalid-image-extension]]') : null);
-		},
-		function(next) {
-			file.isFileTypeAllowed(userPhoto.path, ['png', 'jpeg', 'jpg', 'gif'], next);
-		},
-		function(next) {
-			image.resizeImage(userPhoto.path, extension, imageDimension, imageDimension, next);
-		},
-		function(next) {
-			if (convertToPNG) {
-				image.convertImageToPng(userPhoto.path, extension, next);
-			} else {
-				next();
-			}
-		},
 		function(next) {
 			user.getUidByUserslug(req.params.userslug, next);
 		},
@@ -414,50 +389,17 @@ accountsController.uploadPicture = function (req, res, next) {
 				updateUid = uid;
 				next();
 			});
+		},
+		function(next) {
+			user.uploadPicture(updateUid, userPhoto, next);
 		}
-	], function(err, result) {
-
-		function done(err, image) {
-			fs.unlink(userPhoto.path);
-			if (err) {
-				return res.json({error: err.message});
-			}
-
-			user.setUserFields(updateUid, {uploadedpicture: image.url, picture: image.url});
-
-			res.json([{name: userPhoto.name, url: image.url.startsWith('http') ? image.url : nconf.get('relative_path') + image.url}]);
-		}
-
+	], function(err, image) {
+		fs.unlink(userPhoto.path);
 		if (err) {
-			fs.unlink(userPhoto.path);
 			return next(err);
 		}
 
-		if (plugins.hasListeners('filter:uploadImage')) {
-			return plugins.fireHook('filter:uploadImage', {image: userPhoto, uid: updateUid}, done);
-		}
-
-		var filename = updateUid + '-profileimg' + (convertToPNG ? '.png' : extension);
-
-		user.getUserField(updateUid, 'uploadedpicture', function (err, oldpicture) {
-			if (err) {
-				return next(err);
-			}
-			if (!oldpicture) {
-				file.saveFileToLocal(filename, 'profile', userPhoto.path, done);
-				return;
-			}
-
-			var absolutePath = path.join(nconf.get('base_dir'), nconf.get('upload_path'), 'profile', path.basename(oldpicture));
-
-			fs.unlink(absolutePath, function (err) {
-				if (err) {
-					winston.error(err);
-				}
-
-				file.saveFileToLocal(filename, 'profile', userPhoto.path, done);
-			});
-		});
+		res.json([{name: userPhoto.name, url: image.url.startsWith('http') ? image.url : nconf.get('relative_path') + image.url}]);
 	});
 };
 
diff --git a/src/socket.io/user.js b/src/socket.io/user.js
index 3cd15c9b92..e395418142 100644
--- a/src/socket.io/user.js
+++ b/src/socket.io/user.js
@@ -263,19 +263,27 @@ SocketUser.changePicture = function(socket, data, callback) {
 	});
 };
 
-SocketUser.uploadProfileImageFromUrl = function(socket, url, callback) {
-	if (!socket.uid || !url) {
+SocketUser.uploadProfileImageFromUrl = function(socket, data, callback) {
+	function upload() {
+		user.uploadFromUrl(data.uid, data.url, function(err, uploadedImage) {
+			callback(err, uploadedImage ? uploadedImage.url : null);
+		});
+	}
+
+	if (!socket.uid || !data.url || !data.uid) {
 		return;
 	}
 
-	plugins.fireHook('filter:uploadImage', {image: {url: url}, uid: socket.uid}, function(err, data) {
-		if (err) {
-			return callback(err);
+	if (parseInt(socket.uid, 10) === parseInt(data.uid, 10)) {
+		return upload();
+	}
+
+	user.isAdministrator(socket.uid, function(err, isAdmin) {
+		if (err || !isAdmin) {
+			return callback(err || new Error('[[error:not-allowed]]'));
 		}
 
-		user.setUserFields(socket.uid, {uploadedpicture: data.url, picture: data.url}, function(err) {
-			callback(err, data.url);
-		});
+		upload();
 	});
 };
 
diff --git a/src/user.js b/src/user.js
index 281000ccc0..7ad9810554 100644
--- a/src/user.js
+++ b/src/user.js
@@ -29,6 +29,7 @@ var	async = require('async'),
 	require('./user/settings')(User);
 	require('./user/search')(User);
 	require('./user/jobs')(User);
+	require('./user/picture')(User);
 
 	User.getUserField = function(uid, field, callback) {
 		User.getUserFields(uid, [field], function(err, user) {
diff --git a/src/user/picture.js b/src/user/picture.js
new file mode 100644
index 0000000000..d726773a55
--- /dev/null
+++ b/src/user/picture.js
@@ -0,0 +1,131 @@
+'use strict';
+
+var async = require('async'),
+	path = require('path'),
+	fs = require('fs'),
+	nconf = require('nconf'),
+	winston = require('winston'),
+	request = require('request'),
+	mime = require('mime'),
+
+	plugins = require('../plugins'),
+	file = require('../file'),
+	image = require('../image'),
+	meta = require('../meta');
+
+module.exports = function(User) {
+
+	User.uploadPicture = function (uid, picture, callback) {
+
+		var uploadSize = parseInt(meta.config.maximumProfileImageSize, 10) || 256;
+		var extension = path.extname(picture.name);
+		var updateUid = uid;
+		var imageDimension = parseInt(meta.config.profileImageDimension, 10) || 128;
+		var convertToPNG = parseInt(meta.config['profile:convertProfileImageToPNG'], 10) === 1;
+
+		async.waterfall([
+			function(next) {
+				next(picture.size > uploadSize * 1024 ? new Error('[[error:file-too-big, ' + uploadSize + ']]') : null);
+			},
+			function(next) {
+				next(!extension ? new Error('[[error:invalid-image-extension]]') : null);
+			},
+			function(next) {
+				file.isFileTypeAllowed(picture.path, ['png', 'jpeg', 'jpg', 'gif'], next);
+			},
+			function(next) {
+				image.resizeImage(picture.path, extension, imageDimension, imageDimension, next);
+			},
+			function(next) {
+				if (convertToPNG) {
+					image.convertImageToPng(picture.path, extension, next);
+				} else {
+					next();
+				}
+			}
+		], function(err, result) {
+
+			function done(err, image) {
+				if (err) {
+					return callback(err);
+				}
+
+				User.setUserFields(updateUid, {uploadedpicture: image.url, picture: image.url});
+
+				callback(null, image);
+			}
+
+			if (err) {
+				return callback(err);
+			}
+
+			if (plugins.hasListeners('filter:uploadImage')) {
+				return plugins.fireHook('filter:uploadImage', {image: picture, uid: updateUid}, done);
+			}
+
+			var filename = updateUid + '-profileimg' + (convertToPNG ? '.png' : extension);
+
+			User.getUserField(updateUid, 'uploadedpicture', function (err, oldpicture) {
+				if (err) {
+					return callback(err);
+				}
+
+				if (!oldpicture) {
+					return file.saveFileToLocal(filename, 'profile', picture.path, done);
+				}
+
+				var absolutePath = path.join(nconf.get('base_dir'), nconf.get('upload_path'), 'profile', path.basename(oldpicture));
+
+				fs.unlink(absolutePath, function (err) {
+					if (err) {
+						winston.error(err);
+					}
+
+					file.saveFileToLocal(filename, 'profile', picture.path, done);
+				});
+			});
+		});
+	};
+
+	User.uploadFromUrl = function(uid, url, callback) {
+		var filename = 'uid:' + uid + ':tmp-image';
+		downloadFromUrl(url, filename, function(err, downloadedImage) {
+			if (err) {
+				return callback(err);
+			}
+
+			User.uploadPicture(uid, downloadedImage, function(err, image) {
+				fs.unlink(filename);
+				callback(err, image);
+			});
+		});
+	};
+
+	function downloadFromUrl(url, filename, callback) {
+		request.head(url, function(err, res, body) {
+			if (err) {
+				return callback(err);
+			}
+			var uploadSize = parseInt(meta.config.maximumProfileImageSize, 10) || 256;
+			var size = res.headers['content-length'];
+			var type = res.headers['content-type'];
+			var extension = mime.extension(type);
+
+			if (size > uploadSize * 1024) {
+				return callback(new Error('[[error:file-too-big, ' + uploadSize + ']]'));
+			}
+
+			request.get(url)
+				.on('error', function(err) {
+					winston.error(err);
+				})
+				.pipe(fs.createWriteStream(filename))
+				.on('close', function(err) {
+					if (err) {
+						return callback(err);
+					}
+					callback(null, {path: filename, size: size, type: type, name: filename + '.' + extension});
+				});
+		});
+	}
+};
\ No newline at end of file