Compare commits
233 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d7910f424 | |||
| 10d97c8140 | |||
| d57b870f3e | |||
| 44119e2051 | |||
| 8596226787 | |||
| 85382a5140 | |||
| 4decc86598 | |||
| 6fb5095197 | |||
| 79a7ee656e | |||
| 71679c8921 | |||
| 44dbdd9632 | |||
| 97231e64ba | |||
| cc785e2f1b | |||
| 5daf512405 | |||
| d6bc7757ab | |||
| 94db6c64a9 | |||
| ef159cd863 | |||
| 263da2463a | |||
| 15a485cbdb | |||
| 440828f0f1 | |||
| 5d53e0d5ce | |||
| 07c0cda12d | |||
| 2f08d24743 | |||
| 1b4f249157 | |||
| 410d798e98 | |||
| 34937479a8 | |||
| 41bfd5e1f3 | |||
| e56de16876 | |||
| f385d32331 | |||
| 3c5470358e | |||
| 05db74e7db | |||
| 470e93e4df | |||
| f359c2a716 | |||
| 88516dd8ae | |||
| 3e20032a32 | |||
| f849dd0693 | |||
| a566684564 | |||
| dceb2b7c32 | |||
| 270d1199a6 | |||
| 89bdb78f0a | |||
| 756424b6dd | |||
| e9c710e4fc | |||
| 8f2209680a | |||
| 95cee0eb5d | |||
| ea54fe98f7 | |||
| 939470d771 | |||
| 84754d3d20 | |||
| dd694b5fb4 | |||
| e44e357381 | |||
| ced12cbf76 | |||
| 2854ee56e9 | |||
| fd71023dd6 | |||
| 124e4ba53c | |||
| 85a0ba28d7 | |||
| 54352fe566 | |||
| 326496ff80 | |||
| 6188f07c95 | |||
| 4fa86c4dc3 | |||
| 39a54f5abf | |||
| 52dd0274d3 | |||
| 3ed0960edb | |||
| a12d3834d4 | |||
| 780f2293d6 | |||
| f9c5a0fd4d | |||
| a575e86b88 | |||
| 8f501a928a | |||
| ad762980bb | |||
| b019a57894 | |||
| 8724fe4b11 | |||
| b1b1fe72e8 | |||
| bfff3d3f9b | |||
| cb0666e235 | |||
| cb55229c1e | |||
| 9b1f2462bf | |||
| 3fab16603a | |||
| 66343f977f | |||
| bcb9cf3c06 | |||
| 55d8057b7f | |||
| 5e19854d47 | |||
| 781b579074 | |||
| 77c07615f8 | |||
| 743d01d4a6 | |||
| 12cd67b8d9 | |||
| 6641af720d | |||
| 2d110f25f7 | |||
| 39b6bb8a18 | |||
| 7270be85a4 | |||
| 560d87e26a | |||
| b3245ac327 | |||
| a1a44a3582 | |||
| da5c30efa2 | |||
| 1ffcd33817 | |||
| 9e0a6d86ba | |||
| 501bb0afd6 | |||
| 5f7d053c3a | |||
| 56c8976bac | |||
| 72d6c3246f | |||
| 166edb2cc1 | |||
| 8b31081c52 | |||
| 4619c662cc | |||
| e8a0ceacaf | |||
| 4802f21a9e | |||
| 9c88857364 | |||
| b71cc08ce1 | |||
| 0741598f58 | |||
| e29b0d099f | |||
| 3fde72ea5c | |||
| d022b89063 | |||
| 5b8155a578 | |||
| b7a50a4f6f | |||
| a606131a6a | |||
| 6b413b0d0f | |||
| 693c535a94 | |||
| a25cf8ba83 | |||
| a15a99b304 | |||
| 6e8f970999 | |||
| bbe0cf376f | |||
| f660247b47 | |||
| 1d2d2cf261 | |||
| 50d5ca71d0 | |||
| 189e8ab1e0 | |||
| dbbbfd4b2b | |||
| ece4a843c0 | |||
| d62f138153 | |||
| 7fc1276ac7 | |||
| ba2bba0f66 | |||
| ab7561b2b6 | |||
| 3740ce2854 | |||
| bfd53c5bd7 | |||
| 9691d56713 | |||
| 92829e8f94 | |||
| c518f35e83 | |||
| 3e57a44829 | |||
| 5cf1fd8aa9 | |||
| c64f579518 | |||
| 054c168b32 | |||
| f599267459 | |||
| 3cd416b667 | |||
| 3139636906 | |||
| 0d349e331e | |||
| 51968cfd53 | |||
| 21488bdd7e | |||
| 3945f9cdb1 | |||
| de1b95c8e7 | |||
| 725e733178 | |||
| d226ed697e | |||
| 77b57fbbfe | |||
| 0dc3ffd29a | |||
| 10e45481be | |||
| bfb8436ca2 | |||
| edf3503779 | |||
| a98cfbe868 | |||
| 12ea922389 | |||
| db6fc916cf | |||
| 46e9bf5678 | |||
| c6177d2629 | |||
| 0399a88eb6 | |||
| 8f715e12a9 | |||
| 4b39ce5134 | |||
| 53ae74200a | |||
| 9f570345a5 | |||
| 5d866295d8 | |||
| 9eae10b94a | |||
| ca58aa1644 | |||
| 3b9c10dcf6 | |||
| 28e0fa7d1d | |||
| 3833f2315a | |||
| e65c3ef9c9 | |||
| 552aee93fa | |||
| 1791fbdc49 | |||
| c2e3999f76 | |||
| 677cec6e1c | |||
| 7435064cd3 | |||
| 0c57d94467 | |||
| 366aeb7228 | |||
| 296884b24a | |||
| 2e5ce9f4ec | |||
| cc67ae9dbb | |||
| 71d33fa065 | |||
| db3b0b63da | |||
| 5433932bd4 | |||
| f5c6a22f17 | |||
| f47c64cec6 | |||
| 7feb0f737b | |||
| 5271c1a9ad | |||
| ef3e5899c6 | |||
| badd2908b7 | |||
| 3f3b92a149 | |||
| c3646f5554 | |||
| a97d73d616 | |||
| 50684a5a34 | |||
| f06467b95b | |||
| 9faae4b71c | |||
| e49d5a5f9a | |||
| ed10a5de5b | |||
| e8b84145e8 | |||
| 38f8734014 | |||
| a10564e214 | |||
| ecef3b6b98 | |||
| e65ea6a8b7 | |||
| 7139de2a6e | |||
| b5403de5e5 | |||
| 0966f1358b | |||
| a0ac64cbd6 | |||
| b03b6dfb99 | |||
| c11f9833ac | |||
| 9ee34ef6b3 | |||
| df7e519159 | |||
| 5e60812ad4 | |||
| 1263604703 | |||
| 5904db580f | |||
| 1960067926 | |||
| 33bd9ecd9d | |||
| 7f7c1fcccf | |||
| 34fdd0e839 | |||
| 9de4eccd99 | |||
| a0847dc852 | |||
| 87a3145ba1 | |||
| 85e236d798 | |||
| cb4c3d7a9e | |||
| e55fc87ad3 | |||
| 5398dea0df | |||
| e0eb6bbd28 | |||
| 822b323f8e | |||
| c1f645cd5f | |||
| f1d9359acf | |||
| 550e774db2 | |||
| e23b06ec8c | |||
| 4f8b8a8a59 | |||
| c06d71e662 | |||
| cce43652f0 | |||
| 9f0a4c8edb | |||
| f571cfbf71 |
@@ -19,4 +19,8 @@ RewriteRule ^apps/contacts/carddav.php remote.php/carddav/ [QSA,L]
|
||||
RewriteRule ^apps/([^/]*)/(.*\.(css|php))$ index.php?app=$1&getfile=$2 [QSA,L]
|
||||
RewriteRule ^remote/(.*) remote.php [QSA,L]
|
||||
</IfModule>
|
||||
<IfModule mod_mime.c>
|
||||
AddType image/svg+xml svg svgz
|
||||
AddEncoding gzip svgz
|
||||
</IfModule>
|
||||
Options -Indexes
|
||||
|
||||
+10
-1
@@ -363,6 +363,7 @@ class MDB2_Driver_Manager_pgsql extends MDB2_Driver_Manager_Common
|
||||
return MDB2_OK;
|
||||
}
|
||||
|
||||
$unquoted_name = $name;
|
||||
$name = $db->quoteIdentifier($name, true);
|
||||
|
||||
if (!empty($changes['remove']) && is_array($changes['remove'])) {
|
||||
@@ -398,6 +399,7 @@ class MDB2_Driver_Manager_pgsql extends MDB2_Driver_Manager_Common
|
||||
|
||||
if (!empty($changes['change']) && is_array($changes['change'])) {
|
||||
foreach ($changes['change'] as $field_name => $field) {
|
||||
$unquoted_field_name = $field_name;
|
||||
$field_name = $db->quoteIdentifier($field_name, true);
|
||||
if (!empty($field['definition']['type'])) {
|
||||
$server_info = $db->getServerVersion();
|
||||
@@ -419,7 +421,14 @@ class MDB2_Driver_Manager_pgsql extends MDB2_Driver_Manager_Common
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
if (array_key_exists('default', $field['definition'])) {
|
||||
if (array_key_exists('autoincrement', $field['definition'])) {
|
||||
$query = "ALTER $field_name SET DEFAULT nextval(".$db->quote($unquoted_name.'_'.$unquoted_field_name.'_seq', 'text').")";
|
||||
$result = $db->exec("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
elseif (array_key_exists('default', $field['definition'])) {
|
||||
$query = "ALTER $field_name SET DEFAULT ".$db->quote($field['definition']['default'], $field['definition']['type']);
|
||||
$result = $db->exec("ALTER TABLE $name $query");
|
||||
if (PEAR::isError($result)) {
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* FullCalendar v1.5.3 Stylesheet
|
||||
* FullCalendar v1.5.4 Stylesheet
|
||||
*
|
||||
* Copyright (c) 2011 Adam Shaw
|
||||
* Dual licensed under the MIT and GPL licenses, located in
|
||||
* MIT-LICENSE.txt and GPL-LICENSE.txt respectively.
|
||||
*
|
||||
* Date: Mon Feb 6 22:40:40 2012 -0800
|
||||
* Date: Tue Sep 4 23:38:33 2012 -0700
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* FullCalendar v1.5.3 Print Stylesheet
|
||||
* FullCalendar v1.5.4 Print Stylesheet
|
||||
*
|
||||
* Include this stylesheet on your page to get a more printer-friendly calendar.
|
||||
* When including this stylesheet, use the media='print' attribute of the <link> tag.
|
||||
@@ -9,7 +9,7 @@
|
||||
* Dual licensed under the MIT and GPL licenses, located in
|
||||
* MIT-LICENSE.txt and GPL-LICENSE.txt respectively.
|
||||
*
|
||||
* Date: Mon Feb 6 22:40:40 2012 -0800
|
||||
* Date: Tue Sep 4 23:38:33 2012 -0700
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+17
-21
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @preserve
|
||||
* FullCalendar v1.5.3
|
||||
* FullCalendar v1.5.4
|
||||
* http://arshaw.com/fullcalendar/
|
||||
*
|
||||
* Use fullcalendar.css for basic styling.
|
||||
@@ -11,7 +11,7 @@
|
||||
* Dual licensed under the MIT and GPL licenses, located in
|
||||
* MIT-LICENSE.txt and GPL-LICENSE.txt respectively.
|
||||
*
|
||||
* Date: Mon Feb 6 22:40:40 2012 -0800
|
||||
* Date: Tue Sep 4 23:38:33 2012 -0700
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -111,7 +111,7 @@ var rtlDefaults = {
|
||||
|
||||
|
||||
|
||||
var fc = $.fullCalendar = { version: "1.5.3" };
|
||||
var fc = $.fullCalendar = { version: "1.5.4" };
|
||||
var fcViews = fc.views = {};
|
||||
|
||||
|
||||
@@ -1658,7 +1658,7 @@ function sliceSegs(events, visEventEnds, start, end) {
|
||||
msLength: segEnd - segStart
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return segs.sort(segCmp);
|
||||
}
|
||||
|
||||
@@ -1742,29 +1742,26 @@ function setOuterHeight(element, height, includeMargins) {
|
||||
}
|
||||
|
||||
|
||||
// TODO: curCSS has been deprecated (jQuery 1.4.3 - 10/16/2010)
|
||||
|
||||
|
||||
function hsides(element, includeMargins) {
|
||||
return hpadding(element) + hborders(element) + (includeMargins ? hmargins(element) : 0);
|
||||
}
|
||||
|
||||
|
||||
function hpadding(element) {
|
||||
return (parseFloat($.curCSS(element[0], 'paddingLeft', true)) || 0) +
|
||||
(parseFloat($.curCSS(element[0], 'paddingRight', true)) || 0);
|
||||
return (parseFloat($.css(element[0], 'paddingLeft', true)) || 0) +
|
||||
(parseFloat($.css(element[0], 'paddingRight', true)) || 0);
|
||||
}
|
||||
|
||||
|
||||
function hmargins(element) {
|
||||
return (parseFloat($.curCSS(element[0], 'marginLeft', true)) || 0) +
|
||||
(parseFloat($.curCSS(element[0], 'marginRight', true)) || 0);
|
||||
return (parseFloat($.css(element[0], 'marginLeft', true)) || 0) +
|
||||
(parseFloat($.css(element[0], 'marginRight', true)) || 0);
|
||||
}
|
||||
|
||||
|
||||
function hborders(element) {
|
||||
return (parseFloat($.curCSS(element[0], 'borderLeftWidth', true)) || 0) +
|
||||
(parseFloat($.curCSS(element[0], 'borderRightWidth', true)) || 0);
|
||||
return (parseFloat($.css(element[0], 'borderLeftWidth', true)) || 0) +
|
||||
(parseFloat($.css(element[0], 'borderRightWidth', true)) || 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1774,20 +1771,20 @@ function vsides(element, includeMargins) {
|
||||
|
||||
|
||||
function vpadding(element) {
|
||||
return (parseFloat($.curCSS(element[0], 'paddingTop', true)) || 0) +
|
||||
(parseFloat($.curCSS(element[0], 'paddingBottom', true)) || 0);
|
||||
return (parseFloat($.css(element[0], 'paddingTop', true)) || 0) +
|
||||
(parseFloat($.css(element[0], 'paddingBottom', true)) || 0);
|
||||
}
|
||||
|
||||
|
||||
function vmargins(element) {
|
||||
return (parseFloat($.curCSS(element[0], 'marginTop', true)) || 0) +
|
||||
(parseFloat($.curCSS(element[0], 'marginBottom', true)) || 0);
|
||||
return (parseFloat($.css(element[0], 'marginTop', true)) || 0) +
|
||||
(parseFloat($.css(element[0], 'marginBottom', true)) || 0);
|
||||
}
|
||||
|
||||
|
||||
function vborders(element) {
|
||||
return (parseFloat($.curCSS(element[0], 'borderTopWidth', true)) || 0) +
|
||||
(parseFloat($.curCSS(element[0], 'borderBottomWidth', true)) || 0);
|
||||
return (parseFloat($.css(element[0], 'borderTopWidth', true)) || 0) +
|
||||
(parseFloat($.css(element[0], 'borderBottomWidth', true)) || 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1956,7 +1953,6 @@ function firstDefined() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
fcViews.month = MonthView;
|
||||
|
||||
function MonthView(element, calendar) {
|
||||
@@ -4662,7 +4658,7 @@ function DayEventRenderer() {
|
||||
"</span>";
|
||||
}
|
||||
html +=
|
||||
"<span class='fc-event-title'>" + event.title + "</span>" +
|
||||
"<span class='fc-event-title'>" + htmlEscape(event.title) + "</span>" +
|
||||
"</div>";
|
||||
if (seg.isEnd && isEventResizable(event)) {
|
||||
html +=
|
||||
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
|
||||
FullCalendar v1.5.3
|
||||
FullCalendar v1.5.4
|
||||
http://arshaw.com/fullcalendar/
|
||||
|
||||
Use fullcalendar.css for basic styling.
|
||||
@@ -11,7 +11,7 @@
|
||||
Dual licensed under the MIT and GPL licenses, located in
|
||||
MIT-LICENSE.txt and GPL-LICENSE.txt respectively.
|
||||
|
||||
Date: Mon Feb 6 22:40:40 2012 -0800
|
||||
Date: Tue Sep 4 23:38:33 2012 -0700
|
||||
|
||||
*/
|
||||
(function(m,ma){function wb(a){m.extend(true,Ya,a)}function Yb(a,b,e){function d(k){if(E){u();q();na();S(k)}else f()}function f(){B=b.theme?"ui":"fc";a.addClass("fc");b.isRTL&&a.addClass("fc-rtl");b.theme&&a.addClass("ui-widget");E=m("<div class='fc-content' style='position:relative'/>").prependTo(a);C=new Zb(X,b);(P=C.render())&&a.prepend(P);y(b.defaultView);m(window).resize(oa);t()||g()}function g(){setTimeout(function(){!n.start&&t()&&S()},0)}function l(){m(window).unbind("resize",oa);C.destroy();
|
||||
@@ -39,10 +39,10 @@ a[12])*1E3);lb(e,b)}else{e.setUTCFullYear(a[1],a[3]?a[3]-1:0,a[5]||1);e.setUTCHo
|
||||
10):0)}}function Oa(a,b,e){return ib(a,null,b,e)}function ib(a,b,e,d){d=d||Ya;var f=a,g=b,l,j=e.length,t,y,S,Q="";for(l=0;l<j;l++){t=e.charAt(l);if(t=="'")for(y=l+1;y<j;y++){if(e.charAt(y)=="'"){if(f){Q+=y==l+1?"'":e.substring(l+1,y);l=y}break}}else if(t=="(")for(y=l+1;y<j;y++){if(e.charAt(y)==")"){l=Oa(f,e.substring(l+1,y),d);if(parseInt(l.replace(/\D/,""),10))Q+=l;l=y;break}}else if(t=="[")for(y=l+1;y<j;y++){if(e.charAt(y)=="]"){t=e.substring(l+1,y);l=Oa(f,t,d);if(l!=Oa(g,t,d))Q+=l;l=y;break}}else if(t==
|
||||
"{"){f=b;g=a}else if(t=="}"){f=a;g=b}else{for(y=j;y>l;y--)if(S=dc[e.substring(l,y)]){if(f)Q+=S(f,d);l=y-1;break}if(y==l)if(f)Q+=t}}return Q}function Ua(a){return a.end?ec(a.end,a.allDay):ba(N(a.start),1)}function ec(a,b){a=N(a);return b||a.getHours()||a.getMinutes()?ba(a,1):Ka(a)}function fc(a,b){return(b.msLength-a.msLength)*100+(a.event.start-b.event.start)}function Cb(a,b){return a.end>b.start&&a.start<b.end}function nb(a,b,e,d){var f=[],g,l=a.length,j,t,y,S,Q;for(g=0;g<l;g++){j=a[g];t=j.start;
|
||||
y=b[g];if(y>e&&t<d){if(t<e){t=N(e);S=false}else{t=t;S=true}if(y>d){y=N(d);Q=false}else{y=y;Q=true}f.push({event:j,start:t,end:y,isStart:S,isEnd:Q,msLength:y-t})}}return f.sort(fc)}function ob(a){var b=[],e,d=a.length,f,g,l,j;for(e=0;e<d;e++){f=a[e];for(g=0;;){l=false;if(b[g])for(j=0;j<b[g].length;j++)if(Cb(b[g][j],f)){l=true;break}if(l)g++;else break}if(b[g])b[g].push(f);else b[g]=[f]}return b}function Db(a,b,e){a.unbind("mouseover").mouseover(function(d){for(var f=d.target,g;f!=this;){g=f;f=f.parentNode}if((f=
|
||||
g._fci)!==ma){g._fci=ma;g=b[f];e(g.event,g.element,g);m(d.target).trigger(d)}d.stopPropagation()})}function Va(a,b,e){for(var d=0,f;d<a.length;d++){f=m(a[d]);f.width(Math.max(0,b-pb(f,e)))}}function Eb(a,b,e){for(var d=0,f;d<a.length;d++){f=m(a[d]);f.height(Math.max(0,b-Sa(f,e)))}}function pb(a,b){return gc(a)+hc(a)+(b?ic(a):0)}function gc(a){return(parseFloat(m.curCSS(a[0],"paddingLeft",true))||0)+(parseFloat(m.curCSS(a[0],"paddingRight",true))||0)}function ic(a){return(parseFloat(m.curCSS(a[0],
|
||||
"marginLeft",true))||0)+(parseFloat(m.curCSS(a[0],"marginRight",true))||0)}function hc(a){return(parseFloat(m.curCSS(a[0],"borderLeftWidth",true))||0)+(parseFloat(m.curCSS(a[0],"borderRightWidth",true))||0)}function Sa(a,b){return jc(a)+kc(a)+(b?Fb(a):0)}function jc(a){return(parseFloat(m.curCSS(a[0],"paddingTop",true))||0)+(parseFloat(m.curCSS(a[0],"paddingBottom",true))||0)}function Fb(a){return(parseFloat(m.curCSS(a[0],"marginTop",true))||0)+(parseFloat(m.curCSS(a[0],"marginBottom",true))||0)}
|
||||
function kc(a){return(parseFloat(m.curCSS(a[0],"borderTopWidth",true))||0)+(parseFloat(m.curCSS(a[0],"borderBottomWidth",true))||0)}function Za(a,b){b=typeof b=="number"?b+"px":b;a.each(function(e,d){d.style.cssText+=";min-height:"+b+";_height:"+b})}function xb(){}function Gb(a,b){return a-b}function Hb(a){return Math.max.apply(Math,a)}function Pa(a){return(a<10?"0":"")+a}function jb(a,b){if(a[b]!==ma)return a[b];b=b.split(/(?=[A-Z])/);for(var e=b.length-1,d;e>=0;e--){d=a[b[e].toLowerCase()];if(d!==
|
||||
ma)return d}return a[""]}function Qa(a){return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/'/g,"'").replace(/"/g,""").replace(/\n/g,"<br />")}function Ib(a){return a.id+"/"+a.className+"/"+a.style.cssText.replace(/(^|;)\s*(top|left|width|height)\s*:[^;]*/ig,"")}function qb(a){a.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})}function ab(a){a.children().removeClass("fc-first fc-last").filter(":first-child").addClass("fc-first").end().filter(":last-child").addClass("fc-last")}
|
||||
g._fci)!==ma){g._fci=ma;g=b[f];e(g.event,g.element,g);m(d.target).trigger(d)}d.stopPropagation()})}function Va(a,b,e){for(var d=0,f;d<a.length;d++){f=m(a[d]);f.width(Math.max(0,b-pb(f,e)))}}function Eb(a,b,e){for(var d=0,f;d<a.length;d++){f=m(a[d]);f.height(Math.max(0,b-Sa(f,e)))}}function pb(a,b){return gc(a)+hc(a)+(b?ic(a):0)}function gc(a){return(parseFloat(m.css(a[0],"paddingLeft",true))||0)+(parseFloat(m.css(a[0],"paddingRight",true))||0)}function ic(a){return(parseFloat(m.css(a[0],"marginLeft",
|
||||
true))||0)+(parseFloat(m.css(a[0],"marginRight",true))||0)}function hc(a){return(parseFloat(m.css(a[0],"borderLeftWidth",true))||0)+(parseFloat(m.css(a[0],"borderRightWidth",true))||0)}function Sa(a,b){return jc(a)+kc(a)+(b?Fb(a):0)}function jc(a){return(parseFloat(m.css(a[0],"paddingTop",true))||0)+(parseFloat(m.css(a[0],"paddingBottom",true))||0)}function Fb(a){return(parseFloat(m.css(a[0],"marginTop",true))||0)+(parseFloat(m.css(a[0],"marginBottom",true))||0)}function kc(a){return(parseFloat(m.css(a[0],
|
||||
"borderTopWidth",true))||0)+(parseFloat(m.css(a[0],"borderBottomWidth",true))||0)}function Za(a,b){b=typeof b=="number"?b+"px":b;a.each(function(e,d){d.style.cssText+=";min-height:"+b+";_height:"+b})}function xb(){}function Gb(a,b){return a-b}function Hb(a){return Math.max.apply(Math,a)}function Pa(a){return(a<10?"0":"")+a}function jb(a,b){if(a[b]!==ma)return a[b];b=b.split(/(?=[A-Z])/);for(var e=b.length-1,d;e>=0;e--){d=a[b[e].toLowerCase()];if(d!==ma)return d}return a[""]}function Qa(a){return a.replace(/&/g,
|
||||
"&").replace(/</g,"<").replace(/>/g,">").replace(/'/g,"'").replace(/"/g,""").replace(/\n/g,"<br />")}function Ib(a){return a.id+"/"+a.className+"/"+a.style.cssText.replace(/(^|;)\s*(top|left|width|height)\s*:[^;]*/ig,"")}function qb(a){a.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})}function ab(a){a.children().removeClass("fc-first fc-last").filter(":first-child").addClass("fc-first").end().filter(":last-child").addClass("fc-last")}
|
||||
function rb(a,b){a.each(function(e,d){d.className=d.className.replace(/^fc-\w*/,"fc-"+lc[b.getDay()])})}function Jb(a,b){var e=a.source||{},d=a.color,f=e.color,g=b("eventColor"),l=a.backgroundColor||d||e.backgroundColor||f||b("eventBackgroundColor")||g;d=a.borderColor||d||e.borderColor||f||b("eventBorderColor")||g;a=a.textColor||e.textColor||b("eventTextColor");b=[];l&&b.push("background-color:"+l);d&&b.push("border-color:"+d);a&&b.push("color:"+a);return b.join(";")}function $a(a,b,e){if(m.isFunction(a))a=
|
||||
[a];if(a){var d,f;for(d=0;d<a.length;d++)f=a[d].apply(b,e)||f;return f}}function Ta(){for(var a=0;a<arguments.length;a++)if(arguments[a]!==ma)return arguments[a]}function mc(a,b){function e(j,t){if(t){hb(j,t);j.setDate(1)}j=N(j,true);j.setDate(1);t=hb(N(j),1);var y=N(j),S=N(t),Q=f("firstDay"),q=f("weekends")?0:1;if(q){Fa(y);Fa(S,-1,true)}ba(y,-((y.getDay()-Math.max(Q,q)+7)%7));ba(S,(7-S.getDay()+Math.max(Q,q))%7);Q=Math.round((S-y)/(Ab*7));if(f("weekMode")=="fixed"){ba(S,(6-Q)*7);Q=6}d.title=l(j,
|
||||
f("titleFormat"));d.start=j;d.end=t;d.visStart=y;d.visEnd=S;g(6,Q,q?5:7,true)}var d=this;d.render=e;sb.call(d,a,b,"month");var f=d.opt,g=d.renderBasic,l=b.formatDate}function nc(a,b){function e(j,t){t&&ba(j,t*7);j=ba(N(j),-((j.getDay()-f("firstDay")+7)%7));t=ba(N(j),7);var y=N(j),S=N(t),Q=f("weekends");if(!Q){Fa(y);Fa(S,-1,true)}d.title=l(y,ba(N(S),-1),f("titleFormat"));d.start=j;d.end=t;d.visStart=y;d.visEnd=S;g(1,1,Q?7:5,false)}var d=this;d.render=e;sb.call(d,a,b,"basicWeek");var f=d.opt,g=d.renderBasic,
|
||||
@@ -106,7 +106,7 @@ t,y=-1,S=-1;for(t=0;t<l;t++)if(g>=e[t][0]&&g<e[t][1]){y=t;break}for(t=0;t<j;t++)
|
||||
g=l=null;a.build();b(t);d=y||"mousemove";m(document).bind(d,b)};e.stop=function(){m(document).unbind(d,b);return l}}function xc(a){if(a.pageX===ma){a.pageX=a.originalEvent.pageX;a.pageY=a.originalEvent.pageY}}function Pb(a){function b(l){return d[l]=d[l]||a(l)}var e=this,d={},f={},g={};e.left=function(l){return f[l]=f[l]===ma?b(l).position().left:f[l]};e.right=function(l){return g[l]=g[l]===ma?e.left(l)+b(l).width():g[l]};e.clear=function(){d={};f={};g={}}}var Ya={defaultView:"month",aspectRatio:1.35,
|
||||
header:{left:"title",center:"",right:"today prev,next"},weekends:true,allDayDefault:true,ignoreTimezone:true,lazyFetching:true,startParam:"start",endParam:"end",titleFormat:{month:"MMMM yyyy",week:"MMM d[ yyyy]{ '—'[ MMM] d yyyy}",day:"dddd, MMM d, yyyy"},columnFormat:{month:"ddd",week:"ddd M/d",day:"dddd M/d"},timeFormat:{"":"h(:mm)t"},isRTL:false,firstDay:0,monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan",
|
||||
"Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],buttonText:{prev:" ◄ ",next:" ► ",prevYear:" << ",nextYear:" >> ",today:"today",month:"month",week:"week",day:"day"},theme:false,buttonIcons:{prev:"circle-triangle-w",next:"circle-triangle-e"},unselectAuto:true,dropAccept:"*"},yc=
|
||||
{header:{left:"next,prev today",center:"",right:"title"},buttonText:{prev:" ► ",next:" ◄ ",prevYear:" >> ",nextYear:" << "},buttonIcons:{prev:"circle-triangle-e",next:"circle-triangle-w"}},Aa=m.fullCalendar={version:"1.5.3"},Ja=Aa.views={};m.fn.fullCalendar=function(a){if(typeof a=="string"){var b=Array.prototype.slice.call(arguments,1),e;this.each(function(){var f=m.data(this,"fullCalendar");if(f&&m.isFunction(f[a])){f=f[a].apply(f,
|
||||
{header:{left:"next,prev today",center:"",right:"title"},buttonText:{prev:" ► ",next:" ◄ ",prevYear:" >> ",nextYear:" << "},buttonIcons:{prev:"circle-triangle-e",next:"circle-triangle-w"}},Aa=m.fullCalendar={version:"1.5.4"},Ja=Aa.views={};m.fn.fullCalendar=function(a){if(typeof a=="string"){var b=Array.prototype.slice.call(arguments,1),e;this.each(function(){var f=m.data(this,"fullCalendar");if(f&&m.isFunction(f[a])){f=f[a].apply(f,
|
||||
b);if(e===ma)e=f;a=="destroy"&&m.removeData(this,"fullCalendar")}});if(e!==ma)return e;return this}var d=a.eventSources||[];delete a.eventSources;if(a.events){d.push(a.events);delete a.events}a=m.extend(true,{},Ya,a.isRTL||a.isRTL===ma&&Ya.isRTL?yc:{},a);this.each(function(f,g){f=m(g);g=new Yb(f,a,d);f.data("fullCalendar",g);g.render()});return this};Aa.sourceNormalizers=[];Aa.sourceFetchers=[];var ac={dataType:"json",cache:false},bc=1;Aa.addDays=ba;Aa.cloneDate=N;Aa.parseDate=kb;Aa.parseISO8601=
|
||||
Bb;Aa.parseTime=mb;Aa.formatDate=Oa;Aa.formatDates=ib;var lc=["sun","mon","tue","wed","thu","fri","sat"],Ab=864E5,cc=36E5,wc=6E4,dc={s:function(a){return a.getSeconds()},ss:function(a){return Pa(a.getSeconds())},m:function(a){return a.getMinutes()},mm:function(a){return Pa(a.getMinutes())},h:function(a){return a.getHours()%12||12},hh:function(a){return Pa(a.getHours()%12||12)},H:function(a){return a.getHours()},HH:function(a){return Pa(a.getHours())},d:function(a){return a.getDate()},dd:function(a){return Pa(a.getDate())},
|
||||
ddd:function(a,b){return b.dayNamesShort[a.getDay()]},dddd:function(a,b){return b.dayNames[a.getDay()]},M:function(a){return a.getMonth()+1},MM:function(a){return Pa(a.getMonth()+1)},MMM:function(a,b){return b.monthNamesShort[a.getMonth()]},MMMM:function(a,b){return b.monthNames[a.getMonth()]},yy:function(a){return(a.getFullYear()+"").substring(2)},yyyy:function(a){return a.getFullYear()},t:function(a){return a.getHours()<12?"a":"p"},tt:function(a){return a.getHours()<12?"am":"pm"},T:function(a){return a.getHours()<
|
||||
|
||||
Vendored
+2
-2
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* FullCalendar v1.5.3 Google Calendar Plugin
|
||||
* FullCalendar v1.5.4 Google Calendar Plugin
|
||||
*
|
||||
* Copyright (c) 2011 Adam Shaw
|
||||
* Dual licensed under the MIT and GPL licenses, located in
|
||||
* MIT-LICENSE.txt and GPL-LICENSE.txt respectively.
|
||||
*
|
||||
* Date: Mon Feb 6 22:40:40 2012 -0800
|
||||
* Date: Tue Sep 4 23:38:33 2012 -0700
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+2
-2
@@ -2000,7 +2000,7 @@ class CF_Object
|
||||
// }
|
||||
|
||||
//use OC's mimetype detection for files
|
||||
if(is_file($handle)){
|
||||
if(@is_file($handle)){
|
||||
$this->content_type=OC_Helper::getMimeType($handle);
|
||||
}else{
|
||||
$this->content_type=OC_Helper::getStringMimeType($handle);
|
||||
@@ -2537,7 +2537,7 @@ class CF_Object
|
||||
}
|
||||
$md5 = hash_final($ctx, false);
|
||||
rewind($data);
|
||||
} elseif ((string)is_file($data)) {
|
||||
} elseif ((string)@is_file($data)) {
|
||||
$md5 = md5_file($data);
|
||||
} else {
|
||||
$md5 = md5($data);
|
||||
|
||||
Vendored
+12
@@ -229,6 +229,8 @@ class smb {
|
||||
}
|
||||
|
||||
function addstatcache ($url, $info) {
|
||||
$url = str_replace('//', '/', $url);
|
||||
$url = rtrim($url, '/');
|
||||
global $__smb_cache;
|
||||
$is_file = (strpos ($info['attr'],'D') === FALSE);
|
||||
$s = ($is_file) ? stat ('/etc/passwd') : stat ('/tmp');
|
||||
@@ -238,11 +240,15 @@ class smb {
|
||||
}
|
||||
|
||||
function getstatcache ($url) {
|
||||
$url = str_replace('//', '/', $url);
|
||||
$url = rtrim($url, '/');
|
||||
global $__smb_cache;
|
||||
return isset ($__smb_cache['stat'][$url]) ? $__smb_cache['stat'][$url] : FALSE;
|
||||
}
|
||||
|
||||
function clearstatcache ($url='') {
|
||||
$url = str_replace('//', '/', $url);
|
||||
$url = rtrim($url, '/');
|
||||
global $__smb_cache;
|
||||
if ($url == '') $__smb_cache['stat'] = array (); else unset ($__smb_cache['stat'][$url]);
|
||||
}
|
||||
@@ -358,16 +364,22 @@ class smb_stream_wrapper extends smb {
|
||||
# cache
|
||||
|
||||
function adddircache ($url, $content) {
|
||||
$url = str_replace('//', '/', $url);
|
||||
$url = rtrim($url, '/');
|
||||
global $__smb_cache;
|
||||
return $__smb_cache['dir'][$url] = $content;
|
||||
}
|
||||
|
||||
function getdircache ($url) {
|
||||
$url = str_replace('//', '/', $url);
|
||||
$url = rtrim($url, '/');
|
||||
global $__smb_cache;
|
||||
return isset ($__smb_cache['dir'][$url]) ? $__smb_cache['dir'][$url] : FALSE;
|
||||
}
|
||||
|
||||
function cleardircache ($url='') {
|
||||
$url = str_replace('//', '/', $url);
|
||||
$url = rtrim($url, '/');
|
||||
global $__smb_cache;
|
||||
if ($url == ''){
|
||||
$__smb_cache['dir'] = array ();
|
||||
|
||||
@@ -32,7 +32,7 @@ $htaccessWorking=(getenv('htaccessWorking')=='true');
|
||||
$upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize'));
|
||||
$post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size'));
|
||||
$maxUploadFilesize = OCP\Util::humanFileSize(min($upload_max_filesize, $post_max_size));
|
||||
if($_POST) {
|
||||
if($_POST && OC_Util::isCallRegistered()) {
|
||||
if(isset($_POST['maxUploadSize'])) {
|
||||
if(($setMaxSize = OC_Files::setUploadLimit(OCP\Util::computerFileSize($_POST['maxUploadSize']))) !== false) {
|
||||
$maxUploadFilesize = OCP\Util::humanFileSize($setMaxSize);
|
||||
|
||||
@@ -9,7 +9,7 @@ OCP\JSON::callCheck();
|
||||
// Get data
|
||||
$dir = stripslashes($_GET["dir"]);
|
||||
$file = stripslashes($_GET["file"]);
|
||||
$target = stripslashes($_GET["target"]);
|
||||
$target = stripslashes(urldecode($_GET["target"]));
|
||||
|
||||
|
||||
if(OC_Files::move($dir, $file, $target, $file)) {
|
||||
|
||||
@@ -65,6 +65,7 @@ if($source) {
|
||||
$target=$dir.'/'.$filename;
|
||||
$result=OC_Filesystem::file_put_contents($target, $sourceStream);
|
||||
if($result) {
|
||||
$target = OC_Filesystem::normalizePath($target);
|
||||
$meta = OC_FileCache::get($target);
|
||||
$mime=$meta['mimetype'];
|
||||
$id = OC_FileCache::getId($target);
|
||||
|
||||
@@ -48,10 +48,12 @@ if(strpos($dir, '..') === false) {
|
||||
$fileCount=count($files['name']);
|
||||
for($i=0;$i<$fileCount;$i++) {
|
||||
$target = OCP\Files::buildNotExistingFileName(stripslashes($dir), $files['name'][$i]);
|
||||
// $path needs to be normalized - this failed within drag'n'drop upload to a sub-folder
|
||||
$target = OC_Filesystem::normalizePath($target);
|
||||
if(is_uploaded_file($files['tmp_name'][$i]) and OC_Filesystem::fromTmpFile($files['tmp_name'][$i], $target)) {
|
||||
$meta = OC_FileCache::get($target);
|
||||
$id = OC_FileCache::getId($target);
|
||||
$result[]=array( "status" => "success", 'mime'=>$meta['mimetype'],'size'=>$meta['size'], 'id'=>$id, 'name'=>basename($target));
|
||||
$result[]=array( "status" => "success", 'mime'=>$meta['mimetype'], 'size'=>$meta['size'], 'id'=>$id, 'name'=>basename($target));
|
||||
}
|
||||
}
|
||||
OCP\JSON::encodedPrint($result);
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
* The final URL will look like http://.../remote.php/filesync/oc_chunked/path/to/file
|
||||
*/
|
||||
|
||||
// only need filesystem apps
|
||||
$RUNTIME_APPTYPES=array('filesystem','authentication');
|
||||
// load needed apps
|
||||
$RUNTIME_APPTYPES=array('filesystem','authentication','logging');
|
||||
OC_App::loadApps($RUNTIME_APPTYPES);
|
||||
if(!OC_User::isLoggedIn()) {
|
||||
if(!isset($_SERVER['PHP_AUTH_USER'])) {
|
||||
|
||||
@@ -22,10 +22,12 @@
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
// only need filesystem apps
|
||||
$RUNTIME_APPTYPES=array('filesystem','authentication');
|
||||
// load needed apps
|
||||
$RUNTIME_APPTYPES=array('filesystem','authentication','logging');
|
||||
OC_App::loadApps($RUNTIME_APPTYPES);
|
||||
|
||||
OC_Util::obEnd();
|
||||
|
||||
// Backends
|
||||
$authBackend = new OC_Connector_Sabre_Auth();
|
||||
$lockBackend = new OC_Connector_Sabre_Locks();
|
||||
|
||||
@@ -5,10 +5,10 @@ $installedVersion=OCP\Config::getAppValue('files', 'installed_version');
|
||||
if (version_compare($installedVersion, '1.1.6', '<')) {
|
||||
$query = OC_DB::prepare( "SELECT `propertyname`, `propertypath`, `userid` FROM `*PREFIX*properties`" );
|
||||
$result = $query->execute();
|
||||
$updateQuery = OC_DB::prepare('UPDATE `*PREFIX*properties` SET `propertyname` = ? WHERE `userid` = ? AND `propertypath` = ?');
|
||||
while( $row = $result->fetchRow()){
|
||||
if ( $row["propertyname"][0] != '{' ) {
|
||||
$query = OC_DB::prepare( 'UPDATE `*PREFIX*properties` SET `propertyname` = ? WHERE `userid` = ? AND `propertypath` = ?' );
|
||||
$query->execute( array( '{DAV:}' + $row["propertyname"], $row["userid"], $row["propertypath"] ));
|
||||
$updateQuery->execute(array('{DAV:}' + $row["propertyname"], $row["userid"], $row["propertypath"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,5 +44,5 @@ header('Content-Disposition: attachment; filename="'.basename($filename).'"');
|
||||
OCP\Response::disableCaching();
|
||||
header('Content-Length: '.OC_Filesystem::filesize($filename));
|
||||
|
||||
@ob_end_clean();
|
||||
OC_Util::obEnd();
|
||||
OC_Filesystem::readfile( $filename );
|
||||
|
||||
@@ -36,7 +36,7 @@ if(!isset($_SESSION['timezone'])) {
|
||||
}
|
||||
OCP\App::setActiveNavigationEntry( 'files_index' );
|
||||
// Load the files
|
||||
$dir = isset( $_GET['dir'] ) ? stripslashes($_GET['dir']) : '';
|
||||
$dir = isset( $_GET['dir'] ) ? urldecode(stripslashes($_GET['dir'])) : '';
|
||||
// Redirect if directory does not exist
|
||||
if(!OC_Filesystem::is_dir($dir.'/')) {
|
||||
header('Location: '.$_SERVER['SCRIPT_NAME'].'');
|
||||
|
||||
@@ -15,9 +15,9 @@ var FileList={
|
||||
extension=false;
|
||||
}
|
||||
html+='<td class="filename" style="background-image:url('+img+')"><input type="checkbox" />';
|
||||
html+='<a class="name" href="download.php?file='+$('#dir').val().replace(/</, '<').replace(/>/, '>')+'/'+name+'"><span class="nametext">'+basename;
|
||||
html+='<a class="name" href="download.php?file='+$('#dir').val().replace(/</, '<').replace(/>/, '>')+'/'+escapeHTML(name)+'"><span class="nametext">'+escapeHTML(basename);
|
||||
if(extension){
|
||||
html+='<span class="extension">'+extension+'</span>';
|
||||
html+='<span class="extension">'+escapeHTML(extension)+'</span>';
|
||||
}
|
||||
html+='</span></a></td>';
|
||||
if(size!='Pending'){
|
||||
@@ -137,7 +137,7 @@ var FileList={
|
||||
tr=$('tr').filterAttr('data-file',name);
|
||||
tr.data('renaming',true);
|
||||
td=tr.children('td.filename');
|
||||
input=$('<input class="filename"></input>').val(name);
|
||||
input=$('<input class="filename"/>').val(name);
|
||||
form=$('<form></form>');
|
||||
form.append(input);
|
||||
td.children('a.name').text('');
|
||||
@@ -147,6 +147,9 @@ var FileList={
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
var newname=input.val();
|
||||
if (Files.containsInvalidCharacters(newname)) {
|
||||
return false;
|
||||
}
|
||||
if (newname != name) {
|
||||
if (FileList.checkName(name, newname, false)) {
|
||||
newname = name;
|
||||
@@ -156,11 +159,11 @@ var FileList={
|
||||
OC.dialogs.alert(result.data.message, 'Error moving file');
|
||||
newname = name;
|
||||
}
|
||||
tr.data('renaming',false);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
tr.data('renaming',false);
|
||||
tr.attr('data-file', newname);
|
||||
var path = td.children('a.name').attr('href');
|
||||
td.children('a.name').attr('href', path.replace(encodeURIComponent(name), encodeURIComponent(newname)));
|
||||
@@ -189,9 +192,9 @@ var FileList={
|
||||
checkName:function(oldName, newName, isNewFile) {
|
||||
if (isNewFile || $('tr').filterAttr('data-file', newName).length > 0) {
|
||||
if (isNewFile) {
|
||||
$('#notification').html(newName+' '+t('files', 'already exists')+'<span class="replace">'+t('files', 'replace')+'</span><span class="suggest">'+t('files', 'suggest name')+'</span><span class="cancel">'+t('files', 'cancel')+'</span>');
|
||||
$('#notification').html(escapeHTML(newName)+' '+t('files', 'already exists')+'<span class="replace">'+t('files', 'replace')+'</span><span class="suggest">'+t('files', 'suggest name')+'</span><span class="cancel">'+t('files', 'cancel')+'</span>');
|
||||
} else {
|
||||
$('#notification').html(newName+' '+t('files', 'already exists')+'<span class="replace">'+t('files', 'replace')+'</span><span class="cancel">'+t('files', 'cancel')+'</span>');
|
||||
$('#notification').html(escapeHTML(newName)+' '+t('files', 'already exists')+'<span class="replace">'+t('files', 'replace')+'</span><span class="cancel">'+t('files', 'cancel')+'</span>');
|
||||
}
|
||||
$('#notification').data('oldName', oldName);
|
||||
$('#notification').data('newName', newName);
|
||||
@@ -272,9 +275,9 @@ var FileList={
|
||||
} else {
|
||||
// NOTE: Temporary fix to change the text to unshared for files in root of Shared folder
|
||||
if ($('#dir').val() == '/Shared') {
|
||||
$('#notification').html(t('files', 'unshared')+' '+files+'<span class="undo">'+t('files', 'undo')+'</span>');
|
||||
$('#notification').html(t('files', 'unshared')+' '+ escapeHTML(files) +'<span class="undo">'+t('files', 'undo')+'</span>');
|
||||
} else {
|
||||
$('#notification').html(t('files', 'deleted')+' '+files+'<span class="undo">'+t('files', 'undo')+'</span>');
|
||||
$('#notification').html(t('files', 'deleted')+' '+ escapeHTML(files)+'<span class="undo">'+t('files', 'undo')+'</span>');
|
||||
}
|
||||
$('#notification').fadeIn();
|
||||
}
|
||||
@@ -373,4 +376,7 @@ $(document).ready(function(){
|
||||
FileList.lastAction();
|
||||
}
|
||||
});
|
||||
$(window).unload(function (){
|
||||
$(window).trigger('beforeunload');
|
||||
});
|
||||
});
|
||||
|
||||
+39
-11
@@ -25,6 +25,18 @@ Files={
|
||||
delete uploadingFiles[index];
|
||||
});
|
||||
procesSelection();
|
||||
},
|
||||
containsInvalidCharacters:function (name) {
|
||||
var invalid_characters = ['\\', '/', '<', '>', ':', '"', '|', '?', '*'];
|
||||
for (var i = 0; i < invalid_characters.length; i++) {
|
||||
if (name.indexOf(invalid_characters[i]) != -1) {
|
||||
$('#notification').text(t('files', "Invalid name, '\\', '/', '<', '>', ':', '\"', '|', '?' and '*' are not allowed."));
|
||||
$('#notification').fadeIn();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
$('#notification').fadeOut();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
$(document).ready(function() {
|
||||
@@ -199,7 +211,7 @@ $(document).ready(function() {
|
||||
$(document).bind('drop dragover', function (e) {
|
||||
e.preventDefault(); // prevent browser from doing anything, if file isn't dropped in dropZone
|
||||
});
|
||||
|
||||
|
||||
if ( document.getElementById("data-upload-form") ) {
|
||||
$(function() {
|
||||
$('.file_upload_start').fileupload({
|
||||
@@ -233,7 +245,12 @@ $(document).ready(function() {
|
||||
}
|
||||
});
|
||||
}else{
|
||||
var date=new Date();
|
||||
var dropTarget = $(e.originalEvent.target).closest('tr');
|
||||
if(dropTarget && dropTarget.attr('data-type') === 'dir') { // drag&drop upload to folder
|
||||
var dirName = dropTarget.attr('data-file')
|
||||
}
|
||||
|
||||
var date=new Date();
|
||||
if(files){
|
||||
for(var i=0;i<files.length;i++){
|
||||
if(files[i].size>0){
|
||||
@@ -286,7 +303,10 @@ $(document).ready(function() {
|
||||
var jqXHR = $('.file_upload_start').fileupload('send', {files: files[i],
|
||||
formData: function(form) {
|
||||
var formArray = form.serializeArray();
|
||||
formArray[1]['value'] = dirName;
|
||||
// array index 0 contains the max files size
|
||||
// array index 1 contains the request token
|
||||
// array index 2 contains the directory
|
||||
formArray[2]['value'] = dirName;
|
||||
return formArray;
|
||||
}}).success(function(result, textStatus, jqXHR) {
|
||||
var response;
|
||||
@@ -296,7 +316,13 @@ $(document).ready(function() {
|
||||
$('#notification').fadeIn();
|
||||
}
|
||||
var file=response[0];
|
||||
// TODO: this doesn't work if the file name has been changed server side
|
||||
delete uploadingFiles[dirName][file.name];
|
||||
if ($.assocArraySize(uploadingFiles[dirName]) == 0) {
|
||||
delete uploadingFiles[dirName];
|
||||
}
|
||||
|
||||
var uploadtext = $('tr').filterAttr('data-type', 'dir').filterAttr('data-file', dirName).find('.uploadtext')
|
||||
var currentUploads = parseInt(uploadtext.attr('currentUploads'));
|
||||
currentUploads -= 1;
|
||||
uploadtext.attr('currentUploads', currentUploads);
|
||||
@@ -496,12 +522,14 @@ $(document).ready(function() {
|
||||
$(this).append(input);
|
||||
input.focus();
|
||||
input.change(function(){
|
||||
if(type != 'web' && $(this).val().indexOf('/')!=-1){
|
||||
$('#notification').text(t('files','Invalid name, \'/\' is not allowed.'));
|
||||
$('#notification').fadeIn();
|
||||
return;
|
||||
}
|
||||
var name = getUniqueName($(this).val());
|
||||
if (type != 'web' && Files.containsInvalidCharacters($(this).val())) {
|
||||
return;
|
||||
} else if( type == 'folder' && $('#dir').val() == '/' && $(this).val() == 'Shared') {
|
||||
$('#notification').text(t('files','Invalid folder name. Usage of "Shared" is reserved by Owncloud'));
|
||||
$('#notification').fadeIn();
|
||||
return;
|
||||
}
|
||||
var name = getUniqueName($(this).val());
|
||||
if (name != $(this).val()) {
|
||||
FileList.checkName(name, $(this).val(), true);
|
||||
var hidden = true;
|
||||
@@ -826,7 +854,7 @@ function getSelectedFiles(property){
|
||||
name:$(element).attr('data-file'),
|
||||
mime:$(element).data('mime'),
|
||||
type:$(element).data('type'),
|
||||
size:$(element).data('size'),
|
||||
size:$(element).data('size')
|
||||
};
|
||||
if(property){
|
||||
files.push(file[property]);
|
||||
@@ -863,7 +891,7 @@ function getMimeIcon(mime, ready){
|
||||
if(getMimeIcon.cache[mime]){
|
||||
ready(getMimeIcon.cache[mime]);
|
||||
}else{
|
||||
$.get( OC.filePath('files','ajax','mimeicon.php')+'?mime='+mime, function(path){
|
||||
$.get( OC.filePath('files','ajax','mimeicon.php')+'&mime='+mime, function(path){
|
||||
getMimeIcon.cache[mime]=path;
|
||||
ready(getMimeIcon.cache[mime]);
|
||||
});
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"folders" => "Ordner",
|
||||
"file" => "Datei",
|
||||
"files" => "Dateien",
|
||||
"seconds ago" => "Sekunden her",
|
||||
"seconds ago" => "Gerade eben",
|
||||
"minute ago" => "Minute her",
|
||||
"minutes ago" => "Minuten her",
|
||||
"today" => "Heute",
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<input name="maxZipInputSize" id="maxZipInputSize" style="width:180px;" value='<?php echo $_['maxZipInputSize'] ?>' title="<?php echo $l->t( '0 is unlimited' ); ?>"<?php if (!$_['allowZipDownload']) echo ' disabled="disabled"'; ?> />
|
||||
<label for="maxZipInputSize"><?php echo $l->t( 'Maximum input size for ZIP files' ); ?> </label><br />
|
||||
|
||||
<input type="hidden" value="<?php echo $_['requesttoken']; ?>" name="requesttoken" />
|
||||
<input type="submit" name="submitFilesAdminSettings" id="submitFilesAdminSettings" value="<?php echo $l->t( 'Save' ); ?>"/>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
<div class="file_upload_wrapper svg">
|
||||
<form data-upload-id='1' id="data-upload-form" class="file_upload_form" action="<?php echo OCP\Util::linkTo('files', 'ajax/upload.php'); ?>" method="post" enctype="multipart/form-data" target="file_upload_target_1">
|
||||
<input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $_['uploadMaxFilesize'] ?>" id="max_upload">
|
||||
<!-- Send the requesttoken, this is needed for older IE versions because they don't send the CSRF token via HTTP header in this case -->
|
||||
<input type="hidden" name="requesttoken" value="<?php echo $_['requesttoken'] ?>" id="requesttoken">
|
||||
<input type="hidden" class="max_human_file_size" value="(max <?php echo $_['uploadMaxHumanFilesize']; ?>)">
|
||||
<input type="hidden" name="dir" value="<?php echo $_['dir'] ?>" id="dir">
|
||||
<input class="file_upload_start" type="file" name='files[]'/>
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
<script type="text/javascript">
|
||||
<?php if ( array_key_exists('publicListView', $_) && $_['publicListView'] == true ) {
|
||||
echo "var publicListView = true;";
|
||||
} else {
|
||||
echo "var publicListView = false;";
|
||||
}
|
||||
?>
|
||||
</script>
|
||||
|
||||
<?php foreach($_['files'] as $file):
|
||||
$simple_file_size = OCP\simple_file_size($file['size']);
|
||||
$simple_size_color = intval(200-$file['size']/(1024*1024)*2); // the bigger the file, the darker the shade of grey; megabytes*2
|
||||
|
||||
@@ -109,10 +109,10 @@ class OC_Mount_Config {
|
||||
return $personal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add directory for mount point to the filesystem
|
||||
* @param OC_Fileview instance $view
|
||||
* @param string path to mount point
|
||||
/**
|
||||
* Add directory for mount point to the filesystem
|
||||
* @param OC_Fileview instance $view
|
||||
* @param string path to mount point
|
||||
*/
|
||||
private static function addMountPointDirectory($view, $path) {
|
||||
$dir = '';
|
||||
@@ -285,9 +285,17 @@ class OC_Mount_Config {
|
||||
public static function getCertificates() {
|
||||
$view = \OCP\Files::getStorage('files_external');
|
||||
$path=\OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath("").'uploads/';
|
||||
if (!is_dir($path)) mkdir($path);
|
||||
\OCP\Util::writeLog('files_external', 'checking path '.$path, \OCP\Util::INFO);
|
||||
if(!is_dir($path)) {
|
||||
//path might not exist (e.g. non-standard OC_User::getHome() value)
|
||||
//in this case create full path using 3rd (recursive=true) parameter.
|
||||
mkdir($path, 0777, true);
|
||||
}
|
||||
$result = array();
|
||||
$handle = opendir($path);
|
||||
if (!$handle) {
|
||||
return array();
|
||||
}
|
||||
while (false !== ($file = readdir($handle))) {
|
||||
if($file != '.' && $file != '..') $result[] = $file;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,15 @@ class OC_FileStorage_FTP extends OC_FileStorage_StreamWrapper{
|
||||
$this->host=$params['host'];
|
||||
$this->user=$params['user'];
|
||||
$this->password=$params['password'];
|
||||
$this->secure=isset($params['secure'])?(bool)$params['secure']:false;
|
||||
if(isset($params['secure'])){
|
||||
if(is_string($params['secure'])){
|
||||
$this->secure = ($params['secure'] === 'true');
|
||||
}else{
|
||||
$this->secure = (bool)$params['secure'];
|
||||
}
|
||||
}else{
|
||||
$this->secure = false;
|
||||
}
|
||||
$this->root=isset($params['root'])?$params['root']:'/';
|
||||
if(!$this->root || $this->root[0]!='/') {
|
||||
$this->root='/'.$this->root;
|
||||
|
||||
@@ -59,7 +59,7 @@ class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{
|
||||
}
|
||||
|
||||
public function filetype($path) {
|
||||
return (bool)@$this->opendir($path);//using opendir causes the same amount of requests and caches the content of the folder in one go
|
||||
return (bool)@$this->opendir($path) ? 'dir' : 'file';//using opendir causes the same amount of requests and caches the content of the folder in one go
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,7 +39,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
||||
* @return string
|
||||
*/
|
||||
private function getContainerName($path) {
|
||||
$path=trim($this->root.$path,'/');
|
||||
$path=trim(trim($this->root,'/')."/".$path,'/.');
|
||||
return str_replace('/','\\',$path);
|
||||
}
|
||||
|
||||
@@ -70,11 +70,11 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
||||
* @return CF_Container
|
||||
*/
|
||||
private function createContainer($path) {
|
||||
if($path=='' or $path=='/') {
|
||||
if($path=='' or $path=='/' or $path=='.') {
|
||||
return $this->conn->create_container($this->getContainerName($path));
|
||||
}
|
||||
$parent=dirname($path);
|
||||
if($parent=='' or $parent=='/') {
|
||||
if($parent=='' or $parent=='/' or $parent=='.') {
|
||||
$parentContainer=$this->rootContainer;
|
||||
}else{
|
||||
if(!$this->containerExists($parent)) {
|
||||
@@ -100,6 +100,9 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
||||
if(is_null($container)) {
|
||||
return null;
|
||||
}else{
|
||||
if ($path=="/" or $path=='') {
|
||||
return null;
|
||||
}
|
||||
try{
|
||||
$obj=$container->get_object(basename($path));
|
||||
$this->objects[$path]=$obj;
|
||||
@@ -135,7 +138,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
||||
private function createObject($path) {
|
||||
$container=$this->getContainer(dirname($path));
|
||||
if(!is_null($container)) {
|
||||
$container=$this->createContainer($path);
|
||||
$container=$this->createContainer(dirname($path));
|
||||
}
|
||||
return $container->create_object(basename($path));
|
||||
}
|
||||
@@ -268,7 +271,15 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
||||
$this->host=$params['host'];
|
||||
$this->user=$params['user'];
|
||||
$this->root=isset($params['root'])?$params['root']:'/';
|
||||
$this->secure=isset($params['secure'])?(bool)$params['secure']:true;
|
||||
if(isset($params['secure'])){
|
||||
if(is_string($params['secure'])){
|
||||
$this->secure = ($params['secure'] === 'true');
|
||||
}else{
|
||||
$this->secure = (bool)$params['secure'];
|
||||
}
|
||||
}else{
|
||||
$this->secure = false;
|
||||
}
|
||||
if(!$this->root || $this->root[0]!='/') {
|
||||
$this->root='/'.$this->root;
|
||||
}
|
||||
@@ -277,7 +288,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
||||
|
||||
$this->conn = new CF_Connection($this->auth);
|
||||
|
||||
if(!$this->containerExists($this->root)) {
|
||||
if(!$this->containerExists('/')) {
|
||||
$this->rootContainer=$this->createContainer('/');
|
||||
}else{
|
||||
$this->rootContainer=$this->getContainer('/');
|
||||
@@ -391,6 +402,9 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
||||
}
|
||||
|
||||
public function unlink($path) {
|
||||
if($this->containerExists($path)) {
|
||||
return $this->rmdir($path);
|
||||
}
|
||||
if($this->objectExists($path)) {
|
||||
$container=$this->getContainer(dirname($path));
|
||||
$container->delete_object(basename($path));
|
||||
@@ -401,13 +415,13 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
||||
}
|
||||
|
||||
public function fopen($path,$mode) {
|
||||
$obj=$this->getObject($path);
|
||||
if(is_null($obj)) {
|
||||
return false;
|
||||
}
|
||||
switch($mode) {
|
||||
case 'r':
|
||||
case 'rb':
|
||||
$obj=$this->getObject($path);
|
||||
if (is_null($obj)) {
|
||||
return false;
|
||||
}
|
||||
$fp = fopen('php://temp', 'r+');
|
||||
$obj->stream($fp);
|
||||
|
||||
@@ -440,7 +454,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
||||
}
|
||||
|
||||
public function free_space($path) {
|
||||
return 0;
|
||||
return 1024*1024*1024*8;
|
||||
}
|
||||
|
||||
public function touch($path,$mtime=null) {
|
||||
@@ -481,7 +495,17 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
||||
}
|
||||
|
||||
public function stat($path) {
|
||||
$container=$this->getContainer($path);
|
||||
if (!is_null($container)) {
|
||||
return array(
|
||||
'mtime'=>-1,
|
||||
'size'=>$container->bytes_used,
|
||||
'ctime'=>-1
|
||||
);
|
||||
}
|
||||
|
||||
$obj=$this->getObject($path);
|
||||
|
||||
if(is_null($obj)) {
|
||||
return false;
|
||||
}
|
||||
@@ -505,7 +529,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
|
||||
$obj->save_to_filename($tmpFile);
|
||||
return $tmpFile;
|
||||
}else{
|
||||
return false;
|
||||
return OCP\Files::tmpFile();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,15 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
||||
$this->host=$host;
|
||||
$this->user=$params['user'];
|
||||
$this->password=$params['password'];
|
||||
$this->secure=(isset($params['secure']) && $params['secure'] == 'true')?true:false;
|
||||
if(isset($params['secure'])){
|
||||
if(is_string($params['secure'])){
|
||||
$this->secure = ($params['secure'] === 'true');
|
||||
}else{
|
||||
$this->secure = (bool)$params['secure'];
|
||||
}
|
||||
}else{
|
||||
$this->secure = false;
|
||||
}
|
||||
$this->root=isset($params['root'])?$params['root']:'/';
|
||||
if(!$this->root || $this->root[0]!='/') {
|
||||
$this->root='/'.$this->root;
|
||||
@@ -131,6 +139,9 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
|
||||
switch($mode) {
|
||||
case 'r':
|
||||
case 'rb':
|
||||
if(!$this->file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
//straight up curl instead of sabredav here, sabredav put's the entire get result in memory
|
||||
$curl = curl_init();
|
||||
$fp = fopen('php://temp', 'r+');
|
||||
|
||||
@@ -1,43 +1,42 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Michael Gapczynski
|
||||
* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* ownCloud
|
||||
*
|
||||
* @author Michael Gapczynski
|
||||
* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
$config = include('apps/files_external/tests/config.php');
|
||||
if (!is_array($config) or !isset($config['amazons3']) or !$config['amazons3']['run']) {
|
||||
abstract class Test_Filestorage_AmazonS3 extends Test_FileStorage{}
|
||||
return;
|
||||
} else {
|
||||
class Test_Filestorage_AmazonS3 extends Test_FileStorage {
|
||||
class Test_Filestorage_AmazonS3 extends Test_FileStorage {
|
||||
|
||||
private $config;
|
||||
private $id;
|
||||
private $config;
|
||||
private $id;
|
||||
|
||||
public function setUp() {
|
||||
$id = uniqid();
|
||||
$this->config = include('apps/files_external/tests/config.php');
|
||||
$this->config['amazons3']['bucket'] = $id; // Make sure we have a new empty bucket to work in
|
||||
$this->instance = new OC_Filestorage_AmazonS3($this->config['amazons3']);
|
||||
public function setUp() {
|
||||
$id = uniqid();
|
||||
$this->config = include('files_external/tests/config.php');
|
||||
if (!is_array($this->config) or !isset($this->config['amazons3']) or !$this->config['amazons3']['run']) {
|
||||
$this->markTestSkipped('AmazonS3 backend not configured');
|
||||
}
|
||||
$this->config['amazons3']['bucket'] = $id; // Make sure we have a new empty bucket to work in
|
||||
$this->instance = new OC_Filestorage_AmazonS3($this->config['amazons3']);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
public function tearDown() {
|
||||
if ($this->instance) {
|
||||
$s3 = new AmazonS3(array('key' => $this->config['amazons3']['key'], 'secret' => $this->config['amazons3']['secret']));
|
||||
if ($s3->delete_all_objects($this->id)) {
|
||||
$s3->delete_bucket($this->id);
|
||||
|
||||
@@ -26,7 +26,7 @@ return array(
|
||||
'run'=>false,
|
||||
'user'=>'test:tester',
|
||||
'token'=>'testing',
|
||||
'host'=>'localhost:8080/auth',
|
||||
'host'=>'localhost.local:8080/auth',
|
||||
'root'=>'/',
|
||||
),
|
||||
'smb'=>array(
|
||||
|
||||
@@ -6,22 +6,21 @@
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
$config=include('files_external/tests/config.php');
|
||||
if(!is_array($config) or !isset($config['dropbox']) or !$config['dropbox']['run']) {
|
||||
abstract class Test_Filestorage_Dropbox extends Test_FileStorage{}
|
||||
return;
|
||||
}else{
|
||||
class Test_Filestorage_Dropbox extends Test_FileStorage {
|
||||
private $config;
|
||||
class Test_Filestorage_Dropbox extends Test_FileStorage {
|
||||
private $config;
|
||||
|
||||
public function setUp() {
|
||||
$id=uniqid();
|
||||
$this->config=include('files_external/tests/config.php');
|
||||
$this->config['dropbox']['root'].='/'.$id;//make sure we have an new empty folder to work in
|
||||
$this->instance=new OC_Filestorage_Dropbox($this->config['dropbox']);
|
||||
public function setUp() {
|
||||
$id = uniqid();
|
||||
$this->config = include('files_external/tests/config.php');
|
||||
if (!is_array($this->config) or !isset($this->config['dropbox']) or !$this->config['dropbox']['run']) {
|
||||
$this->markTestSkipped('Dropbox backend not configured');
|
||||
}
|
||||
$this->config['dropbox']['root'] .= '/' . $id; //make sure we have an new empty folder to work in
|
||||
$this->instance = new OC_Filestorage_Dropbox($this->config['dropbox']);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
public function tearDown() {
|
||||
if ($this->instance) {
|
||||
$this->instance->unlink('/');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,23 +6,40 @@
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
$config=include('apps/files_external/tests/config.php');
|
||||
if(!is_array($config) or !isset($config['ftp']) or !$config['ftp']['run']) {
|
||||
abstract class Test_Filestorage_FTP extends Test_FileStorage{}
|
||||
return;
|
||||
}else{
|
||||
class Test_Filestorage_FTP extends Test_FileStorage {
|
||||
private $config;
|
||||
class Test_Filestorage_FTP extends Test_FileStorage {
|
||||
private $config;
|
||||
|
||||
public function setUp() {
|
||||
$id=uniqid();
|
||||
$this->config=include('apps/files_external/tests/config.php');
|
||||
$this->config['ftp']['root'].='/'.$id;//make sure we have an new empty folder to work in
|
||||
$this->instance=new OC_Filestorage_FTP($this->config['ftp']);
|
||||
public function setUp() {
|
||||
$id = uniqid();
|
||||
$this->config = include('files_external/tests/config.php');
|
||||
if (!is_array($this->config) or !isset($this->config['ftp']) or !$this->config['ftp']['run']) {
|
||||
$this->markTestSkipped('FTP backend not configured');
|
||||
}
|
||||
$this->config['ftp']['root'] .= '/' . $id; //make sure we have an new empty folder to work in
|
||||
$this->instance = new OC_Filestorage_FTP($this->config['ftp']);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
public function tearDown() {
|
||||
if ($this->instance) {
|
||||
OCP\Files::rmdirr($this->instance->constructUrl(''));
|
||||
}
|
||||
}
|
||||
|
||||
public function testConstructUrl(){
|
||||
$config = array ( 'host' => 'localhost', 'user' => 'ftp', 'password' => 'ftp', 'root' => '/', 'secure' => false );
|
||||
$instance = new OC_Filestorage_FTP($config);
|
||||
$this->assertEqual('ftp://ftp:ftp@localhost/', $instance->constructUrl(''));
|
||||
|
||||
$config['secure'] = true;
|
||||
$instance = new OC_Filestorage_FTP($config);
|
||||
$this->assertEqual('ftps://ftp:ftp@localhost/', $instance->constructUrl(''));
|
||||
|
||||
$config['secure'] = 'false';
|
||||
$instance = new OC_Filestorage_FTP($config);
|
||||
$this->assertEqual('ftp://ftp:ftp@localhost/', $instance->constructUrl(''));
|
||||
|
||||
$config['secure'] = 'true';
|
||||
$instance = new OC_Filestorage_FTP($config);
|
||||
$this->assertEqual('ftps://ftp:ftp@localhost/', $instance->constructUrl(''));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Michael Gapczynski
|
||||
* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
* ownCloud
|
||||
*
|
||||
* @author Michael Gapczynski
|
||||
* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
$config=include('apps/files_external/tests/config.php');
|
||||
if(!is_array($config) or !isset($config['google']) or !$config['google']['run']) {
|
||||
abstract class Test_Filestorage_Google extends Test_FileStorage{}
|
||||
return;
|
||||
}else{
|
||||
class Test_Filestorage_Google extends Test_FileStorage {
|
||||
class Test_Filestorage_Google extends Test_FileStorage {
|
||||
|
||||
private $config;
|
||||
private $config;
|
||||
|
||||
public function setUp() {
|
||||
$id=uniqid();
|
||||
$this->config=include('apps/files_external/tests/config.php');
|
||||
$this->config['google']['root'].='/'.$id;//make sure we have an new empty folder to work in
|
||||
$this->instance=new OC_Filestorage_Google($this->config['google']);
|
||||
public function setUp() {
|
||||
$id = uniqid();
|
||||
$this->config = include('files_external/tests/config.php');
|
||||
if (!is_array($this->config) or !isset($this->config['google']) or !$this->config['google']['run']) {
|
||||
$this->markTestSkipped('Google backend not configured');
|
||||
}
|
||||
$this->config['google']['root'] .= '/' . $id; //make sure we have an new empty folder to work in
|
||||
$this->instance = new OC_Filestorage_Google($this->config['google']);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
public function tearDown() {
|
||||
if ($this->instance) {
|
||||
$this->instance->rmdir('/');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,23 +6,21 @@
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
$config=include('apps/files_external/tests/config.php');
|
||||
class Test_Filestorage_SMB extends Test_FileStorage {
|
||||
private $config;
|
||||
|
||||
if(!is_array($config) or !isset($config['smb']) or !$config['smb']['run']) {
|
||||
abstract class Test_Filestorage_SMB extends Test_FileStorage{}
|
||||
return;
|
||||
}else{
|
||||
class Test_Filestorage_SMB extends Test_FileStorage {
|
||||
private $config;
|
||||
|
||||
public function setUp() {
|
||||
$id=uniqid();
|
||||
$this->config=include('apps/files_external/tests/config.php');
|
||||
$this->config['smb']['root'].=$id;//make sure we have an new empty folder to work in
|
||||
$this->instance=new OC_Filestorage_SMB($this->config['smb']);
|
||||
public function setUp() {
|
||||
$id = uniqid();
|
||||
$this->config = include('files_external/tests/config.php');
|
||||
if (!is_array($this->config) or !isset($this->config['smb']) or !$this->config['smb']['run']) {
|
||||
$this->markTestSkipped('Samba backend not configured');
|
||||
}
|
||||
$this->config['smb']['root'] .= $id; //make sure we have an new empty folder to work in
|
||||
$this->instance = new OC_Filestorage_SMB($this->config['smb']);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
public function tearDown() {
|
||||
if ($this->instance) {
|
||||
OCP\Files::rmdirr($this->instance->constructUrl(''));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,25 +6,23 @@
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
$config=include('apps/files_external/tests/config.php');
|
||||
if(!is_array($config) or !isset($config['swift']) or !$config['swift']['run']) {
|
||||
abstract class Test_Filestorage_SWIFT extends Test_FileStorage{}
|
||||
return;
|
||||
}else{
|
||||
class Test_Filestorage_SWIFT extends Test_FileStorage {
|
||||
private $config;
|
||||
class Test_Filestorage_SWIFT extends Test_FileStorage {
|
||||
private $config;
|
||||
|
||||
public function setUp() {
|
||||
$id=uniqid();
|
||||
$this->config=include('apps/files_external/tests/config.php');
|
||||
$this->config['swift']['root'].='/'.$id;//make sure we have an new empty folder to work in
|
||||
$this->instance=new OC_Filestorage_SWIFT($this->config['swift']);
|
||||
public function setUp() {
|
||||
$id = uniqid();
|
||||
$this->config = include('files_external/tests/config.php');
|
||||
if (!is_array($this->config) or !isset($this->config['swift']) or !$this->config['swift']['run']) {
|
||||
$this->markTestSkipped('OpenStack SWIFT backend not configured');
|
||||
}
|
||||
$this->config['swift']['root'] .= '/' . $id; //make sure we have an new empty folder to work in
|
||||
$this->instance = new OC_Filestorage_SWIFT($this->config['swift']);
|
||||
}
|
||||
|
||||
|
||||
public function tearDown() {
|
||||
$this->instance->rmdir('');
|
||||
public function tearDown() {
|
||||
if ($this->instance) {
|
||||
$this->instance->rmdir('');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,22 +6,21 @@
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
$config=include('apps/files_external/tests/config.php');
|
||||
if(!is_array($config) or !isset($config['webdav']) or !$config['webdav']['run']) {
|
||||
abstract class Test_Filestorage_DAV extends Test_FileStorage{}
|
||||
return;
|
||||
}else{
|
||||
class Test_Filestorage_DAV extends Test_FileStorage {
|
||||
private $config;
|
||||
class Test_Filestorage_DAV extends Test_FileStorage {
|
||||
private $config;
|
||||
|
||||
public function setUp() {
|
||||
$id=uniqid();
|
||||
$this->config=include('apps/files_external/tests/config.php');
|
||||
$this->config['webdav']['root'].='/'.$id;//make sure we have an new empty folder to work in
|
||||
$this->instance=new OC_Filestorage_DAV($this->config['webdav']);
|
||||
public function setUp() {
|
||||
$id = uniqid();
|
||||
$this->config = include('files_external/tests/config.php');
|
||||
if (!is_array($this->config) or !isset($this->config['webdav']) or !$this->config['webdav']['run']) {
|
||||
$this->markTestSkipped('WebDAV backend not configured');
|
||||
}
|
||||
$this->config['webdav']['root'] .= '/' . $id; //make sure we have an new empty folder to work in
|
||||
$this->instance = new OC_Filestorage_DAV($this->config['webdav']);
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
public function tearDown() {
|
||||
if ($this->instance) {
|
||||
$this->instance->rmdir('/');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
OC::$CLASSPATH['OC_Share_Backend_File'] = "apps/files_sharing/lib/share/file.php";
|
||||
OC::$CLASSPATH['OC_Share_Backend_Folder'] = 'apps/files_sharing/lib/share/folder.php';
|
||||
OC::$CLASSPATH['OC_Filestorage_Shared'] = "apps/files_sharing/lib/sharedstorage.php";
|
||||
OC::$CLASSPATH['OC_Files_Sharing_Util'] = "apps/files_sharing/lib/util.php";
|
||||
OCP\Util::connectHook('OC_Filesystem', 'setup', 'OC_Filestorage_Shared', 'setup');
|
||||
OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
|
||||
OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
|
||||
|
||||
@@ -55,6 +55,7 @@ if (version_compare($installedVersion, '0.3', '<')) {
|
||||
OC_Util::tearDownFS();
|
||||
}
|
||||
}
|
||||
OC_User::setUserId(null);
|
||||
if ($update_error) {
|
||||
OCP\Util::writeLog('files_sharing', 'There were some problems upgrading the sharing of files', OCP\Util::ERROR);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
$(document).ready(function() {
|
||||
|
||||
if (typeof OC.Share !== 'undefined' && typeof FileActions !== 'undefined') {
|
||||
if (typeof OC.Share !== 'undefined' && typeof FileActions !== 'undefined' && !publicListView) {
|
||||
OC.Share.loadIcons('file');
|
||||
FileActions.register('all', 'Share', OC.PERMISSION_READ, function(filename) {
|
||||
// Return the correct sharing icon
|
||||
@@ -46,7 +46,7 @@ $(document).ready(function() {
|
||||
var appendTo = $(tr).find('td.filename');
|
||||
// Check if drop down is already visible for a different file
|
||||
if (OC.Share.droppedDown) {
|
||||
if (item != $('#dropdown').data('item')) {
|
||||
if ($(tr).data('id') != $('#dropdown').attr('data-item-source')) {
|
||||
OC.Share.hideDropDown(function () {
|
||||
$(tr).addClass('mouseOver');
|
||||
OC.Share.showDropDown(itemType, $(tr).data('id'), appendTo, true, possiblePermissions);
|
||||
|
||||
@@ -113,7 +113,10 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
||||
return false;
|
||||
} else if ($source = $this->getSourcePath($path)) {
|
||||
$storage = OC_Filesystem::getStorage($source);
|
||||
return $storage->mkdir($this->getInternalPath($source));
|
||||
if( ($storage->mkdir($this->getInternalPath($source))) ) {
|
||||
$this->updateFSCache($path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -296,10 +299,15 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
||||
'target' => $this->sharedFolder.$path,
|
||||
'source' => $source,
|
||||
);
|
||||
OCP\Util::emitHook('OC_Filestorage_Shared', 'file_put_contents', $info);
|
||||
OCP\Util::emitHook('OC_Filestorage_Shared', 'file_put_contents', $info);
|
||||
$parts = explode('/', $source, 4);
|
||||
$user = $parts[1];
|
||||
$intPath = '/'.$parts[3];
|
||||
$storage = OC_Filesystem::getStorage($source);
|
||||
$result = $storage->file_put_contents($this->getInternalPath($source), $data);
|
||||
return $result;
|
||||
if( ( $result = $storage->file_put_contents($this->getInternalPath($source), $data) ) ) {
|
||||
$this->updateFSCache($path);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -368,17 +376,18 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
||||
|
||||
public function fopen($path, $mode) {
|
||||
if ($source = $this->getSourcePath($path)) {
|
||||
$write = false;
|
||||
switch ($mode) {
|
||||
case 'w':
|
||||
case 'wb':
|
||||
case 'w+':
|
||||
case 'wb+': $write = true;
|
||||
case 'r+':
|
||||
case 'rb+':
|
||||
case 'w+':
|
||||
case 'wb+':
|
||||
case 'x+':
|
||||
case 'xb+':
|
||||
case 'a+':
|
||||
case 'ab+':
|
||||
case 'w':
|
||||
case 'wb':
|
||||
case 'x':
|
||||
case 'xb':
|
||||
case 'a':
|
||||
@@ -394,6 +403,14 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
||||
);
|
||||
OCP\Util::emitHook('OC_Filestorage_Shared', 'fopen', $info);
|
||||
$storage = OC_Filesystem::getStorage($source);
|
||||
|
||||
$parts = explode('/', $source, 4);
|
||||
$user = $parts[1];
|
||||
$intPath = '/'.$parts[3];
|
||||
|
||||
if ( $write && $storage->touch($this->getInternalPath($source)) ) {
|
||||
$this->updateFSCache($path);
|
||||
}
|
||||
return $storage->fopen($this->getInternalPath($source), $mode);
|
||||
}
|
||||
return false;
|
||||
@@ -447,4 +464,16 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
|
||||
//TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
private function updateFSCache($path) {
|
||||
$source = $this->getSourcePath($path);
|
||||
$parts = explode('/', $source, 4);
|
||||
$user = $parts[1];
|
||||
$intPath = '/'.$parts[3];
|
||||
|
||||
$mtime = $this->filemtime($path);
|
||||
$size = $this->filesize($path);
|
||||
$mime = $this->getMimeType($path);
|
||||
OC_FileCache::put($intPath ,array('user'=>$user, 'size'=>$size, 'mtime'=>$mtime, 'mimetype'=>$mime, 'writable'=>true),'/'.$user.'/files');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Bjoern Schiessle
|
||||
* @copyright 2012 Bjoern Schiessle schiessle@owncloud.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class OC_Files_Sharing_Util {
|
||||
|
||||
private static $files = array();
|
||||
|
||||
/**
|
||||
* @brief Get the source file path and the permissions granted for a shared file
|
||||
* @param string Shared target file path
|
||||
* @return Returns array with the keys path and permissions or false if not found
|
||||
*/
|
||||
private static function getFile($target) {
|
||||
$target = '/'.$target;
|
||||
$target = rtrim($target, '/');
|
||||
if (isset(self::$files[$target])) {
|
||||
return self::$files[$target];
|
||||
} else {
|
||||
$pos = strpos($target, '/', 1);
|
||||
// Get shared folder name
|
||||
if ($pos !== false) {
|
||||
$folder = substr($target, 0, $pos);
|
||||
if (isset(self::$files[$folder])) {
|
||||
$file = self::$files[$folder];
|
||||
} else {
|
||||
$file = OCP\Share::getItemSharedWith('folder', $folder, OC_Share_Backend_File::FORMAT_SHARED_STORAGE);
|
||||
}
|
||||
if ($file) {
|
||||
self::$files[$target]['path'] = $file['path'].substr($target, strlen($folder));
|
||||
self::$files[$target]['permissions'] = $file['permissions'];
|
||||
return self::$files[$target];
|
||||
}
|
||||
} else {
|
||||
$file = OCP\Share::getItemSharedWith('file', $target, OC_Share_Backend_File::FORMAT_SHARED_STORAGE);
|
||||
if ($file) {
|
||||
self::$files[$target] = $file;
|
||||
return self::$files[$target];
|
||||
}
|
||||
}
|
||||
OCP\Util::writeLog('files_sharing', 'File source not found for: '.$target, OCP\Util::ERROR);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the source file path for a shared file
|
||||
* @param string Shared target file path
|
||||
* @return Returns source file path or false if not found
|
||||
*/
|
||||
public static function getSourcePath($target) {
|
||||
$file = self::getFile($target);
|
||||
if (isset($file['path'])) {
|
||||
$uid = substr($file['path'], 1, strpos($file['path'], '/', 1) - 1);
|
||||
OC_Filesystem::mount('OC_Filestorage_Local', array('datadir' => OC_User::getHome($uid)), $uid);
|
||||
return $file['path'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+236
-150
@@ -19,174 +19,260 @@ if (isset($_GET['token'])) {
|
||||
\OCP\Util::writeLog('files_sharing', 'You have files that are shared by link originating from ownCloud 4.0. Redistribute the new links, because backwards compatibility will be removed in ownCloud 5.', \OCP\Util::WARN);
|
||||
}
|
||||
}
|
||||
// Enf of backward compatibility
|
||||
|
||||
if (isset($_GET['file']) || isset($_GET['dir'])) {
|
||||
function getID($path) {
|
||||
// use the share table from the db to find the item source if the file was reshared because shared files
|
||||
// are not stored in the file cache.
|
||||
if (substr(OC_Filesystem::getMountPoint($path), -7, 6) == "Shared") {
|
||||
$path_parts = explode('/', $path, 5);
|
||||
$user = $path_parts[1];
|
||||
$intPath = '/'.$path_parts[4];
|
||||
$query = \OC_DB::prepare('SELECT `item_source` FROM `*PREFIX*share` WHERE `uid_owner` = ? AND `file_target` = ? ');
|
||||
$result = $query->execute(array($user, $intPath));
|
||||
$row = $result->fetchRow();
|
||||
$fileSource = $row['item_source'];
|
||||
} else {
|
||||
$fileSource = OC_Filecache::getId($path, '');
|
||||
}
|
||||
|
||||
return $fileSource;
|
||||
}
|
||||
// End of backward compatibility
|
||||
|
||||
/**
|
||||
* lookup file path and owner by fetching it from the fscache
|
||||
* needed becaus OC_FileCache::getPath($id, $user) already requires the user
|
||||
* @param int $id
|
||||
* @return array
|
||||
*/
|
||||
function getPathAndUser($id) {
|
||||
$query = \OC_DB::prepare('SELECT `user`, `path` FROM `*PREFIX*fscache` WHERE `id` = ?');
|
||||
$result = $query->execute(array($id));
|
||||
$row = $result->fetchRow();
|
||||
return $row;
|
||||
}
|
||||
|
||||
|
||||
if (isset($_GET['t'])) {
|
||||
$token = $_GET['t'];
|
||||
$linkItem = OCP\Share::getShareByToken($token);
|
||||
if (is_array($linkItem) && isset($linkItem['uid_owner'])) {
|
||||
// seems to be a valid share
|
||||
$type = $linkItem['item_type'];
|
||||
$fileSource = $linkItem['file_source'];
|
||||
$shareOwner = $linkItem['uid_owner'];
|
||||
|
||||
if (OCP\User::userExists($shareOwner) && $fileSource != -1 ) {
|
||||
|
||||
$pathAndUser = getPathAndUser($linkItem['file_source']);
|
||||
$fileOwner = $pathAndUser['user'];
|
||||
|
||||
//if this is a reshare check the file owner also exists
|
||||
if ($shareOwner != $fileOwner && ! OCP\User::userExists($fileOwner)) {
|
||||
OCP\Util::writeLog('share', 'original file owner '.$fileOwner.' does not exist for share '.$linkItem['id'], \OCP\Util::ERROR);
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
$tmpl = new OCP\Template('', '404', 'guest');
|
||||
$tmpl->printPage();
|
||||
exit();
|
||||
}
|
||||
|
||||
//mount filesystem of file owner
|
||||
OC_Util::setupFS($fileOwner);
|
||||
}
|
||||
}
|
||||
} else if (isset($_GET['file']) || isset($_GET['dir'])) {
|
||||
OCP\Util::writeLog('share', 'Missing token, trying fallback file/dir links', \OCP\Util::DEBUG);
|
||||
if (isset($_GET['dir'])) {
|
||||
$type = 'folder';
|
||||
$path = $_GET['dir'];
|
||||
if(strlen($path)>1 and substr($path, -1, 1)==='/') {
|
||||
$path=substr($path, 0, -1);
|
||||
}
|
||||
$baseDir = $path;
|
||||
$dir = $baseDir;
|
||||
} else {
|
||||
$type = 'file';
|
||||
$path = $_GET['file'];
|
||||
if(strlen($path)>1 and substr($path, -1, 1)==='/') {
|
||||
$path=substr($path, 0, -1);
|
||||
}
|
||||
}
|
||||
$uidOwner = substr($path, 1, strpos($path, '/', 1) - 1);
|
||||
if (OCP\User::userExists($uidOwner)) {
|
||||
OC_Util::setupFS($uidOwner);
|
||||
$fileSource = OC_Filecache::getId($path, '');
|
||||
if ($fileSource != -1 && ($linkItem = OCP\Share::getItemSharedWithByLink($type, $fileSource, $uidOwner))) {
|
||||
// TODO Fix in the getItems
|
||||
if (!isset($linkItem['item_type']) || $linkItem['item_type'] != $type) {
|
||||
$shareOwner = substr($path, 1, strpos($path, '/', 1) - 1);
|
||||
|
||||
if (OCP\User::userExists($shareOwner)) {
|
||||
OC_Util::setupFS($shareOwner);
|
||||
$fileSource = getID($path);
|
||||
if ($fileSource != -1 ) {
|
||||
$linkItem = OCP\Share::getItemSharedWithByLink($type, $fileSource, $shareOwner);
|
||||
$pathAndUser['path'] = $path;
|
||||
$path_parts = explode('/', $path, 5);
|
||||
$pathAndUser['user'] = $path_parts[1];
|
||||
$fileOwner = $path_parts[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($linkItem) {
|
||||
if (!isset($linkItem['item_type'])) {
|
||||
OCP\Util::writeLog('share', 'No item type set for share id: '.$linkItem['id'], \OCP\Util::ERROR);
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
$tmpl = new OCP\Template('', '404', 'guest');
|
||||
$tmpl->printPage();
|
||||
exit();
|
||||
}
|
||||
if (isset($linkItem['share_with'])) {
|
||||
// Authenticate share_with
|
||||
$url = OCP\Util::linkToPublic('files').'&t='.$token;
|
||||
if (isset($_GET['file'])) {
|
||||
$url .= '&file='.urlencode($_GET['file']);
|
||||
} else if (isset($_GET['dir'])) {
|
||||
$url .= '&dir='.urlencode($_GET['dir']);
|
||||
}
|
||||
if (isset($_POST['password'])) {
|
||||
$password = $_POST['password'];
|
||||
if ($linkItem['share_type'] == OCP\Share::SHARE_TYPE_LINK) {
|
||||
// Check Password
|
||||
$forcePortable = (CRYPT_BLOWFISH != 1);
|
||||
$hasher = new PasswordHash(8, $forcePortable);
|
||||
if (!($hasher->CheckPassword($password.OC_Config::getValue('passwordsalt', ''), $linkItem['share_with']))) {
|
||||
$tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest');
|
||||
$tmpl->assign('URL', $url);
|
||||
$tmpl->assign('error', true);
|
||||
$tmpl->printPage();
|
||||
exit();
|
||||
} else {
|
||||
// Save item id in session for future requests
|
||||
$_SESSION['public_link_authenticated'] = $linkItem['id'];
|
||||
}
|
||||
} else {
|
||||
OCP\Util::writeLog('share', 'Unknown share type '.$linkItem['share_type'].' for share id '.$linkItem['id'], \OCP\Util::ERROR);
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
$tmpl = new OCP\Template('', '404', 'guest');
|
||||
$tmpl->printPage();
|
||||
exit();
|
||||
}
|
||||
if (isset($linkItem['share_with'])) {
|
||||
// Check password
|
||||
if (isset($_POST['password'])) {
|
||||
$password = $_POST['password'];
|
||||
$storedHash = $linkItem['share_with'];
|
||||
$forcePortable = (CRYPT_BLOWFISH != 1);
|
||||
$hasher = new PasswordHash(8, $forcePortable);
|
||||
if (!($hasher->CheckPassword($password.OC_Config::getValue('passwordsalt', ''), $storedHash))) {
|
||||
$tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest');
|
||||
$tmpl->assign('URL', OCP\Util::linkToPublic('files').'&file='.$_GET['file']);
|
||||
$tmpl->assign('error', true);
|
||||
$tmpl->printPage();
|
||||
exit();
|
||||
} else {
|
||||
// Save item id in session for future requests
|
||||
$_SESSION['public_link_authenticated'] = $linkItem['id'];
|
||||
}
|
||||
// Check if item id is set in session
|
||||
} else if (!isset($_SESSION['public_link_authenticated']) || $_SESSION['public_link_authenticated'] !== $linkItem['id']) {
|
||||
// Prompt for password
|
||||
$tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest');
|
||||
$tmpl->assign('URL', OCP\Util::linkToPublic('files').'&file='.$_GET['file']);
|
||||
$tmpl->printPage();
|
||||
exit();
|
||||
}
|
||||
}
|
||||
$path = $linkItem['path'];
|
||||
if (isset($_GET['path'])) {
|
||||
$path .= $_GET['path'];
|
||||
$dir .= $_GET['path'];
|
||||
if (!OC_Filesystem::file_exists($path)) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
$tmpl = new OCP\Template('', '404', 'guest');
|
||||
$tmpl->printPage();
|
||||
exit();
|
||||
}
|
||||
}
|
||||
// Download the file
|
||||
if (isset($_GET['download'])) {
|
||||
if (isset($_GET['dir'])) {
|
||||
if ( isset($_GET['files']) ) { // download selected files
|
||||
OC_Files::get($path, $_GET['files'], $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
} else if (isset($_GET['path']) && $_GET['path'] != '' ) { // download a file from a shared directory
|
||||
OC_Files::get('', $path, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
} else { // download the whole shared directory
|
||||
OC_Files::get($path, '', $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
}
|
||||
} else { // download a single shared file
|
||||
OC_Files::get("", $path, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
}
|
||||
|
||||
} else {
|
||||
OCP\Util::addStyle('files_sharing', 'public');
|
||||
OCP\Util::addScript('files_sharing', 'public');
|
||||
OCP\Util::addScript('files', 'fileactions');
|
||||
$tmpl = new OCP\Template('files_sharing', 'public', 'base');
|
||||
$tmpl->assign('owner', $uidOwner);
|
||||
// Show file list
|
||||
if (OC_Filesystem::is_dir($path)) {
|
||||
OCP\Util::addStyle('files', 'files');
|
||||
OCP\Util::addScript('files', 'files');
|
||||
OCP\Util::addScript('files', 'filelist');
|
||||
$files = array();
|
||||
$rootLength = strlen($baseDir) + 1;
|
||||
foreach (OC_Files::getDirectoryContent($path) as $i) {
|
||||
$i['date'] = OCP\Util::formatDate($i['mtime']);
|
||||
if ($i['type'] == 'file') {
|
||||
$fileinfo = pathinfo($i['name']);
|
||||
$i['basename'] = $fileinfo['filename'];
|
||||
$i['extension'] = isset($fileinfo['extension']) ? ('.'.$fileinfo['extension']) : '';
|
||||
}
|
||||
$i['directory'] = '/'.substr('/'.$uidOwner.'/files'.$i['directory'], $rootLength);
|
||||
if ($i['directory'] == '/') {
|
||||
$i['directory'] = '';
|
||||
}
|
||||
$i['permissions'] = OCP\Share::PERMISSION_READ;
|
||||
$files[] = $i;
|
||||
}
|
||||
// Make breadcrumb
|
||||
$breadcrumb = array();
|
||||
$pathtohere = '';
|
||||
$count = 1;
|
||||
foreach (explode('/', $dir) as $i) {
|
||||
if ($i != '') {
|
||||
if ($i != $baseDir) {
|
||||
$pathtohere .= '/'.$i;
|
||||
}
|
||||
if ( strlen($pathtohere) < strlen($_GET['dir'])) {
|
||||
continue;
|
||||
}
|
||||
$breadcrumb[] = array('dir' => str_replace($_GET['dir'], "", $pathtohere, $count), 'name' => $i);
|
||||
}
|
||||
}
|
||||
$list = new OCP\Template('files', 'part.list', '');
|
||||
$list->assign('files', $files, false);
|
||||
$list->assign('baseURL', OCP\Util::linkToPublic('files').'&dir='.$_GET['dir'].'&path=', false);
|
||||
$list->assign('downloadURL', OCP\Util::linkToPublic('files').'&download&dir='.$_GET['dir'].'&path=', false);
|
||||
$breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '' );
|
||||
$breadcrumbNav->assign('breadcrumb', $breadcrumb, false);
|
||||
$breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files').'&dir='.$_GET['dir'].'&path=', false);
|
||||
$folder = new OCP\Template('files', 'index', '');
|
||||
$folder->assign('fileList', $list->fetchPage(), false);
|
||||
$folder->assign('breadcrumb', $breadcrumbNav->fetchPage(), false);
|
||||
$folder->assign('dir', basename($dir));
|
||||
$folder->assign('isCreatable', false);
|
||||
$folder->assign('permissions', 0);
|
||||
$folder->assign('files', $files);
|
||||
$folder->assign('uploadMaxFilesize', 0);
|
||||
$folder->assign('uploadMaxHumanFilesize', 0);
|
||||
$folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true)));
|
||||
$tmpl->assign('folder', $folder->fetchPage(), false);
|
||||
$tmpl->assign('uidOwner', $uidOwner);
|
||||
$tmpl->assign('dir', basename($dir));
|
||||
$tmpl->assign('filename', basename($path));
|
||||
$tmpl->assign('mimetype', OC_Filesystem::getMimeType($path));
|
||||
$tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true)));
|
||||
if (isset($_GET['path'])) {
|
||||
$getPath = $_GET['path'];
|
||||
} else {
|
||||
$getPath = '';
|
||||
}
|
||||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').'&download&dir='.$_GET['dir'].'&path='.$getPath);
|
||||
} else {
|
||||
// Show file preview if viewer is available
|
||||
$tmpl->assign('uidOwner', $uidOwner);
|
||||
$tmpl->assign('dir', dirname($path));
|
||||
$tmpl->assign('filename', basename($path));
|
||||
$tmpl->assign('mimetype', OC_Filesystem::getMimeType($path));
|
||||
if ($type == 'file') {
|
||||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').'&file='.$_GET['file'].'&download');
|
||||
} else {
|
||||
if (isset($_GET['path'])) {
|
||||
$getPath = $_GET['path'];
|
||||
} else {
|
||||
$getPath = '';
|
||||
}
|
||||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').'&download&dir='.$_GET['dir'].'&path='.$getPath);
|
||||
}
|
||||
}
|
||||
$tmpl->printPage();
|
||||
}
|
||||
// Check if item id is set in session
|
||||
} else if (!isset($_SESSION['public_link_authenticated']) || $_SESSION['public_link_authenticated'] !== $linkItem['id']) {
|
||||
// Prompt for password
|
||||
$tmpl = new OCP\Template('files_sharing', 'authenticate', 'guest');
|
||||
$tmpl->assign('URL', $url);
|
||||
$tmpl->printPage();
|
||||
exit();
|
||||
}
|
||||
}
|
||||
$basePath = substr($pathAndUser['path'] , strlen('/'.$fileOwner.'/files'));
|
||||
$path = $basePath;
|
||||
if (isset($_GET['path'])) {
|
||||
$path .= $_GET['path'];
|
||||
}
|
||||
if (!$path || !OC_Filesystem::isValidPath($path) || !OC_Filesystem::file_exists($path)) {
|
||||
OCP\Util::writeLog('share', 'Invalid path '.$path.' for share id '.$linkItem['id'], \OCP\Util::ERROR);
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
$tmpl = new OCP\Template('', '404', 'guest');
|
||||
$tmpl->printPage();
|
||||
exit();
|
||||
}
|
||||
$dir = dirname($path);
|
||||
$file = basename($path);
|
||||
// Download the file
|
||||
if (isset($_GET['download'])) {
|
||||
if (isset($_GET['path']) && $_GET['path'] !== '' ) {
|
||||
if ( isset($_GET['files']) ) { // download selected files
|
||||
OC_Files::get($path, $_GET['files'], $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
} else if (isset($_GET['path']) && $_GET['path'] != '' ) { // download a file from a shared directory
|
||||
OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
} else { // download the whole shared directory
|
||||
OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
}
|
||||
} else { // download a single shared file
|
||||
OC_Files::get($dir, $file, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
|
||||
}
|
||||
|
||||
} else {
|
||||
OCP\Util::addStyle('files_sharing', 'public');
|
||||
OCP\Util::addScript('files_sharing', 'public');
|
||||
OCP\Util::addScript('files', 'fileactions');
|
||||
$tmpl = new OCP\Template('files_sharing', 'public', 'base');
|
||||
$tmpl->assign('uidOwner', $shareOwner);
|
||||
$tmpl->assign('dir', $dir);
|
||||
$tmpl->assign('filename', $file);
|
||||
$tmpl->assign('mimetype', OC_Filesystem::getMimeType($path));
|
||||
if (isset($_GET['path'])) {
|
||||
$getPath = $_GET['path'];
|
||||
} else {
|
||||
$getPath = '';
|
||||
}
|
||||
//
|
||||
$urlLinkIdentifiers= (isset($token)?'&t='.$token:'').(isset($_GET['dir'])?'&dir='.$_GET['dir']:'').(isset($_GET['file'])?'&file='.$_GET['file']:'');
|
||||
// Show file list
|
||||
if (OC_Filesystem::is_dir($path)) {
|
||||
OCP\Util::addStyle('files', 'files');
|
||||
OCP\Util::addScript('files', 'files');
|
||||
OCP\Util::addScript('files', 'filelist');
|
||||
$files = array();
|
||||
$rootLength = strlen($basePath) + 1;
|
||||
foreach (OC_Files::getDirectoryContent($path) as $i) {
|
||||
$i['date'] = OCP\Util::formatDate($i['mtime']);
|
||||
if ($i['type'] == 'file') {
|
||||
$fileinfo = pathinfo($i['name']);
|
||||
$i['basename'] = $fileinfo['filename'];
|
||||
$i['extension'] = isset($fileinfo['extension']) ? ('.'.$fileinfo['extension']) : '';
|
||||
}
|
||||
$i['directory'] = '/'.substr($i['directory'], $rootLength);
|
||||
if ($i['directory'] == '/') {
|
||||
$i['directory'] = '';
|
||||
}
|
||||
$i['permissions'] = OCP\Share::PERMISSION_READ;
|
||||
$files[] = $i;
|
||||
}
|
||||
// Make breadcrumb
|
||||
$breadcrumb = array();
|
||||
$pathtohere = '';
|
||||
|
||||
//add base breadcrumb
|
||||
$breadcrumb[] = array('dir' => '/', 'name' => basename($basePath));
|
||||
|
||||
//add subdir breadcrumbs
|
||||
foreach (explode('/', urldecode($_GET['path'])) as $i) {
|
||||
if ($i != '') {
|
||||
$pathtohere .= '/'.$i;
|
||||
$breadcrumb[] = array('dir' => $pathtohere, 'name' => $i);
|
||||
}
|
||||
}
|
||||
|
||||
$list = new OCP\Template('files', 'part.list', '');
|
||||
$list->assign('files', $files, false);
|
||||
$list->assign('publicListView', true);
|
||||
$list->assign('baseURL', OCP\Util::linkToPublic('files').$urlLinkIdentifiers.'&path=', false);
|
||||
$list->assign('downloadURL', OCP\Util::linkToPublic('files').$urlLinkIdentifiers.'&download&path=', false);
|
||||
$breadcrumbNav = new OCP\Template('files', 'part.breadcrumb', '' );
|
||||
$breadcrumbNav->assign('breadcrumb', $breadcrumb, false);
|
||||
$breadcrumbNav->assign('baseURL', OCP\Util::linkToPublic('files').$urlLinkIdentifiers.'&path=', false);
|
||||
$folder = new OCP\Template('files', 'index', '');
|
||||
$folder->assign('fileList', $list->fetchPage(), false);
|
||||
$folder->assign('breadcrumb', $breadcrumbNav->fetchPage(), false);
|
||||
$folder->assign('isCreatable', false);
|
||||
$folder->assign('permissions', 0);
|
||||
$folder->assign('files', $files);
|
||||
$folder->assign('uploadMaxFilesize', 0);
|
||||
$folder->assign('uploadMaxHumanFilesize', 0);
|
||||
$folder->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true)));
|
||||
$tmpl->assign('folder', $folder->fetchPage(), false);
|
||||
$tmpl->assign('allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true)));
|
||||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').$urlLinkIdentifiers.'&download&path='.urlencode($getPath));
|
||||
} else {
|
||||
// Show file preview if viewer is available
|
||||
if ($type == 'file') {
|
||||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').$urlLinkIdentifiers.'&download');
|
||||
} else {
|
||||
$tmpl->assign('downloadURL', OCP\Util::linkToPublic('files').$urlLinkIdentifiers.'&download&path='.urlencode($getPath));
|
||||
}
|
||||
}
|
||||
$tmpl->printPage();
|
||||
}
|
||||
exit();
|
||||
} else {
|
||||
OCP\Util::writeLog('share', 'could not resolve linkItem', \OCP\Util::DEBUG);
|
||||
}
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
$tmpl = new OCP\Template('', '404', 'guest');
|
||||
|
||||
@@ -21,11 +21,11 @@ $(document).ready(function(){
|
||||
}
|
||||
,function(filename){
|
||||
// Action to perform when clicked
|
||||
if (scanFiles.scanning || !$('#dropdown').hasClass('drop-versions')){return;}//workaround to prevent additional http request block scanning feedback
|
||||
if (scanFiles.scanning){return;}//workaround to prevent additional http request block scanning feedback
|
||||
|
||||
var file = $('#dir').val()+'/'+filename;
|
||||
// Check if drop down is already visible for a different file
|
||||
if (($('#dropdown').length > 0)) {
|
||||
if (($('#dropdown').length > 0) && $('#dropdown').hasClass('drop-versions') ) {
|
||||
if (file != $('#dropdown').data('file')) {
|
||||
$('#dropdown').hide('blind', function() {
|
||||
$('#dropdown').remove();
|
||||
@@ -45,7 +45,7 @@ function createVersionsDropdown(filename, files) {
|
||||
|
||||
var historyUrl = OC.linkTo('files_versions', 'history.php') + '?path='+encodeURIComponent( $( '#dir' ).val() ).replace( /%2F/g, '/' )+'/'+encodeURIComponent( filename );
|
||||
|
||||
var html = '<div id="dropdown" class="drop drop-versions" data-file="'+files+'">';
|
||||
var html = '<div id="dropdown" class="drop drop-versions" data-file="'+escapeHTML(files)+'">';
|
||||
html += '<div id="private">';
|
||||
html += '<select data-placeholder="Saved versions" id="found_versions" class="chzen-select" style="width:16em;">';
|
||||
html += '<option value=""></option>';
|
||||
@@ -73,7 +73,6 @@ function createVersionsDropdown(filename, files) {
|
||||
$.each( versions, function(index, row ) {
|
||||
addVersion( row );
|
||||
});
|
||||
$('#found_versions').chosen();
|
||||
} else {
|
||||
$('#found_versions').hide();
|
||||
$('#makelink').hide();
|
||||
|
||||
@@ -64,7 +64,7 @@ class Hooks {
|
||||
$abs_newpath = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$params['newpath'].'.v';
|
||||
if(Storage::isversioned($rel_oldpath)) {
|
||||
$info=pathinfo($abs_newpath);
|
||||
if(!file_exists($info['dirname'])) mkdir($info['dirname'],0700,true);
|
||||
if(!file_exists($info['dirname'])) mkdir($info['dirname'],0750,true);
|
||||
$versions = Storage::getVersions($rel_oldpath);
|
||||
foreach ($versions as $v) {
|
||||
rename($abs_oldpath.$v['version'], $abs_newpath.$v['version']);
|
||||
|
||||
@@ -1,279 +1,278 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Frank Karlitschek <frank@owncloud.org>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Versions
|
||||
*
|
||||
* A class to handle the versioning of files.
|
||||
*/
|
||||
|
||||
namespace OCA_Versions;
|
||||
|
||||
class Storage {
|
||||
|
||||
|
||||
// config.php configuration:
|
||||
// - files_versions
|
||||
// - files_versionsfolder
|
||||
// - files_versionsblacklist
|
||||
// - files_versionsmaxfilesize
|
||||
// - files_versionsinterval
|
||||
// - files_versionmaxversions
|
||||
//
|
||||
// todo:
|
||||
// - finish porting to OC_FilesystemView to enable network transparency
|
||||
// - add transparent compression. first test if it´s worth it.
|
||||
|
||||
const DEFAULTENABLED=true;
|
||||
const DEFAULTBLACKLIST='avi mp3 mpg mp4 ctmp';
|
||||
const DEFAULTMAXFILESIZE=1048576; // 10MB
|
||||
const DEFAULTMININTERVAL=60; // 1 min
|
||||
const DEFAULTMAXVERSIONS=50;
|
||||
|
||||
private static function getUidAndFilename($filename)
|
||||
{
|
||||
if (\OCP\App::isEnabled('files_sharing')
|
||||
&& substr($filename, 0, 7) == '/Shared'
|
||||
&& $source = \OCP\Share::getItemSharedWith('file',
|
||||
substr($filename, 7),
|
||||
\OC_Share_Backend_File::FORMAT_SHARED_STORAGE)) {
|
||||
$filename = $source['path'];
|
||||
$pos = strpos($filename, '/files', 1);
|
||||
$uid = substr($filename, 1, $pos - 1);
|
||||
$filename = substr($filename, $pos + 6);
|
||||
} else {
|
||||
$uid = \OCP\User::getUser();
|
||||
}
|
||||
return array($uid, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* store a new version of a file.
|
||||
*/
|
||||
public function store($filename) {
|
||||
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
|
||||
list($uid, $filename) = self::getUidAndFilename($filename);
|
||||
$files_view = new \OC_FilesystemView('/'.$uid.'/files');
|
||||
$users_view = new \OC_FilesystemView('/'.$uid);
|
||||
|
||||
//check if source file already exist as version to avoid recursions.
|
||||
// todo does this check work?
|
||||
if ($users_view->file_exists($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if filename is a directory
|
||||
if($files_view->is_dir($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check filetype blacklist
|
||||
$blacklist=explode(' ',\OCP\Config::getSystemValue('files_versionsblacklist', Storage::DEFAULTBLACKLIST));
|
||||
foreach($blacklist as $bl) {
|
||||
$parts=explode('.', $filename);
|
||||
$ext=end($parts);
|
||||
if(strtolower($ext)==$bl) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// we should have a source file to work with
|
||||
if (!$files_view->file_exists($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check filesize
|
||||
if($files_view->filesize($filename)>\OCP\Config::getSystemValue('files_versionsmaxfilesize', Storage::DEFAULTMAXFILESIZE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// check mininterval if the file is being modified by the owner (all shared files should be versioned despite mininterval)
|
||||
if ($uid == \OCP\User::getUser()) {
|
||||
$versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
|
||||
$versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath('');
|
||||
$matches=glob($versionsFolderName.'/'.$filename.'.v*');
|
||||
sort($matches);
|
||||
$parts=explode('.v',end($matches));
|
||||
if((end($parts)+Storage::DEFAULTMININTERVAL)>time()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// create all parent folders
|
||||
$dirname = dirname($filename);
|
||||
if(!$users_view->file_exists('/files_versions/'.$dirname)) {
|
||||
$users_view->mkdir('/files_versions/'.$dirname,0700,true);
|
||||
}
|
||||
|
||||
// store a new version of a file
|
||||
$users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'.time());
|
||||
|
||||
// expire old revisions if necessary
|
||||
Storage::expire($filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* rollback to an old version of a file.
|
||||
*/
|
||||
public static function rollback($filename,$revision) {
|
||||
|
||||
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
|
||||
list($uid, $filename) = self::getUidAndFilename($filename);
|
||||
$users_view = new \OC_FilesystemView('/'.$uid);
|
||||
|
||||
// rollback
|
||||
if( @$users_view->copy('files_versions'.$filename.'.v'.$revision, 'files'.$filename) ) {
|
||||
|
||||
return true;
|
||||
|
||||
}else{
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* check if old versions of a file exist.
|
||||
*/
|
||||
public static function isversioned($filename) {
|
||||
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
|
||||
list($uid, $filename) = self::getUidAndFilename($filename);
|
||||
$versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
|
||||
|
||||
$versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath('');
|
||||
|
||||
// check for old versions
|
||||
$matches=glob($versionsFolderName.$filename.'.v*');
|
||||
if(count($matches)>0) {
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief get a list of all available versions of a file in descending chronological order
|
||||
* @param $filename file to find versions of, relative to the user files dir
|
||||
* @param $count number of versions to return
|
||||
* @returns array
|
||||
*/
|
||||
public static function getVersions( $filename, $count = 0 ) {
|
||||
|
||||
if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) {
|
||||
list($uid, $filename) = self::getUidAndFilename($filename);
|
||||
$versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
|
||||
|
||||
$versionsFolderName = \OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath('');
|
||||
$versions = array();
|
||||
|
||||
// fetch for old versions
|
||||
$matches = glob( $versionsFolderName.'/'.$filename.'.v*' );
|
||||
|
||||
sort( $matches );
|
||||
|
||||
$i = 0;
|
||||
|
||||
$files_view = new \OC_FilesystemView('/'.$uid.'/files');
|
||||
$local_file = $files_view->getLocalFile($filename);
|
||||
foreach( $matches as $ma ) {
|
||||
|
||||
$i++;
|
||||
$versions[$i]['cur'] = 0;
|
||||
$parts = explode( '.v', $ma );
|
||||
$versions[$i]['version'] = ( end( $parts ) );
|
||||
|
||||
// if file with modified date exists, flag it in array as currently enabled version
|
||||
( \md5_file( $ma ) == \md5_file( $local_file ) ? $versions[$i]['fileMatch'] = 1 : $versions[$i]['fileMatch'] = 0 );
|
||||
|
||||
}
|
||||
|
||||
$versions = array_reverse( $versions );
|
||||
|
||||
foreach( $versions as $key => $value ) {
|
||||
|
||||
// flag the first matched file in array (which will have latest modification date) as current version
|
||||
if ( $value['fileMatch'] ) {
|
||||
|
||||
$value['cur'] = 1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$versions = array_reverse( $versions );
|
||||
|
||||
// only show the newest commits
|
||||
if( $count != 0 and ( count( $versions )>$count ) ) {
|
||||
|
||||
$versions = array_slice( $versions, count( $versions ) - $count );
|
||||
|
||||
}
|
||||
|
||||
return( $versions );
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
// if versioning isn't enabled then return an empty array
|
||||
return( array() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erase a file's versions which exceed the set quota
|
||||
*/
|
||||
public static function expire($filename) {
|
||||
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
|
||||
list($uid, $filename) = self::getUidAndFilename($filename);
|
||||
$versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
|
||||
|
||||
$versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath('');
|
||||
|
||||
// check for old versions
|
||||
$matches = glob( $versionsFolderName.'/'.$filename.'.v*' );
|
||||
|
||||
if( count( $matches ) > \OCP\Config::getSystemValue( 'files_versionmaxversions', Storage::DEFAULTMAXVERSIONS ) ) {
|
||||
|
||||
$numberToDelete = count($matches) - \OCP\Config::getSystemValue( 'files_versionmaxversions', Storage::DEFAULTMAXVERSIONS );
|
||||
|
||||
// delete old versions of a file
|
||||
$deleteItems = array_slice( $matches, 0, $numberToDelete );
|
||||
|
||||
foreach( $deleteItems as $de ) {
|
||||
|
||||
unlink( $versionsFolderName.'/'.$filename.'.v'.$de );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erase all old versions of all user files
|
||||
* @return true/false
|
||||
*/
|
||||
public function expireAll() {
|
||||
$view = \OCP\Files::getStorage('files_versions');
|
||||
return $view->deleteAll('', true);
|
||||
}
|
||||
}
|
||||
<?php
|
||||
/**
|
||||
* Copyright (c) 2012 Frank Karlitschek <frank@owncloud.org>
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Versions
|
||||
*
|
||||
* A class to handle the versioning of files.
|
||||
*/
|
||||
|
||||
namespace OCA_Versions;
|
||||
|
||||
class Storage {
|
||||
|
||||
|
||||
// config.php configuration:
|
||||
// - files_versions
|
||||
// - files_versionsfolder
|
||||
// - files_versionsblacklist
|
||||
// - files_versionsmaxfilesize
|
||||
// - files_versionsinterval
|
||||
// - files_versionmaxversions
|
||||
//
|
||||
// todo:
|
||||
// - finish porting to OC_FilesystemView to enable network transparency
|
||||
// - add transparent compression. first test if it´s worth it.
|
||||
|
||||
const DEFAULTENABLED=true;
|
||||
const DEFAULTBLACKLIST='avi mp3 mpg mp4 ctmp';
|
||||
const DEFAULTMAXFILESIZE=1048576; // 10MB
|
||||
const DEFAULTMININTERVAL=60; // 1 min
|
||||
const DEFAULTMAXVERSIONS=50;
|
||||
|
||||
private static function getUidAndFilename($filename)
|
||||
{
|
||||
if (\OCP\App::isEnabled('files_sharing')
|
||||
&& substr($filename, 0, 7) == '/Shared'
|
||||
&& $source = \OCP\Share::getItemSharedWith('file',
|
||||
substr($filename, 7),
|
||||
\OC_Share_Backend_File::FORMAT_SHARED_STORAGE)) {
|
||||
$filename = $source['path'];
|
||||
$pos = strpos($filename, '/files', 1);
|
||||
$uid = substr($filename, 1, $pos - 1);
|
||||
$filename = substr($filename, $pos + 6);
|
||||
} else {
|
||||
$uid = \OCP\User::getUser();
|
||||
}
|
||||
return array($uid, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* store a new version of a file.
|
||||
*/
|
||||
public function store($filename) {
|
||||
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
|
||||
list($uid, $filename) = self::getUidAndFilename($filename);
|
||||
$files_view = new \OC_FilesystemView('/'.\OCP\User::getUser() .'/files');
|
||||
$users_view = new \OC_FilesystemView('/'.\OCP\User::getUser());
|
||||
|
||||
//check if source file already exist as version to avoid recursions.
|
||||
// todo does this check work?
|
||||
if ($users_view->file_exists($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if filename is a directory
|
||||
if($files_view->is_dir($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check filetype blacklist
|
||||
$blacklist=explode(' ',\OCP\Config::getSystemValue('files_versionsblacklist', Storage::DEFAULTBLACKLIST));
|
||||
foreach($blacklist as $bl) {
|
||||
$parts=explode('.', $filename);
|
||||
$ext=end($parts);
|
||||
if(strtolower($ext)==$bl) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// we should have a source file to work with
|
||||
if (!$files_view->file_exists($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check filesize
|
||||
if($files_view->filesize($filename)>\OCP\Config::getSystemValue('files_versionsmaxfilesize', Storage::DEFAULTMAXFILESIZE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// check mininterval if the file is being modified by the owner (all shared files should be versioned despite mininterval)
|
||||
if ($uid == \OCP\User::getUser()) {
|
||||
$versions_fileview = new \OC_FilesystemView('/'.\OCP\User::getUser().'/files_versions');
|
||||
$versionsName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename);
|
||||
$versionsFolderName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('');
|
||||
$matches=glob($versionsName.'.v*');
|
||||
sort($matches);
|
||||
$parts=explode('.v',end($matches));
|
||||
if((end($parts)+Storage::DEFAULTMININTERVAL)>time()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// create all parent folders
|
||||
$info=pathinfo($filename);
|
||||
if(!file_exists($versionsFolderName.'/'.$info['dirname'])) {
|
||||
mkdir($versionsFolderName.'/'.$info['dirname'],0750,true);
|
||||
}
|
||||
|
||||
// store a new version of a file
|
||||
$users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'.time());
|
||||
|
||||
// expire old revisions if necessary
|
||||
Storage::expire($filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* rollback to an old version of a file.
|
||||
*/
|
||||
public static function rollback($filename,$revision) {
|
||||
|
||||
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
|
||||
list($uid, $filename) = self::getUidAndFilename($filename);
|
||||
$users_view = new \OC_FilesystemView('/'.\OCP\User::getUser());
|
||||
|
||||
// rollback
|
||||
if( @$users_view->copy('files_versions'.$filename.'.v'.$revision, 'files'.$filename) ) {
|
||||
|
||||
return true;
|
||||
|
||||
}else{
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* check if old versions of a file exist.
|
||||
*/
|
||||
public static function isversioned($filename) {
|
||||
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
|
||||
list($uid, $filename) = self::getUidAndFilename($filename);
|
||||
$versions_fileview = new \OC_FilesystemView('/'.\OCP\User::getUser().'/files_versions');
|
||||
|
||||
$versionsName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename);
|
||||
|
||||
// check for old versions
|
||||
$matches=glob($versionsName.'.v*');
|
||||
if(count($matches)>0) {
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief get a list of all available versions of a file in descending chronological order
|
||||
* @param $filename file to find versions of, relative to the user files dir
|
||||
* @param $count number of versions to return
|
||||
* @returns array
|
||||
*/
|
||||
public static function getVersions( $filename, $count = 0 ) {
|
||||
if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) {
|
||||
list($uid, $filename) = self::getUidAndFilename($filename);
|
||||
$versions_fileview = new \OC_FilesystemView('/'.\OCP\User::getUser().'/files_versions');
|
||||
|
||||
$versionsName = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename);
|
||||
$versions = array();
|
||||
// fetch for old versions
|
||||
$matches = glob( $versionsName.'.v*' );
|
||||
|
||||
sort( $matches );
|
||||
|
||||
$i = 0;
|
||||
|
||||
$files_view = new \OC_FilesystemView('/'.\OCP\User::getUser().'/files');
|
||||
$local_file = $files_view->getLocalFile($filename);
|
||||
foreach( $matches as $ma ) {
|
||||
|
||||
$i++;
|
||||
$versions[$i]['cur'] = 0;
|
||||
$parts = explode( '.v', $ma );
|
||||
$versions[$i]['version'] = ( end( $parts ) );
|
||||
|
||||
// if file with modified date exists, flag it in array as currently enabled version
|
||||
( \md5_file( $ma ) == \md5_file( $local_file ) ? $versions[$i]['fileMatch'] = 1 : $versions[$i]['fileMatch'] = 0 );
|
||||
|
||||
}
|
||||
|
||||
$versions = array_reverse( $versions );
|
||||
|
||||
foreach( $versions as $key => $value ) {
|
||||
|
||||
// flag the first matched file in array (which will have latest modification date) as current version
|
||||
if ( $value['fileMatch'] ) {
|
||||
|
||||
$value['cur'] = 1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$versions = array_reverse( $versions );
|
||||
|
||||
// only show the newest commits
|
||||
if( $count != 0 and ( count( $versions )>$count ) ) {
|
||||
|
||||
$versions = array_slice( $versions, count( $versions ) - $count );
|
||||
|
||||
}
|
||||
|
||||
return( $versions );
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
// if versioning isn't enabled then return an empty array
|
||||
return( array() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erase a file's versions which exceed the set quota
|
||||
*/
|
||||
public static function expire($filename) {
|
||||
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
|
||||
list($uid, $filename) = self::getUidAndFilename($filename);
|
||||
$versions_fileview = new \OC_FilesystemView('/'.$uid.'/files_versions');
|
||||
|
||||
$versionsName=\OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath($filename);
|
||||
|
||||
// check for old versions
|
||||
$matches = glob( $versionsName.'.v*' );
|
||||
|
||||
if( count( $matches ) > \OCP\Config::getSystemValue( 'files_versionmaxversions', Storage::DEFAULTMAXVERSIONS ) ) {
|
||||
|
||||
$numberToDelete = count($matches) - \OCP\Config::getSystemValue( 'files_versionmaxversions', Storage::DEFAULTMAXVERSIONS );
|
||||
|
||||
// delete old versions of a file
|
||||
$deleteItems = array_slice( $matches, 0, $numberToDelete );
|
||||
|
||||
foreach( $deleteItems as $de ) {
|
||||
|
||||
unlink( $versionsName.'.v'.$de );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erase all old versions of all user files
|
||||
* @return true/false
|
||||
*/
|
||||
public function expireAll() {
|
||||
$view = \OCP\Files::getStorage('files_versions');
|
||||
return $view->deleteAll('', true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
</field>
|
||||
|
||||
<index>
|
||||
<name>ldap_group_members</name>
|
||||
<name>ldap_group_members_index</name>
|
||||
<unique>true</unique>
|
||||
<field>
|
||||
<name>owncloudname</name>
|
||||
|
||||
@@ -34,22 +34,49 @@ $groupBE = new \OCA\user_ldap\GROUP_LDAP();
|
||||
$groupBE->setConnector($connector);
|
||||
|
||||
foreach($objects as $object) {
|
||||
$fetchDNSql = 'SELECT `ldap_dn`, `owncloud_name` FROM `*PREFIX*ldap_'.$object.'_mapping` WHERE `directory_uuid` = ""';
|
||||
$updateSql = 'UPDATE `*PREFIX*ldap_'.$object.'_mapping` SET `ldap_DN` = ?, `directory_uuid` = ? WHERE `ldap_dn` = ?';
|
||||
$fetchDNSql = '
|
||||
SELECT `ldap_dn`, `owncloud_name`, `directory_uuid`
|
||||
FROM `*PREFIX*ldap_'.$object.'_mapping`';
|
||||
$updateSql = '
|
||||
UPDATE `*PREFIX*ldap_'.$object.'_mapping`
|
||||
SET `ldap_DN` = ?, `directory_uuid` = ?
|
||||
WHERE `ldap_dn` = ?';
|
||||
|
||||
$query = OCP\DB::prepare($fetchDNSql);
|
||||
$res = $query->execute();
|
||||
$DNs = $res->fetchAll();
|
||||
$updateQuery = OCP\DB::prepare($updateSql);
|
||||
foreach($DNs as $dn) {
|
||||
$newDN = mb_strtolower($dn['ldap_dn'], 'UTF-8');
|
||||
if($object == 'user') {
|
||||
$newDN = escapeDN(mb_strtolower($dn['ldap_dn'], 'UTF-8'));
|
||||
if(!empty($dn['directory_uuid'])) {
|
||||
$uuid = $dn['directory_uuid'];
|
||||
} elseif($object == 'user') {
|
||||
$uuid = $userBE->getUUID($newDN);
|
||||
//fix home folder to avoid new ones depending on the configuration
|
||||
$userBE->getHome($dn['owncloud_name']);
|
||||
} else {
|
||||
$uuid = $groupBE->getUUID($newDN);
|
||||
}
|
||||
$updateQuery->execute(array($newDN, $uuid, $dn['ldap_dn']));
|
||||
try {
|
||||
$updateQuery->execute(array($newDN, $uuid, $dn['ldap_dn']));
|
||||
} catch(Exception $e) {
|
||||
\OCP\Util::writeLog('user_ldap', 'Could not update '.$object.' '.$dn['ldap_dn'].' in the mappings table. ', \OCP\Util::WARN);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function escapeDN($dn) {
|
||||
$aDN = ldap_explode_dn($dn, false);
|
||||
unset($aDN['count']);
|
||||
foreach($aDN as $key => $part) {
|
||||
$value = substr($part, strpos($part, '=')+1);
|
||||
$escapedValue = strtr($value, Array(','=>'\2c', '='=>'\3d', '+'=>'\2b',
|
||||
'<'=>'\3c', '>'=>'\3e', ';'=>'\3b', '\\'=>'\5c',
|
||||
'"'=>'\22', '#'=>'\23'));
|
||||
$part = str_replace($part, $value, $escapedValue);
|
||||
}
|
||||
$dn = implode(',', $aDN);
|
||||
|
||||
return $dn;
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.3.0.0
|
||||
0.3.0.1
|
||||
@@ -28,10 +28,11 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface {
|
||||
|
||||
public function setConnector(lib\Connection &$connection) {
|
||||
parent::setConnector($connection);
|
||||
if(empty($this->connection->ldapGroupFilter) || empty($this->connection->ldapGroupMemberAssocAttr)) {
|
||||
$this->enabled = false;
|
||||
$filter = $this->connection->ldapGroupFilter;
|
||||
$gassoc = $this->connection->ldapGroupMemberAssocAttr;
|
||||
if(!empty($filter) && !empty($gassoc)) {
|
||||
$this->enabled = true;
|
||||
}
|
||||
$this->enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,12 +97,13 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface {
|
||||
if(!$this->enabled) {
|
||||
return array();
|
||||
}
|
||||
if($this->connection->isCached('getUserGroups'.$uid)) {
|
||||
return $this->connection->getFromCache('getUserGroups'.$uid);
|
||||
$cacheKey = 'getUserGroups'.$uid;
|
||||
if($this->connection->isCached($cacheKey)) {
|
||||
return $this->connection->getFromCache($cacheKey);
|
||||
}
|
||||
$userDN = $this->username2dn($uid);
|
||||
if(!$userDN) {
|
||||
$this->connection->writeToCache('getUserGroups'.$uid, array());
|
||||
$this->connection->writeToCache($cacheKey, array());
|
||||
return array();
|
||||
}
|
||||
|
||||
@@ -124,7 +126,7 @@ class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface {
|
||||
));
|
||||
$groups = $this->fetchListOfGroups($filter, array($this->connection->ldapGroupDisplayName,'dn'));
|
||||
$groups = array_unique($this->ownCloudGroupNames($groups), SORT_LOCALE_STRING);
|
||||
$this->connection->writeToCache('getUserGroups'.$uid, $groups);
|
||||
$this->connection->writeToCache($cacheKey, $groups);
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
@@ -38,9 +38,11 @@ abstract class Access {
|
||||
* @brief reads a given attribute for an LDAP record identified by a DN
|
||||
* @param $dn the record in question
|
||||
* @param $attr the attribute that shall be retrieved
|
||||
* @returns the values in an array on success, false otherwise
|
||||
* if empty, just check the record's existence
|
||||
* @returns an array of values on success or an empty
|
||||
* array if $attr is empty, false otherwise
|
||||
*
|
||||
* Reads an attribute from an LDAP entry
|
||||
* Reads an attribute from an LDAP entry or check if entry exists
|
||||
*/
|
||||
public function readAttribute($dn, $attr) {
|
||||
if(!$this->checkConnection()) {
|
||||
@@ -53,12 +55,18 @@ abstract class Access {
|
||||
\OCP\Util::writeLog('user_ldap', 'LDAP resource not available.', \OCP\Util::DEBUG);
|
||||
return false;
|
||||
}
|
||||
//Slashes should only be escaped in filters, not bases.
|
||||
$dn = $this->DNasBaseParameter($dn);
|
||||
$rr = @ldap_read($cr, $dn, 'objectClass=*', array($attr));
|
||||
if(!is_resource($rr)) {
|
||||
\OCP\Util::writeLog('user_ldap', 'readAttribute '.$attr.' failed for DN '.$dn, \OCP\Util::DEBUG);
|
||||
\OCP\Util::writeLog('user_ldap', 'readAttribute failed for DN '.$dn, \OCP\Util::DEBUG);
|
||||
//in case an error occurs , e.g. object does not exist
|
||||
return false;
|
||||
}
|
||||
if (empty($attr)) {
|
||||
\OCP\Util::writeLog('user_ldap', 'readAttribute: '.$dn.' found', \OCP\Util::DEBUG);
|
||||
return array();
|
||||
}
|
||||
$er = ldap_first_entry($cr, $rr);
|
||||
//LDAP attributes are not case sensitive
|
||||
$result = \OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8');
|
||||
@@ -67,7 +75,13 @@ abstract class Access {
|
||||
if(isset($result[$attr]) && $result[$attr]['count'] > 0) {
|
||||
$values = array();
|
||||
for($i=0;$i<$result[$attr]['count'];$i++) {
|
||||
$values[] = $this->resemblesDN($attr) ? $this->sanitizeDN($result[$attr][$i]) : $result[$attr][$i];
|
||||
if($this->resemblesDN($attr)) {
|
||||
$values[] = $this->sanitizeDN($result[$attr][$i]);
|
||||
} elseif(strtolower($attr) == 'objectguid') {
|
||||
$values[] = $this->convertObjectGUID2Str($result[$attr][$i]);
|
||||
} else {
|
||||
$values[] = $result[$attr][$i];
|
||||
}
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
@@ -101,6 +115,21 @@ abstract class Access {
|
||||
//make comparisons and everything work
|
||||
$dn = mb_strtolower($dn, 'UTF-8');
|
||||
|
||||
//escape DN values according to RFC 2253 – this is already done by ldap_explode_dn
|
||||
//to use the DN in search filters, \ needs to be escaped to \5c additionally
|
||||
//to use them in bases, we convert them back to simple backslashes in readAttribute()
|
||||
$replacements = array(
|
||||
'\,' => '\5c2C',
|
||||
'\=' => '\5c3D',
|
||||
'\+' => '\5c2B',
|
||||
'\<' => '\5c3C',
|
||||
'\>' => '\5c3E',
|
||||
'\;' => '\5c3B',
|
||||
'\"' => '\5c22',
|
||||
'\#' => '\5c23',
|
||||
);
|
||||
$dn = str_replace(array_keys($replacements),array_values($replacements), $dn);
|
||||
|
||||
return $dn;
|
||||
}
|
||||
|
||||
@@ -209,7 +238,6 @@ abstract class Access {
|
||||
* returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN
|
||||
*/
|
||||
public function dn2ocname($dn, $ldapname = null, $isUser = true) {
|
||||
$dn = $this->sanitizeDN($dn);
|
||||
$table = $this->getMapTable($isUser);
|
||||
if($isUser) {
|
||||
$fncFindMappedName = 'findMappedUser';
|
||||
@@ -339,7 +367,8 @@ abstract class Access {
|
||||
$ownCloudNames = array();
|
||||
|
||||
foreach($ldapObjects as $ldapObject) {
|
||||
$ocname = $this->dn2ocname($ldapObject['dn'], $ldapObject[$nameAttribute], $isUsers);
|
||||
$nameByLDAP = isset($ldapObject[$nameAttribute]) ? $ldapObject[$nameAttribute] : null;
|
||||
$ocname = $this->dn2ocname($ldapObject['dn'], $nameByLDAP, $isUsers);
|
||||
if($ocname) {
|
||||
$ownCloudNames[] = $ocname;
|
||||
}
|
||||
@@ -405,7 +434,6 @@ abstract class Access {
|
||||
*/
|
||||
private function mapComponent($dn, $ocname, $isUser = true) {
|
||||
$table = $this->getMapTable($isUser);
|
||||
$dn = $this->sanitizeDN($dn);
|
||||
|
||||
$sqlAdjustment = '';
|
||||
$dbtype = \OCP\Config::getSystemValue('dbtype');
|
||||
@@ -503,6 +531,12 @@ abstract class Access {
|
||||
$link_resource = $this->connection->getConnectionResource();
|
||||
if(is_resource($link_resource)) {
|
||||
$sr = ldap_search($link_resource, $base, $filter, $attr);
|
||||
if(!is_resource($sr)) {
|
||||
$errmsg = '('.ldap_errno($link_resource).') ' . ldap_error($link_resource);
|
||||
$errmsg .= ', search filter: ' . $filter;
|
||||
\OCP\Util::writeLog('user_ldap', 'Search: no result resource, LDAP error message: ' . $errmsg, \OCP\Util::ERROR);
|
||||
return array();
|
||||
}
|
||||
$findings = ldap_get_entries($link_resource, $sr );
|
||||
|
||||
// if we're here, probably no connection resource is returned.
|
||||
@@ -622,6 +656,7 @@ abstract class Access {
|
||||
}
|
||||
|
||||
public function areCredentialsValid($name, $password) {
|
||||
$name = $this->DNasBaseParameter($name);
|
||||
$testConnection = clone $this->connection;
|
||||
$credentials = array(
|
||||
'ldapAgentName' => $name,
|
||||
@@ -664,6 +699,7 @@ abstract class Access {
|
||||
|
||||
public function getUUID($dn) {
|
||||
if($this->detectUuidAttribute($dn)) {
|
||||
\OCP\Util::writeLog('user_ldap', 'UUID Checking \ UUID for '.$dn.' using '. $this->connection->ldapUuidAttribute, \OCP\Util::DEBUG);
|
||||
$uuid = $this->readAttribute($dn, $this->connection->ldapUuidAttribute);
|
||||
if(!is_array($uuid) && $this->connection->ldapOverrideUuidAttribute) {
|
||||
$this->detectUuidAttribute($dn, true);
|
||||
@@ -679,4 +715,44 @@ abstract class Access {
|
||||
}
|
||||
return $uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief converts a binary ObjectGUID into a string representation
|
||||
* @param $oguid the ObjectGUID in it's binary form as retrieved from AD
|
||||
* @returns String
|
||||
*
|
||||
* converts a binary ObjectGUID into a string representation
|
||||
* http://www.php.net/manual/en/function.ldap-get-values-len.php#73198
|
||||
*/
|
||||
private function convertObjectGUID2Str($oguid) {
|
||||
$hex_guid = bin2hex($oguid);
|
||||
$hex_guid_to_guid_str = '';
|
||||
for($k = 1; $k <= 4; ++$k) {
|
||||
$hex_guid_to_guid_str .= substr($hex_guid, 8 - 2 * $k, 2);
|
||||
}
|
||||
$hex_guid_to_guid_str .= '-';
|
||||
for($k = 1; $k <= 2; ++$k) {
|
||||
$hex_guid_to_guid_str .= substr($hex_guid, 12 - 2 * $k, 2);
|
||||
}
|
||||
$hex_guid_to_guid_str .= '-';
|
||||
for($k = 1; $k <= 2; ++$k) {
|
||||
$hex_guid_to_guid_str .= substr($hex_guid, 16 - 2 * $k, 2);
|
||||
}
|
||||
$hex_guid_to_guid_str .= '-' . substr($hex_guid, 16, 4);
|
||||
$hex_guid_to_guid_str .= '-' . substr($hex_guid, 20);
|
||||
|
||||
return strtoupper($hex_guid_to_guid_str);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief converts a stored DN so it can be used as base parameter for LDAP queries
|
||||
* @param $dn the DN
|
||||
* @returns String
|
||||
*
|
||||
* converts a stored DN so it can be used as base parameter for LDAP queries
|
||||
* internally we store them for usage in LDAP filters
|
||||
*/
|
||||
private function DNasBaseParameter($dn) {
|
||||
return str_replace('\\5c', '\\', $dn);
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ class Connection {
|
||||
\OCP\Util::writeLog('user_ldap', 'Set config ldapUuidAttribute to '.$value, \OCP\Util::DEBUG);
|
||||
$this->config[$name] = $value;
|
||||
if(!empty($this->configID)) {
|
||||
\OCP\Config::getAppValue($this->configID, 'ldap_uuid_attribute', $value);
|
||||
\OCP\Config::setAppValue($this->configID, 'ldap_uuid_attribute', $value);
|
||||
}
|
||||
$changed = true;
|
||||
}
|
||||
|
||||
@@ -26,16 +26,12 @@ OCP\Util::addscript('user_ldap', 'settings');
|
||||
OCP\Util::addstyle('user_ldap', 'settings');
|
||||
|
||||
if ($_POST) {
|
||||
$clearCache = false;
|
||||
foreach($params as $param) {
|
||||
if(isset($_POST[$param])) {
|
||||
$clearCache = true;
|
||||
if('ldap_agent_password' == $param) {
|
||||
OCP\Config::setAppValue('user_ldap', $param, base64_encode($_POST[$param]));
|
||||
} elseif('ldap_cache_ttl' == $param) {
|
||||
if(OCP\Config::getAppValue('user_ldap', $param,'') != $_POST[$param]) {
|
||||
$ldap = new \OCA\user_ldap\lib\Connection('user_ldap');
|
||||
$ldap->clearCache();
|
||||
OCP\Config::setAppValue('user_ldap', $param, $_POST[$param]);
|
||||
}
|
||||
} elseif('home_folder_naming_rule' == $param) {
|
||||
$value = empty($_POST[$param]) ? 'opt:username' : 'attr:'.$_POST[$param];
|
||||
OCP\Config::setAppValue('user_ldap', $param, $value);
|
||||
@@ -54,6 +50,10 @@ if ($_POST) {
|
||||
OCP\Config::setAppValue('user_ldap', $param, 0);
|
||||
}
|
||||
}
|
||||
if($clearCache) {
|
||||
$ldap = new \OCA\user_ldap\lib\Connection('user_ldap');
|
||||
$ldap->clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
// fill template
|
||||
|
||||
@@ -29,11 +29,13 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface {
|
||||
|
||||
private function updateQuota($dn) {
|
||||
$quota = null;
|
||||
if(!empty($this->connection->ldapQuotaDefault)) {
|
||||
$quota = $this->connection->ldapQuotaDefault;
|
||||
$quotaDefault = $this->connection->ldapQuotaDefault;
|
||||
$quotaAttribute = $this->connection->ldapQuotaAttribute;
|
||||
if(!empty($quotaDefault)) {
|
||||
$quota = $quotaDefault;
|
||||
}
|
||||
if(!empty($this->connection->ldapQuotaAttribute)) {
|
||||
$aQuota = $this->readAttribute($dn, $this->connection->ldapQuotaAttribute);
|
||||
if(!empty($quotaAttribute)) {
|
||||
$aQuota = $this->readAttribute($dn, $quotaAttribute);
|
||||
|
||||
if($aQuota && (count($aQuota) > 0)) {
|
||||
$quota = $aQuota[0];
|
||||
@@ -46,8 +48,9 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface {
|
||||
|
||||
private function updateEmail($dn) {
|
||||
$email = null;
|
||||
if(!empty($this->connection->ldapEmailAttribute)) {
|
||||
$aEmail = $this->readAttribute($dn, $this->connection->ldapEmailAttribute);
|
||||
$emailAttribute = $this->connection->ldapEmailAttribute;
|
||||
if(!empty($emailAttribute)) {
|
||||
$aEmail = $this->readAttribute($dn, $emailAttribute);
|
||||
if($aEmail && (count($aEmail) > 0)) {
|
||||
$email = $aEmail[0];
|
||||
}
|
||||
@@ -138,9 +141,8 @@ class USER_LDAP extends lib\Access implements \OCP\UserInterface {
|
||||
return false;
|
||||
}
|
||||
|
||||
//if user really still exists, we will be able to read his objectclass
|
||||
$objcs = $this->readAttribute($dn, 'objectclass');
|
||||
if(!$objcs || empty($objcs)) {
|
||||
//check if user really still exists by reading its entry
|
||||
if(!is_array($this->readAttribute($dn, ''))) {
|
||||
$this->connection->writeToCache('userExists'.$uid, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
require_once 'apps/user_webdavauth/user_webdavauth.php';
|
||||
|
||||
OC_APP::registerAdmin('user_webdavauth','settings');
|
||||
OC_APP::registerAdmin('user_webdavauth', 'settings');
|
||||
|
||||
OC_User::registerBackend("WEBDAVAUTH");
|
||||
OC_User::useBackend( "WEBDAVAUTH" );
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
<info>
|
||||
<id>user_webdavauth</id>
|
||||
<name>WebDAV user backend</name>
|
||||
<description>Authenticate Users by a WebDAV call</description>
|
||||
<version>1.0</version>
|
||||
<description>Authenticate users by a WebDAV call. You can use any WebDAV server, ownCloud server or other webserver to authenticate. It should return http 200 for right credentials and http 401 for wrong ones.</description>
|
||||
<licence>AGPL</licence>
|
||||
<author>Frank Karlitschek</author>
|
||||
<require>4.9</require>
|
||||
<shipped>true</shipped>
|
||||
<types>
|
||||
<authentication/>
|
||||
</types>
|
||||
</info>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
1.1.0.0
|
||||
@@ -21,7 +21,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
print_r($_POST);
|
||||
if($_POST) {
|
||||
|
||||
if(isset($_POST['webdav_url'])) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<form id="webdavauth" action="#" method="post">
|
||||
<fieldset class="personalblock">
|
||||
<legend><strong>WebDAV Authentication</strong></legend>
|
||||
<p><label for="webdav_url"><?php echo $l->t('webdav_url');?><input type="text" id="webdav_url" name="webdav_url" value="<?php echo $_['webdav_url']; ?>"></label>
|
||||
<p><label for="webdav_url"><?php echo $l->t('WebDAV URL: http://');?><input type="text" id="webdav_url" name="webdav_url" value="<?php echo $_['webdav_url']; ?>"></label>
|
||||
<input type="submit" value="Save" />
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
@@ -30,37 +30,36 @@ class OC_USER_WEBDAVAUTH extends OC_User_Backend {
|
||||
|
||||
public function createUser() {
|
||||
// Can't create user
|
||||
OC_Log::write('OC_USER_WEBDAVAUTH', 'Not possible to create users from web frontend using WebDAV user backend',3);
|
||||
OC_Log::write('OC_USER_WEBDAVAUTH', 'Not possible to create users from web frontend using WebDAV user backend', 3);
|
||||
return false;
|
||||
}
|
||||
|
||||
public function deleteUser() {
|
||||
public function deleteUser($uid) {
|
||||
// Can't delete user
|
||||
OC_Log::write('OC_USER_WEBDAVAUTH', 'Not possible to delete users from web frontend using WebDAV user backend',3);
|
||||
OC_Log::write('OC_USER_WEBDAVAUTH', 'Not possible to delete users from web frontend using WebDAV user backend', 3);
|
||||
return false;
|
||||
}
|
||||
|
||||
public function setPassword ( $uid, $password ) {
|
||||
// We can't change user password
|
||||
OC_Log::write('OC_USER_WEBDAVAUTH', 'Not possible to change password for users from web frontend using WebDAV user backend',3);
|
||||
OC_Log::write('OC_USER_WEBDAVAUTH', 'Not possible to change password for users from web frontend using WebDAV user backend', 3);
|
||||
return false;
|
||||
}
|
||||
|
||||
public function checkPassword( $uid, $password ) {
|
||||
|
||||
$url= 'http://'.urlencode($uid).':'.urlencode($password).'@'.$this->webdavauth_url;
|
||||
$headers = get_headers($url);
|
||||
if($headers==false) {
|
||||
OC_Log::write('OC_USER_WEBDAVAUTH', 'Not possible to connect to WebDAV Url: "'.$this->webdavauth_url.'" ' ,3);
|
||||
OC_Log::write('OC_USER_WEBDAVAUTH', 'Not possible to connect to WebDAV Url: "'.$this->webdavauth_url.'" ', 3);
|
||||
return false;
|
||||
|
||||
}
|
||||
$returncode= substr($headers[0], 9, 3);
|
||||
|
||||
if($returncode=='401') {
|
||||
return false;
|
||||
return(false);
|
||||
}else{
|
||||
return true;
|
||||
return($uid);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -68,14 +67,15 @@ class OC_USER_WEBDAVAUTH extends OC_User_Backend {
|
||||
/*
|
||||
* we don´t know if a user exists without the password. so we have to return false all the time
|
||||
*/
|
||||
public function userExists( $uid ) {
|
||||
return false;
|
||||
public function userExists( $uid ){
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* we don´t know the users so all we can do it return an empty array here
|
||||
*/
|
||||
public function getUsers() {
|
||||
public function getUsers($search = '', $limit = 10, $offset = 0) {
|
||||
$returnArray = array();
|
||||
|
||||
return $returnArray;
|
||||
|
||||
@@ -30,6 +30,12 @@ $CONFIG = array(
|
||||
/* Force use of HTTPS connection (true = use HTTPS) */
|
||||
"forcessl" => false,
|
||||
|
||||
/* The automatic hostname detection of ownCloud can fail in certain reverse proxy situations. This option allows to manually override the automatic detection. You can also add a port. For example "www.example.com:88" */
|
||||
"overwritehost" => "",
|
||||
|
||||
/* The automatic protocol detection of ownCloud can fail in certain reverse proxy situations. This option allows to manually override the protocol detection. For example "https" */
|
||||
"overwriteprotocol" => "",
|
||||
|
||||
/* Theme to use for ownCloud */
|
||||
"theme" => "",
|
||||
|
||||
@@ -104,4 +110,4 @@ $CONFIG = array(
|
||||
'writable' => true,
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
|
||||
+11
-5
@@ -28,13 +28,19 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo
|
||||
case 'share':
|
||||
if (isset($_POST['shareType']) && isset($_POST['shareWith']) && isset($_POST['permissions'])) {
|
||||
try {
|
||||
if ((int)$_POST['shareType'] === OCP\Share::SHARE_TYPE_LINK && $_POST['shareWith'] == '') {
|
||||
$shareType = (int)$_POST['shareType'];
|
||||
$shareWith = $_POST['shareWith'];
|
||||
if ($shareType === OCP\Share::SHARE_TYPE_LINK && $shareWith == '') {
|
||||
$shareWith = null;
|
||||
} else {
|
||||
$shareWith = $_POST['shareWith'];
|
||||
}
|
||||
OCP\Share::shareItem($_POST['itemType'], $_POST['itemSource'], (int)$_POST['shareType'], $shareWith, $_POST['permissions']);
|
||||
OC_JSON::success();
|
||||
|
||||
$token = OCP\Share::shareItem($_POST['itemType'], $_POST['itemSource'], $shareType, $shareWith, $_POST['permissions']);
|
||||
|
||||
if (is_string($token)) {
|
||||
OC_JSON::success(array('data' => array('token' => $token)));
|
||||
} else {
|
||||
OC_JSON::success();
|
||||
}
|
||||
} catch (Exception $exception) {
|
||||
OC_JSON::error(array('data' => array('message' => $exception->getMessage())));
|
||||
}
|
||||
|
||||
+12
-3
@@ -42,7 +42,11 @@ OC.EventSource=function(src,data){
|
||||
}
|
||||
dataStr+='requesttoken='+OC.Request.Token;
|
||||
if(!this.useFallBack && typeof EventSource !='undefined'){
|
||||
this.source=new EventSource(src+'?'+dataStr);
|
||||
var joinChar = '&';
|
||||
if(src.indexOf('?') == -1) {
|
||||
joinChar = '?';
|
||||
}
|
||||
this.source=new EventSource(src+joinChar+dataStr);
|
||||
this.source.onmessage=function(e){
|
||||
for(var i=0;i<this.typelessListeners.length;i++){
|
||||
this.typelessListeners[i](JSON.parse(e.data));
|
||||
@@ -54,7 +58,12 @@ OC.EventSource=function(src,data){
|
||||
this.iframe=$('<iframe/>');
|
||||
this.iframe.attr('id',iframeId);
|
||||
this.iframe.hide();
|
||||
this.iframe.attr('src',src+'?fallback=true&fallback_id='+OC.EventSource.iframeCount+'&'+dataStr);
|
||||
|
||||
var joinChar = '&';
|
||||
if(src.indexOf('?') == -1) {
|
||||
joinChar = '?';
|
||||
}
|
||||
this.iframe.attr('src',src+joinChar+'fallback=true&fallback_id='+OC.EventSource.iframeCount+'&'+dataStr);
|
||||
$('body').append(this.iframe);
|
||||
this.useFallBack=true;
|
||||
OC.EventSource.iframeCount++
|
||||
@@ -90,7 +99,7 @@ OC.EventSource.prototype={
|
||||
lastLength:0,//for fallback
|
||||
listen:function(type,callback){
|
||||
if(callback && callback.call){
|
||||
|
||||
|
||||
if(type){
|
||||
if(this.useFallBack){
|
||||
if(!this.listeners[type]){
|
||||
|
||||
+10
-1
@@ -30,6 +30,15 @@ function t(app,text){
|
||||
}
|
||||
t.cache={};
|
||||
|
||||
/*
|
||||
* Sanitizes a HTML string
|
||||
* @param string
|
||||
* @return Sanitized string
|
||||
*/
|
||||
function escapeHTML(s) {
|
||||
return s.toString().split('&').join('&').split('<').join('<').split('"').join('"');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to download a file
|
||||
* @param file The filename
|
||||
@@ -619,7 +628,7 @@ $.fn.filterAttr = function(attr_name, attr_value) {
|
||||
function humanFileSize(size) {
|
||||
var humanList = ['B', 'kB', 'MB', 'GB', 'TB'];
|
||||
// Calculate Log with base 1024: size = 1024 ** order
|
||||
var order = Math.floor(Math.log(size) / Math.log(1024));
|
||||
var order = size?Math.floor(Math.log(size) / Math.log(1024)):0;
|
||||
// Stay in range of the byte sizes that are defined
|
||||
order = Math.min(humanList.length - 1, order);
|
||||
var readableFormat = humanList[order];
|
||||
|
||||
+29
-25
@@ -66,51 +66,54 @@ var OCdialogs = {
|
||||
/**
|
||||
* prompt user for input with custom form
|
||||
* fields should be passed in following format: [{text:'prompt text', name:'return name', type:'input type', value: 'dafault value'},...]
|
||||
* @param fields to display
|
||||
* select example var fields=[{text:'Test', name:'test', type:'select', options:[{text:'hallo',value:1},{text:'hallo1',value:2}] }];
|
||||
* @param fields to display
|
||||
* @param title dialog title
|
||||
* @param callback which will be triggered when user press OK (user answers will be passed to callback in following format: [{name:'return name', value: 'user value'},...])
|
||||
*/
|
||||
form:function(fields, title, callback, modal) {
|
||||
var content = '<table>';
|
||||
for (var a in fields) {
|
||||
content += '<tr><td>'+fields[a].text+'</td><td>';
|
||||
var type=fields[a].type;
|
||||
$.each(fields, function(index, val){
|
||||
content += '<tr><td>'+val.text+'</td><td>';
|
||||
var type=val.type;
|
||||
|
||||
if (type == 'text' || type == 'checkbox' || type == 'password') {
|
||||
content += '<input type="'+type+'" name="'+fields[a].name+'"';
|
||||
content += '<input type="'+type+'" name="'+val.name+'"';
|
||||
if (type == 'checkbox') {
|
||||
if (fields[a].value != undefined && fields[a].value == true) {
|
||||
if (val.value != undefined && val.value == true) {
|
||||
content += ' checked="checked">';
|
||||
} else {
|
||||
content += '>';
|
||||
}
|
||||
} else if (type == 'text' || type == 'password' && fields[a].value) {
|
||||
content += ' value="'+fields[a].value+'">';
|
||||
} else if (type == 'text' || type == 'password' && val.value) {
|
||||
content += ' value="'+val.value+'">';
|
||||
}
|
||||
} else if (type == 'select') {
|
||||
content += '<select name="'+fields[a].name+'"';
|
||||
if (fields[a].value != undefined) {
|
||||
content += ' value="'+fields[a].value+'"';
|
||||
content += '<select name="'+val.name+'"';
|
||||
if (val.value != undefined) {
|
||||
content += ' value="'+val.value+'"';
|
||||
}
|
||||
content += '>';
|
||||
for (var o in fields[a].options) {
|
||||
content += '<option value="'+fields[a].options[o].value+'">'+fields[a].options[o].text+'</option>';
|
||||
}
|
||||
$.each(val.options, function(index, valo){
|
||||
content += '<option value="'+valo.value+'">'+valo.text+'</option>';
|
||||
});
|
||||
content += '</select>';
|
||||
}
|
||||
content += '</td></tr>';
|
||||
}
|
||||
|
||||
});
|
||||
content += '</table>';
|
||||
OCdialogs.message(content, title, OCdialogs.FORM_DIALOG, OCdialogs.OK_CANCEL_BUTTONS, callback, modal);
|
||||
},
|
||||
filepicker:function(title, callback, multiselect, mimetype_filter, modal) {
|
||||
var c_name = 'oc-dialog-'+OCdialogs.dialogs_counter+'-content';
|
||||
var c_id = '#'+c_name;
|
||||
var d = '<div id="'+c_name+'" title="'+title+'"><select id="dirtree"><option value="0">'+OC.currentUser+'</option></select><div id="filelist"></div><div class="filepicker_loader"><img src="'+OC.filePath('gallery','img','loading.gif')+'"></div></div>';
|
||||
var d = '<div id="'+c_name+'" title="'+title+'"><select id="dirtree"><option value="0">'+OC.currentUser+'</option></select><div id="filelist"></div><div class="filepicker_loader"><img src="'+OC.filePath('core','img','loading.gif')+'"></div></div>';
|
||||
if (!modal) modal = false; // Huh..
|
||||
if (!multiselect) multiselect = false;
|
||||
$('body').append(d);
|
||||
$(c_id + ' #dirtree').focus(function() {
|
||||
var t = $(this);
|
||||
var t = $(this);
|
||||
t.data('oldval', t.val())
|
||||
}).change({dcid: c_id}, OC.dialogs.handleTreeListSelect);
|
||||
$(c_id).ready(function(){
|
||||
@@ -120,7 +123,7 @@ var OCdialogs = {
|
||||
}).data('multiselect', multiselect).data('mimetype',mimetype_filter);
|
||||
// build buttons
|
||||
var b = [{
|
||||
text: t('core', 'Choose'),
|
||||
text: t('core', 'Choose'),
|
||||
click: function(){
|
||||
if (callback != undefined) {
|
||||
var p;
|
||||
@@ -140,7 +143,7 @@ var OCdialogs = {
|
||||
}
|
||||
},
|
||||
{
|
||||
text: t('core', 'Cancel'),
|
||||
text: t('core', 'Cancel'),
|
||||
click: function(){$(c_id).dialog('close'); }}
|
||||
];
|
||||
$(c_id).dialog({width: ((4*$('body').width())/9), height: 400, modal: modal, buttons: b});
|
||||
@@ -215,9 +218,10 @@ var OCdialogs = {
|
||||
fillFilePicker:function(r, dialog_content_id) {
|
||||
var entry_template = '<div onclick="javascript:OC.dialogs.handlePickerClick(this, \'*ENTRYNAME*\',\''+dialog_content_id+'\')" data="*ENTRYTYPE*"><img src="*MIMETYPEICON*" style="margin-right:1em;"><span id="filename">*NAME*</span><div style="float:right;margin-right:1em;">*LASTMODDATE*</div></div>';
|
||||
var names = '';
|
||||
for (var a in r.data) {
|
||||
names += entry_template.replace('*LASTMODDATE*', OC.mtime2date(r.data[a].mtime)).replace('*NAME*', r.data[a].name).replace('*MIMETYPEICON*', r.data[a].mimetype_icon).replace('*ENTRYNAME*', r.data[a].name).replace('*ENTRYTYPE*', r.data[a].type);
|
||||
}
|
||||
$.each(r.data, function(index, a) {
|
||||
names += entry_template.replace('*LASTMODDATE*', OC.mtime2date(a.mtime)).replace('*NAME*', a.name).replace('*MIMETYPEICON*', a.mimetype_icon).replace('*ENTRYNAME*', a.name).replace('*ENTRYTYPE*', a.type);
|
||||
});
|
||||
|
||||
$(dialog_content_id + ' #filelist').html(names);
|
||||
$(dialog_content_id + ' .filepicker_loader').css('visibility', 'hidden');
|
||||
},
|
||||
@@ -231,10 +235,10 @@ var OCdialogs = {
|
||||
}
|
||||
var skip_first = true;
|
||||
var path = '';
|
||||
$(this).children().each(function(i, element) {
|
||||
$(this).children().each(function(i, element) {
|
||||
if (skip_first) {
|
||||
skip_first = false;
|
||||
return;
|
||||
skip_first = false;
|
||||
return;
|
||||
}
|
||||
path += '/'+$(element).text();
|
||||
});
|
||||
|
||||
+25
-20
@@ -158,7 +158,7 @@ OC.Share={
|
||||
if (data.shares) {
|
||||
$.each(data.shares, function(index, share) {
|
||||
if (share.share_type == OC.Share.SHARE_TYPE_LINK) {
|
||||
OC.Share.showLink(itemSource, share.share_with);
|
||||
OC.Share.showLink(share.token, share.share_with, itemSource);
|
||||
} else {
|
||||
if (share.collection) {
|
||||
OC.Share.addShareWith(share.share_type, share.share_with, share.permissions, possiblePermissions, share.collection);
|
||||
@@ -302,18 +302,24 @@ OC.Share={
|
||||
$('#expiration').show();
|
||||
}
|
||||
},
|
||||
showLink:function(itemSource, password) {
|
||||
showLink:function(token, password, itemSource) {
|
||||
OC.Share.itemShares[OC.Share.SHARE_TYPE_LINK] = true;
|
||||
$('#linkCheckbox').attr('checked', true);
|
||||
var filename = $('tr').filterAttr('data-id', String(itemSource)).data('file');
|
||||
var type = $('tr').filterAttr('data-id', String(itemSource)).data('type');
|
||||
if ($('#dir').val() == '/') {
|
||||
var file = $('#dir').val() + filename;
|
||||
if (! token) {
|
||||
//fallback to pre token link
|
||||
var filename = $('tr').filterAttr('data-id', String(itemSource)).data('file');
|
||||
var type = $('tr').filterAttr('data-id', String(itemSource)).data('type');
|
||||
if ($('#dir').val() == '/') {
|
||||
var file = $('#dir').val() + filename;
|
||||
} else {
|
||||
var file = $('#dir').val() + '/' + filename;
|
||||
}
|
||||
file = '/'+OC.currentUser+'/files'+file;
|
||||
var link = parent.location.protocol+'//'+location.host+OC.linkTo('', 'public.php')+'?service=files&'+type+'='+encodeURIComponent(file);
|
||||
} else {
|
||||
var file = $('#dir').val() + '/' + filename;
|
||||
//TODO add path param when showing a link to file in a subfolder of a public link share
|
||||
var link = parent.location.protocol+'//'+location.host+OC.linkTo('', 'public.php')+'?service=files&t='+token;
|
||||
}
|
||||
file = '/'+OC.currentUser+'/files'+file;
|
||||
var link = parent.location.protocol+'//'+location.host+OC.linkTo('', 'public.php')+'?service=files&'+type+'='+file;
|
||||
$('#linkText').val(link);
|
||||
$('#linkText').show('blind');
|
||||
$('#showPassword').show();
|
||||
@@ -449,8 +455,8 @@ $(document).ready(function() {
|
||||
var itemSource = $('#dropdown').data('item-source');
|
||||
if (this.checked) {
|
||||
// Create a link
|
||||
OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', OC.PERMISSION_READ, function() {
|
||||
OC.Share.showLink(itemSource);
|
||||
OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', OC.PERMISSION_READ, function(data) {
|
||||
OC.Share.showLink(data.token, null, itemSource);
|
||||
OC.Share.updateIcon(itemType, itemSource);
|
||||
});
|
||||
} else {
|
||||
@@ -475,15 +481,14 @@ $(document).ready(function() {
|
||||
$('#linkPass').toggle('blind');
|
||||
});
|
||||
|
||||
$('#linkPassText').live('keyup', function(event) {
|
||||
if (event.keyCode == 13) {
|
||||
var itemType = $('#dropdown').data('item-type');
|
||||
var itemSource = $('#dropdown').data('item-source');
|
||||
OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, $(this).val(), OC.PERMISSION_READ, function() {
|
||||
$('#linkPassText').val('');
|
||||
$('#linkPassText').attr('placeholder', t('core', 'Password protected'));
|
||||
});
|
||||
}
|
||||
$('#linkPassText').live('focusout', function(event) {
|
||||
var itemType = $('#dropdown').data('item-type');
|
||||
var itemSource = $('#dropdown').data('item-source');
|
||||
OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, $(this).val(), OC.PERMISSION_READ, function() {
|
||||
$('#linkPassText').val('');
|
||||
$('#linkPassText').attr('placeholder', t('core', 'Password protected'));
|
||||
});
|
||||
$('#linkPassText').attr('placeholder', t('core', 'Password protected'));
|
||||
});
|
||||
|
||||
$('#expirationCheckbox').live('click', function() {
|
||||
|
||||
@@ -13,8 +13,8 @@ require_once '../../lib/base.php';
|
||||
// Someone lost their password:
|
||||
if (isset($_POST['user'])) {
|
||||
if (OC_User::userExists($_POST['user'])) {
|
||||
$token = hash("sha256", $_POST['user'].OC_Util::generate_random_bytes(10));
|
||||
OC_Preferences::setValue($_POST['user'], 'owncloud', 'lostpassword', $token);
|
||||
$token = hash("sha256", OC_Util::generate_random_bytes(30).OC_Config::getValue('passwordsalt', ''));
|
||||
OC_Preferences::setValue($_POST['user'], 'owncloud', 'lostpassword', hash("sha256", $token)); // Hash the token again to prevent timing attacks
|
||||
$email = OC_Preferences::getValue($_POST['user'], 'settings', 'email', '');
|
||||
if (!empty($email)) {
|
||||
$link = OC_Helper::linkToAbsolute('core/lostpassword', 'resetpassword.php', array('user' => $_POST['user'], 'token' => $token));
|
||||
|
||||
@@ -10,7 +10,7 @@ $RUNTIME_NOAPPS = TRUE; //no apps
|
||||
require_once '../../lib/base.php';
|
||||
|
||||
// Someone wants to reset their password:
|
||||
if(isset($_GET['token']) && isset($_GET['user']) && OC_Preferences::getValue($_GET['user'], 'owncloud', 'lostpassword') === $_GET['token']) {
|
||||
if(isset($_GET['token']) && isset($_GET['user']) && OC_Preferences::getValue($_GET['user'], 'owncloud', 'lostpassword') === hash("sha256", $_GET['token'])) {
|
||||
if (isset($_POST['password'])) {
|
||||
if (OC_User::setPassword($_GET['user'], $_POST['password'])) {
|
||||
OC_Preferences::deleteKey($_GET['user'], 'owncloud', 'lostpassword');
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
<input type='hidden' id='hasPostgreSQL' value='<?php echo $_['hasPostgreSQL'] ?>'></input>
|
||||
<input type='hidden' id='hasOracle' value='<?php echo $_['hasOracle'] ?>'></input>
|
||||
<form action="index.php" method="post">
|
||||
|
||||
<input type="hidden" name="install" value="true" />
|
||||
<?php if(count($_['errors']) > 0): ?>
|
||||
<ul class="errors">
|
||||
@@ -19,7 +18,20 @@
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(!$_['secureRNG']): ?>
|
||||
<fieldset style="color: #B94A48; background-color: #F2DEDE; border-color: #EED3D7; border-style:solid; border-radius: 5px; border-width:1px; padding:0.5em;">
|
||||
<legend><strong><?php echo $l->t('Security Warning');?></strong></legend>
|
||||
<span><?php echo $l->t('No secure random number generator is available, please enable the PHP OpenSSL extension.');?></span>
|
||||
<br/>
|
||||
<span><?php echo $l->t('Without a secure random number generator an attacker may be able to predict password reset tokens and take over your account.');?></span>
|
||||
</fieldset>
|
||||
<?php endif; ?>
|
||||
<?php if(!$_['htaccessWorking']): ?>
|
||||
<fieldset style="color: #B94A48; background-color: #F2DEDE; border-color: #EED3D7; border-style:solid; border-radius: 5px; border-width:1px; padding:0.5em;">
|
||||
<legend><strong><?php echo $l->t('Security Warning');?></strong></legend>
|
||||
<span><?php echo $l->t('Your data directory and your files are probably accessible from the internet. The .htaccess file that ownCloud provides is not working. We strongly suggest that you configure your webserver in a way that the data directory is no longer accessible or you move the data directory outside the webserver document root.');?></span>
|
||||
</fieldset>
|
||||
<?php endif; ?>
|
||||
<fieldset>
|
||||
<legend><?php echo $l->t( 'Create an <strong>admin account</strong>' ); ?></legend>
|
||||
<p class="infield">
|
||||
@@ -99,7 +111,7 @@
|
||||
</p>
|
||||
<p class="infield">
|
||||
<label for="dbname" class="infield"><?php echo $l->t( 'Database name' ); ?></label>
|
||||
<input type="text" name="dbname" id="dbname" value="<?php print OC_Helper::init_var('dbname'); ?>" autocomplete="off" />
|
||||
<input type="text" name="dbname" id="dbname" value="<?php print OC_Helper::init_var('dbname'); ?>" autocomplete="off" pattern="[0-9a-zA-Z$_]+" />
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
@@ -581,6 +581,21 @@
|
||||
<notnull>false</notnull>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>token</name>
|
||||
<type>text</type>
|
||||
<default></default>
|
||||
<notnull>false</notnull>
|
||||
<length>32</length>
|
||||
</field>
|
||||
|
||||
<index>
|
||||
<name>token_index</name>
|
||||
<field>
|
||||
<name>token</name>
|
||||
<sorting>ascending</sorting>
|
||||
</field>
|
||||
</index>
|
||||
</declaration>
|
||||
|
||||
</table>
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
require_once 'Archive/Tar.php';
|
||||
require_once '3rdparty/Archive/Tar.php';
|
||||
|
||||
class OC_Archive_TAR extends OC_Archive{
|
||||
const PLAIN=0;
|
||||
|
||||
+2
-1
@@ -193,6 +193,7 @@ class OC{
|
||||
public static function checkSSL() {
|
||||
// redirect to https site if configured
|
||||
if( OC_Config::getValue( "forcessl", false )) {
|
||||
header('Strict-Transport-Security: max-age=31536000');
|
||||
ini_set("session.cookie_secure", "on");
|
||||
if(OC_Request::serverProtocol()<>'https' and !OC::$CLI) {
|
||||
$url = "https://". OC_Request::serverHost() . $_SERVER['REQUEST_URI'];
|
||||
@@ -281,7 +282,7 @@ class OC{
|
||||
ini_set('arg_separator.output', '&');
|
||||
|
||||
// try to switch magic quotes off.
|
||||
if(function_exists('set_magic_quotes_runtime')) {
|
||||
if(get_magic_quotes_gpc()) {
|
||||
@set_magic_quotes_runtime(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ class OC_Connector_Sabre_Auth extends Sabre_DAV_Auth_Backend_AbstractBasic {
|
||||
} else {
|
||||
OC_Util::setUpFS();//login hooks may need early access to the filesystem
|
||||
if(OC_User::login($username, $password)) {
|
||||
OC_Util::setUpFS($username);
|
||||
OC_Util::setUpFS(OC_User::getUser());
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
|
||||
@@ -117,29 +117,36 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
|
||||
*/
|
||||
public function getChildren() {
|
||||
|
||||
$source = $this->getFileSource($this->path);
|
||||
$path = $source['path'];
|
||||
$user = $source['user'];
|
||||
|
||||
$folder_content = OC_Files::getDirectoryContent($this->path);
|
||||
$paths = array();
|
||||
foreach($folder_content as $info) {
|
||||
$paths[] = $this->path.'/'.$info['name'];
|
||||
$paths[] = $path.'/'.$info['name'];
|
||||
}
|
||||
$properties = array_fill_keys($paths, array());
|
||||
if(count($paths)>0) {
|
||||
$placeholders = join(',', array_fill(0, count($paths), '?'));
|
||||
$query = OC_DB::prepare( 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ?' . ' AND `propertypath` IN ('.$placeholders.')' );
|
||||
array_unshift($paths, OC_User::getUser()); // prepend userid
|
||||
$result = $query->execute( $paths );
|
||||
while($row = $result->fetchRow()) {
|
||||
$propertypath = $row['propertypath'];
|
||||
$propertyname = $row['propertyname'];
|
||||
$propertyvalue = $row['propertyvalue'];
|
||||
$properties[$propertypath][$propertyname] = $propertyvalue;
|
||||
$chunks = array_chunk($paths, 200, false);
|
||||
foreach ($chunks as $pack) {
|
||||
$placeholders = join(',', array_fill(0, count($pack), '?'));
|
||||
$query = OC_DB::prepare( 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ?' . ' AND `propertypath` IN ('.$placeholders.')' );
|
||||
array_unshift($pack, $user); // prepend userid
|
||||
$result = $query->execute( $pack );
|
||||
while($row = $result->fetchRow()) {
|
||||
$propertypath = $row['propertypath'];
|
||||
$propertyname = $row['propertyname'];
|
||||
$propertyvalue = $row['propertyvalue'];
|
||||
$properties[$propertypath][$propertyname] = $propertyvalue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$nodes = array();
|
||||
foreach($folder_content as $info) {
|
||||
$node = $this->getChild($info['name'], $info);
|
||||
$node->setPropertyCache($properties[$this->path.'/'.$info['name']]);
|
||||
$node->setPropertyCache($properties[$path.'/'.$info['name']]);
|
||||
$nodes[] = $node;
|
||||
}
|
||||
return $nodes;
|
||||
@@ -200,7 +207,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
|
||||
public function getProperties($properties) {
|
||||
$props = parent::getProperties($properties);
|
||||
if (in_array(self::GETETAG_PROPERTYNAME, $properties) && !isset($props[self::GETETAG_PROPERTYNAME])) {
|
||||
$props[self::GETETAG_PROPERTYNAME]
|
||||
$props[self::GETETAG_PROPERTYNAME]
|
||||
= OC_Connector_Sabre_Node::getETagPropertyForPath($this->path);
|
||||
}
|
||||
return $props;
|
||||
|
||||
@@ -25,6 +25,13 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
|
||||
const GETETAG_PROPERTYNAME = '{DAV:}getetag';
|
||||
const LASTMODIFIED_PROPERTYNAME = '{DAV:}lastmodified';
|
||||
|
||||
/**
|
||||
* Allow configuring the method used to generate Etags
|
||||
*
|
||||
* @var array(class_name, function_name)
|
||||
*/
|
||||
public static $ETagFunction = null;
|
||||
|
||||
/**
|
||||
* The path to the current node
|
||||
*
|
||||
@@ -141,13 +148,16 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
|
||||
* @return bool|array
|
||||
*/
|
||||
public function updateProperties($properties) {
|
||||
// get source path of shared files
|
||||
$source = self::getFileSource($this->path);
|
||||
|
||||
$existing = $this->getProperties(array());
|
||||
foreach($properties as $propertyName => $propertyValue) {
|
||||
// If it was null, we need to delete the property
|
||||
if (is_null($propertyValue)) {
|
||||
if(array_key_exists( $propertyName, $existing )) {
|
||||
$query = OC_DB::prepare( 'DELETE FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?' );
|
||||
$query->execute( array( OC_User::getUser(), $this->path, $propertyName ));
|
||||
$query->execute( array( $source['user'], $source['path'], $propertyName ));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -156,10 +166,10 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
|
||||
} else {
|
||||
if(!array_key_exists( $propertyName, $existing )) {
|
||||
$query = OC_DB::prepare( 'INSERT INTO `*PREFIX*properties` (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)' );
|
||||
$query->execute( array( OC_User::getUser(), $this->path, $propertyName,$propertyValue ));
|
||||
$query->execute( array( $source['user'], $source['path'], $propertyName, $propertyValue ));
|
||||
} else {
|
||||
$query = OC_DB::prepare( 'UPDATE `*PREFIX*properties` SET `propertyvalue` = ? WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?' );
|
||||
$query->execute( array( $propertyValue,OC_User::getUser(), $this->path, $propertyName ));
|
||||
$query->execute( array( $propertyValue, $source['user'], $source['path'], $propertyName ));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,19 +188,22 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
|
||||
* If the array is empty, all properties should be returned
|
||||
*
|
||||
* @param array $properties
|
||||
* @return void
|
||||
* @return array
|
||||
*/
|
||||
public function getProperties($properties) {
|
||||
if (is_null($this->property_cache)) {
|
||||
|
||||
$source = self::getFileSource($this->path);
|
||||
|
||||
if (is_null($this->property_cache) || empty($this->property_cache)) {
|
||||
$query = OC_DB::prepare( 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ?' );
|
||||
$result = $query->execute( array( OC_User::getUser(), $this->path ));
|
||||
$result = $query->execute( array( $source['user'], $source['path'] ));
|
||||
|
||||
$this->property_cache = array();
|
||||
while( $row = $result->fetchRow()) {
|
||||
$this->property_cache[$row['propertyname']] = $row['propertyvalue'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if the array was empty, we need to return everything
|
||||
if(count($properties) == 0) {
|
||||
return $this->property_cache;
|
||||
@@ -209,7 +222,12 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
|
||||
* @return string|null Returns null if the ETag can not effectively be determined
|
||||
*/
|
||||
static protected function createETag($path) {
|
||||
return uniqid('', true);
|
||||
if(self::$ETagFunction) {
|
||||
$hash = call_user_func(self::$ETagFunction, $path);
|
||||
return $hash;
|
||||
}else{
|
||||
return uniqid('', true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,9 +240,12 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
|
||||
if (empty($tag)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$source = self::getFileSource($path);
|
||||
|
||||
$etag = '"'.$tag.'"';
|
||||
$query = OC_DB::prepare( 'INSERT INTO `*PREFIX*properties` (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)' );
|
||||
$query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME, $etag ));
|
||||
$query->execute( array( $source['user'], $source['path'], self::GETETAG_PROPERTYNAME, $etag ));
|
||||
return $etag;
|
||||
}
|
||||
|
||||
@@ -234,6 +255,9 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
|
||||
*/
|
||||
static public function removeETagPropertyForPath($path) {
|
||||
// remove tags from this and parent paths
|
||||
$source = self::getFileSource($path);
|
||||
$path = $source['path'];
|
||||
|
||||
$paths = array();
|
||||
while ($path != '/' && $path != '.' && $path != '' && $path != '\\') {
|
||||
$paths[] = $path;
|
||||
@@ -249,7 +273,26 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
|
||||
.' AND `propertyname` = ?'
|
||||
.' AND `propertypath` IN ('.$path_placeholders.')'
|
||||
);
|
||||
$vals = array( OC_User::getUser(), self::GETETAG_PROPERTYNAME );
|
||||
$vals = array( $source['user'], self::GETETAG_PROPERTYNAME );
|
||||
$query->execute(array_merge( $vals, $paths ));
|
||||
|
||||
//remove etag for all Shared folders
|
||||
$query = OC_DB::prepare( 'DELETE FROM `*PREFIX*properties`'
|
||||
.' WHERE `propertypath` = \'/Shared\' '
|
||||
);
|
||||
$query->execute(array());
|
||||
|
||||
}
|
||||
|
||||
protected static function getFileSource($path) {
|
||||
if ( OC_App::isEnabled('files_sharing') && !strncmp($path, '/Shared/', 8)) {
|
||||
$source = OC_Files_Sharing_Util::getSourcePath(str_replace('/Shared/', '', $path));
|
||||
$parts = explode('/', $source, 4);
|
||||
$user = $parts[1];
|
||||
$path = '/'.$parts[3];
|
||||
} else {
|
||||
$user = OC_User::getUser();
|
||||
}
|
||||
return(array('user' => $user, 'path' => $path));
|
||||
}
|
||||
}
|
||||
|
||||
+6
-11
@@ -168,8 +168,7 @@ class OC_DB {
|
||||
try{
|
||||
self::$PDO=new PDO($dsn, $user, $pass, $opts);
|
||||
}catch(PDOException $e) {
|
||||
echo( '<b>can not connect to database, using '.$type.'. ('.$e->getMessage().')</center>');
|
||||
die();
|
||||
OC_Template::printErrorPage( 'can not connect to database, using '.$type.'. ('.$e->getMessage().')' );
|
||||
}
|
||||
// We always, really always want associative arrays
|
||||
self::$PDO->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
||||
@@ -263,10 +262,7 @@ class OC_DB {
|
||||
|
||||
// Die if we could not connect
|
||||
if( PEAR::isError( self::$MDB2 )) {
|
||||
echo( '<b>can not connect to database, using '.$type.'. ('.self::$MDB2->getUserInfo().')</center>');
|
||||
OC_Log::write('core', self::$MDB2->getUserInfo(), OC_Log::FATAL);
|
||||
OC_Log::write('core', self::$MDB2->getMessage(), OC_Log::FATAL);
|
||||
die();
|
||||
OC_Template::printErrorPage( 'can not connect to database, using '.$type.'. ('.self::$MDB2->getUserInfo().')' );
|
||||
}
|
||||
|
||||
// We always, really always want associative arrays
|
||||
@@ -326,7 +322,7 @@ class OC_DB {
|
||||
$entry .= 'Offending command was: '.htmlentities($query).'<br />';
|
||||
OC_Log::write('core', $entry,OC_Log::FATAL);
|
||||
error_log('DB error: '.$entry);
|
||||
die( $entry );
|
||||
OC_Template::printErrorPage( $entry );
|
||||
}
|
||||
}else{
|
||||
try{
|
||||
@@ -336,7 +332,7 @@ class OC_DB {
|
||||
$entry .= 'Offending command was: '.htmlentities($query).'<br />';
|
||||
OC_Log::write('core', $entry,OC_Log::FATAL);
|
||||
error_log('DB error: '.$entry);
|
||||
die( $entry );
|
||||
OC_Template::printErrorPage( $entry );
|
||||
}
|
||||
$result=new PDOStatementWrapper($result);
|
||||
}
|
||||
@@ -449,7 +445,7 @@ class OC_DB {
|
||||
|
||||
// Die in case something went wrong
|
||||
if( $definition instanceof MDB2_Schema_Error ) {
|
||||
die( $definition->getMessage().': '.$definition->getUserInfo());
|
||||
OC_Template::printErrorPage( $definition->getMessage().': '.$definition->getUserInfo() );
|
||||
}
|
||||
if(OC_Config::getValue('dbtype', 'sqlite')==='oci') {
|
||||
unset($definition['charset']); //or MDB2 tries SHUTDOWN IMMEDIATE
|
||||
@@ -461,8 +457,7 @@ class OC_DB {
|
||||
|
||||
// Die in case something went wrong
|
||||
if( $ret instanceof MDB2_Error ) {
|
||||
echo (self::$MDB2->getDebugOutput());
|
||||
die ($ret->getMessage() . ': ' . $ret->getUserInfo());
|
||||
OC_Template::printErrorPage( self::$MDB2->getDebugOutput().' '.$ret->getMessage() . ': ' . $ret->getUserInfo() );
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ class OC_EventSource{
|
||||
private $fallBackId=0;
|
||||
|
||||
public function __construct() {
|
||||
@ob_end_clean();
|
||||
OC_Util::obEnd();
|
||||
header('Cache-Control: no-cache');
|
||||
$this->fallback=isset($_GET['fallback']) and $_GET['fallback']=='true';
|
||||
if($this->fallback) {
|
||||
@@ -80,4 +80,4 @@ class OC_EventSource{
|
||||
public function close() {
|
||||
$this->send('__internal__','close');//server side closing can be an issue, let the client do it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+60
-17
@@ -43,6 +43,9 @@ class OC_FileCache{
|
||||
* - versioned
|
||||
*/
|
||||
public static function get($path,$root=false) {
|
||||
|
||||
list($path, $root) = self::getSourcePathOfSharedFile($path, $root);
|
||||
|
||||
if(OC_FileCache_Update::hasUpdated($path,$root)) {
|
||||
if($root===false) {//filesystem hooks are only valid for the default root
|
||||
OC_Hook::emit('OC_Filesystem','post_write',array('path'=>$path));
|
||||
@@ -65,7 +68,7 @@ class OC_FileCache{
|
||||
if($root===false) {
|
||||
$root=OC_Filesystem::getRoot();
|
||||
}
|
||||
$fullpath=$root.$path;
|
||||
$fullpath=OC_Filesystem::normalizePath($root.'/'.$path);
|
||||
$parent=self::getParentId($fullpath);
|
||||
$id=self::getId($fullpath,'');
|
||||
if(isset(OC_FileCache_Cached::$savedData[$fullpath])) {
|
||||
@@ -79,8 +82,8 @@ class OC_FileCache{
|
||||
|
||||
// add parent directory to the file cache if it does not exist yet.
|
||||
if ($parent == -1 && $fullpath != $root) {
|
||||
$parentDir = substr(dirname($path), 0, strrpos(dirname($path), DIRECTORY_SEPARATOR));
|
||||
self::scanFile($parentDir);
|
||||
$parentDir = dirname(OC_Filesystem::normalizePath($path));
|
||||
self::scanFile($parentDir, $root);
|
||||
$parent = self::getParentId($fullpath);
|
||||
}
|
||||
|
||||
@@ -94,15 +97,19 @@ class OC_FileCache{
|
||||
if(!isset($data['versioned'])) {
|
||||
$data['versioned']=false;
|
||||
}
|
||||
if(!isset($data['user'])) {
|
||||
$data['user']=OC_User::getUser();
|
||||
}
|
||||
|
||||
|
||||
$mimePart=dirname($data['mimetype']);
|
||||
$data['size']=(int)$data['size'];
|
||||
$data['ctime']=(int)$data['mtime'];
|
||||
$data['writable']=(int)$data['writable'];
|
||||
$data['encrypted']=(int)$data['encrypted'];
|
||||
$data['versioned']=(int)$data['versioned'];
|
||||
$user=OC_User::getUser();
|
||||
$query=OC_DB::prepare('INSERT INTO `*PREFIX*fscache`(`parent`, `name`, `path`, `path_hash`, `size`, `mtime`, `ctime`, `mimetype`, `mimepart`,`user`,`writable`,`encrypted`,`versioned`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)');
|
||||
$result=$query->execute(array($parent,basename($fullpath),$fullpath,md5($fullpath),$data['size'],$data['mtime'],$data['ctime'],$data['mimetype'],$mimePart,$user,$data['writable'],$data['encrypted'],$data['versioned']));
|
||||
$result=$query->execute(array($parent,basename($fullpath),$fullpath,md5($fullpath),$data['size'],$data['mtime'],$data['ctime'],$data['mimetype'],$mimePart,$data['user'],$data['writable'],$data['encrypted'],$data['versioned']));
|
||||
if(OC_DB::isError($result)) {
|
||||
OC_Log::write('files','error while writing file('.$fullpath.') to cache',OC_Log::ERROR);
|
||||
}
|
||||
@@ -120,7 +127,7 @@ class OC_FileCache{
|
||||
private static function update($id,$data) {
|
||||
$arguments=array();
|
||||
$queryParts=array();
|
||||
foreach(array('size','mtime','ctime','mimetype','encrypted','versioned','writable') as $attribute) {
|
||||
foreach(array('size','mtime','ctime','mimetype','encrypted','versioned','writable', 'user') as $attribute) {
|
||||
if(isset($data[$attribute])) {
|
||||
//Convert to int it args are false
|
||||
if($data[$attribute] === false) {
|
||||
@@ -203,7 +210,7 @@ class OC_FileCache{
|
||||
|
||||
OC_Cache::remove('fileid/'.$root.$path);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* return array of filenames matching the querty
|
||||
* @param string $query
|
||||
@@ -273,6 +280,9 @@ class OC_FileCache{
|
||||
* @return int
|
||||
*/
|
||||
public static function getId($path,$root=false) {
|
||||
|
||||
list($path, $root) = self::getSourcePathOfSharedFile($path, $root);
|
||||
|
||||
if($root===false) {
|
||||
$root=OC_Filesystem::getRoot();
|
||||
}
|
||||
@@ -344,21 +354,34 @@ class OC_FileCache{
|
||||
*/
|
||||
public static function increaseSize($path,$sizeDiff, $root=false) {
|
||||
if($sizeDiff==0) return;
|
||||
$id=self::getId($path,$root);
|
||||
$item = OC_FileCache_Cached::get($path);
|
||||
//stop walking up the filetree if we hit a non-folder
|
||||
if($item['mimetype'] !== 'httpd/unix-directory'){
|
||||
return;
|
||||
}
|
||||
$id = $item['id'];
|
||||
while($id!=-1) {//walk up the filetree increasing the size of all parent folders
|
||||
$query=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `size`=`size`+? WHERE `id`=?');
|
||||
$query->execute(array($sizeDiff,$id));
|
||||
$id=self::getParentId($path);
|
||||
$query->execute(array($sizeDiff, $id));
|
||||
if($path == '' or $path =='/'){
|
||||
return;
|
||||
}
|
||||
$path=dirname($path);
|
||||
$parent = OC_FileCache_Cached::get($path);
|
||||
$id = $parent['id'];
|
||||
//stop walking up the filetree if we hit a non-folder
|
||||
if($parent['mimetype'] !== 'httpd/unix-directory'){
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* recursively scan the filesystem and fill the cache
|
||||
* @param string $path
|
||||
* @param OC_EventSource $enventSource (optional)
|
||||
* @param int count (optional)
|
||||
* @param string root (optional)
|
||||
* @param OC_EventSource $eventSource (optional)
|
||||
* @param int $count (optional)
|
||||
* @param string $root (optional)
|
||||
*/
|
||||
public static function scan($path,$eventSource=false,&$count=0,$root=false) {
|
||||
if($eventSource) {
|
||||
@@ -496,16 +519,36 @@ class OC_FileCache{
|
||||
*/
|
||||
public static function triggerUpdate($user=''){
|
||||
if($user) {
|
||||
$query=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `mtime`=0 WHERE `user`=? AND `mimetype`="httpd/unix-directory"');
|
||||
$query->execute(array($user));
|
||||
$query=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `mtime`=0 WHERE `user`=? AND `mimetype`= ? ');
|
||||
$query->execute(array($user,'httpd/unix-directory'));
|
||||
}else{
|
||||
$query=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `mtime`=0 AND `mimetype`="httpd/unix-directory"');
|
||||
$query->execute();
|
||||
$query=OC_DB::prepare('UPDATE `*PREFIX*fscache` SET `mtime`=0 WHERE `mimetype`= ? ');
|
||||
$query->execute(array('httpd/unix-directory'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get the real path and the root of a shared file
|
||||
* @param string $path
|
||||
* @return array with the path and the root of the give file
|
||||
*/
|
||||
private static function getSourcePathOfSharedFile($path, $root) {
|
||||
if ( OC_App::isEnabled('files_sharing')) {
|
||||
$fullPath = OC_Filesystem::normalizePath($root.'/'.$path);
|
||||
$sharedPos = strpos($fullPath, '/Shared/');
|
||||
if ( $sharedPos !== false && ($source = OC_Files_Sharing_Util::getSourcePath(substr($fullPath, $sharedPos+8))) ) {
|
||||
$parts = explode('/', $source, 4);
|
||||
$root = '/'.$parts[1].'/files';
|
||||
$path = '/'.$parts[3];
|
||||
}
|
||||
}
|
||||
|
||||
return array($path, $root);
|
||||
}
|
||||
}
|
||||
|
||||
//watch for changes and try to keep the cache up to date
|
||||
OC_Hook::connect('OC_Filesystem','post_write','OC_FileCache_Update','fileSystemWatcherWrite');
|
||||
OC_Hook::connect('OC_Filesystem','post_delete','OC_FileCache_Update','fileSystemWatcherDelete');
|
||||
OC_Hook::connect('OC_Filesystem','post_rename','OC_FileCache_Update','fileSystemWatcherRename');
|
||||
OC_Hook::connect('OC_User','post_deleteUser','OC_FileCache_Update','deleteFromUser');
|
||||
|
||||
@@ -18,7 +18,7 @@ class OC_FileCache_Cached{
|
||||
$root=OC_Filesystem::getRoot();
|
||||
}
|
||||
$path=$root.$path;
|
||||
$stmt=OC_DB::prepare('SELECT `path`,`ctime`,`mtime`,`mimetype`,`size`,`encrypted`,`versioned`,`writable` FROM `*PREFIX*fscache` WHERE `path_hash`=?');
|
||||
$stmt=OC_DB::prepare('SELECT `id`, `path`,`ctime`,`mtime`,`mimetype`,`size`,`encrypted`,`versioned`,`writable` FROM `*PREFIX*fscache` WHERE `path_hash`=?');
|
||||
if ( ! OC_DB::isError($stmt) ) {
|
||||
$result=$stmt->execute(array(md5($path)));
|
||||
if ( ! OC_DB::isError($result) ) {
|
||||
@@ -78,4 +78,4 @@ class OC_FileCache_Cached{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +174,9 @@ class OC_FileCache_Update{
|
||||
}else{
|
||||
$size=OC_FileCache::scanFile($path, $root);
|
||||
}
|
||||
OC_FileCache::increaseSize(dirname($path), $size-$cachedSize, $root);
|
||||
if($path !== '' and $path !== '/'){
|
||||
OC_FileCache::increaseSize(dirname($path), $size-$cachedSize, $root);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,4 +216,12 @@ class OC_FileCache_Update{
|
||||
OC_FileCache::increaseSize(dirname($newPath), $oldSize, $root);
|
||||
OC_FileCache::move($oldPath, $newPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete files owned by user from the cache
|
||||
* @param string $parameters$parameters["uid"])
|
||||
*/
|
||||
public static function deleteFromUser($parameters) {
|
||||
OC_FileCache::clear($parameters["uid"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* ownCloud
|
||||
*
|
||||
* @author Bjoern Schiessle
|
||||
* @copyright 2012 Bjoern Schiessle <schiessle@owncloud.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* check if standard file operations
|
||||
*/
|
||||
|
||||
class OC_FileProxy_FileOperations extends OC_FileProxy{
|
||||
static $rootView;
|
||||
|
||||
public function premkdir($path) {
|
||||
if(!self::$rootView){
|
||||
self::$rootView = new OC_FilesystemView('');
|
||||
}
|
||||
return !self::$rootView->file_exists($path);
|
||||
}
|
||||
|
||||
}
|
||||
+12
-8
@@ -42,16 +42,20 @@ class OC_Files {
|
||||
* - versioned
|
||||
*/
|
||||
public static function getFileInfo($path) {
|
||||
$path = OC_Filesystem::normalizePath($path);
|
||||
if (($path == '/Shared' || substr($path, 0, 8) == '/Shared/') && OC_App::isEnabled('files_sharing')) {
|
||||
if ($path == '/Shared') {
|
||||
list($info) = OCP\Share::getItemsSharedWith('file', OC_Share_Backend_File::FORMAT_FILE_APP_ROOT);
|
||||
}else{
|
||||
$info['size'] = OC_Filesystem::filesize($path);
|
||||
$info['mtime'] = OC_Filesystem::filemtime($path);
|
||||
$info['ctime'] = OC_Filesystem::filectime($path);
|
||||
$info['mimetype'] = OC_Filesystem::getMimeType($path);
|
||||
$info['encrypted'] = false;
|
||||
$info['versioned'] = false;
|
||||
} else {
|
||||
$info = array();
|
||||
if (OC_Filesystem::file_exists($path)) {
|
||||
$info['size'] = OC_Filesystem::filesize($path);
|
||||
$info['mtime'] = OC_Filesystem::filemtime($path);
|
||||
$info['ctime'] = OC_Filesystem::filectime($path);
|
||||
$info['mimetype'] = OC_Filesystem::getMimeType($path);
|
||||
$info['encrypted'] = false;
|
||||
$info['versioned'] = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$info = OC_FileCache::get($path);
|
||||
@@ -178,7 +182,7 @@ class OC_Files {
|
||||
$zip=false;
|
||||
$filename=$dir.'/'.$files;
|
||||
}
|
||||
@ob_end_clean();
|
||||
OC_Util::obEnd();
|
||||
if($zip or OC_Filesystem::is_readable($filename)) {
|
||||
header('Content-Disposition: attachment; filename="'.basename($filename).'"');
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
|
||||
+83
-52
@@ -46,6 +46,7 @@
|
||||
class OC_Filesystem{
|
||||
static private $storages=array();
|
||||
static private $mounts=array();
|
||||
static private $loadedUsers=array();
|
||||
public static $loaded=false;
|
||||
/**
|
||||
* @var OC_Filestorage $defaultInstance
|
||||
@@ -178,72 +179,92 @@ class OC_Filesystem{
|
||||
$internalPath=substr($path,strlen($mountPoint));
|
||||
return $internalPath;
|
||||
}
|
||||
|
||||
static private function mountPointsLoaded($user) {
|
||||
return in_array($user, self::$loadedUsers);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the storage object for a path
|
||||
* @param string path
|
||||
* @return OC_Filestorage
|
||||
*/
|
||||
static public function getStorage($path) {
|
||||
$user = ltrim(substr($path, 0, strpos($path, '/', 1)), '/');
|
||||
// check mount points if file was shared from a different user
|
||||
if ($user != OC_User::getUser() && !self::mountPointsLoaded($user)) {
|
||||
OC_Util::loadUserMountPoints($user);
|
||||
self::loadSystemMountPoints($user);
|
||||
self::$loadedUsers[] = $user;
|
||||
}
|
||||
|
||||
$mountpoint=self::getMountPoint($path);
|
||||
if($mountpoint) {
|
||||
if(!isset(OC_Filesystem::$storages[$mountpoint])) {
|
||||
$mount=OC_Filesystem::$mounts[$mountpoint];
|
||||
OC_Filesystem::$storages[$mountpoint]=OC_Filesystem::createStorage($mount['class'],$mount['arguments']);
|
||||
OC_Filesystem::$storages[$mountpoint]=OC_Filesystem::createStorage($mount['class'], $mount['arguments']);
|
||||
}
|
||||
return OC_Filesystem::$storages[$mountpoint];
|
||||
}
|
||||
}
|
||||
|
||||
static public function init($root) {
|
||||
static private function loadSystemMountPoints($user) {
|
||||
if(is_file(OC::$SERVERROOT.'/config/mount.php')) {
|
||||
$mountConfig=include OC::$SERVERROOT.'/config/mount.php';
|
||||
if(isset($mountConfig['global'])) {
|
||||
foreach($mountConfig['global'] as $mountPoint=>$options) {
|
||||
self::mount($options['class'], $options['options'], $mountPoint);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($mountConfig['group'])) {
|
||||
foreach($mountConfig['group'] as $group=>$mounts) {
|
||||
if(OC_Group::inGroup($user, $group)) {
|
||||
foreach($mounts as $mountPoint=>$options) {
|
||||
$mountPoint=self::setUserVars($mountPoint, $user);
|
||||
foreach($options as &$option) {
|
||||
$option=self::setUserVars($option, $user);
|
||||
}
|
||||
self::mount($options['class'], $options['options'], $mountPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($mountConfig['user'])) {
|
||||
foreach($mountConfig['user'] as $mountUser=>$mounts) {
|
||||
if($user==='all' or strtolower($mountUser)===strtolower($user)) {
|
||||
foreach($mounts as $mountPoint=>$options) {
|
||||
$mountPoint=self::setUserVars($mountPoint, $user);
|
||||
foreach($options as &$option) {
|
||||
$option=self::setUserVars($option, $user);
|
||||
}
|
||||
self::mount($options['class'], $options['options'], $mountPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$mtime=filemtime(OC::$SERVERROOT.'/config/mount.php');
|
||||
$previousMTime=OC_Appconfig::getValue('files', 'mountconfigmtime', 0);
|
||||
if($mtime>$previousMTime) {//mount config has changed, filecache needs to be updated
|
||||
OC_FileCache::triggerUpdate();
|
||||
OC_Appconfig::setValue('files', 'mountconfigmtime', $mtime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public function init($root, $user = '') {
|
||||
if(self::$defaultInstance) {
|
||||
return false;
|
||||
}
|
||||
self::$defaultInstance=new OC_FilesystemView($root);
|
||||
|
||||
//load custom mount config
|
||||
if(is_file(OC::$SERVERROOT.'/config/mount.php')) {
|
||||
$mountConfig=include(OC::$SERVERROOT.'/config/mount.php');
|
||||
if(isset($mountConfig['global'])) {
|
||||
foreach($mountConfig['global'] as $mountPoint=>$options) {
|
||||
self::mount($options['class'],$options['options'],$mountPoint);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($mountConfig['group'])) {
|
||||
foreach($mountConfig['group'] as $group=>$mounts) {
|
||||
if(OC_Group::inGroup(OC_User::getUser(),$group)) {
|
||||
foreach($mounts as $mountPoint=>$options) {
|
||||
$mountPoint=self::setUserVars($mountPoint);
|
||||
foreach($options as &$option) {
|
||||
$option=self::setUserVars($option);
|
||||
}
|
||||
self::mount($options['class'],$options['options'],$mountPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($mountConfig['user'])) {
|
||||
foreach($mountConfig['user'] as $user=>$mounts) {
|
||||
if($user==='all' or strtolower($user)===strtolower(OC_User::getUser())) {
|
||||
foreach($mounts as $mountPoint=>$options) {
|
||||
$mountPoint=self::setUserVars($mountPoint);
|
||||
foreach($options as &$option) {
|
||||
$option=self::setUserVars($option);
|
||||
}
|
||||
self::mount($options['class'],$options['options'],$mountPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$mtime=filemtime(OC::$SERVERROOT.'/config/mount.php');
|
||||
$previousMTime=OC_Appconfig::getValue('files','mountconfigmtime',0);
|
||||
if($mtime>$previousMTime) {//mount config has changed, filecache needs to be updated
|
||||
OC_FileCache::triggerUpdate();
|
||||
OC_Appconfig::setValue('files','mountconfigmtime',$mtime);
|
||||
}
|
||||
if (!isset($user)) {
|
||||
$user = OC_User::getUser();
|
||||
}
|
||||
self::loadSystemMountPoints($user);
|
||||
|
||||
self::$loaded=true;
|
||||
}
|
||||
@@ -253,8 +274,12 @@ class OC_Filesystem{
|
||||
* @param string intput
|
||||
* @return string
|
||||
*/
|
||||
private static function setUserVars($input) {
|
||||
return str_replace('$user',OC_User::getUser(),$input);
|
||||
private static function setUserVars($input, $user) {
|
||||
if (isset($user)) {
|
||||
return str_replace('$user', $user,$input);
|
||||
} else {
|
||||
return str_replace('$user',OC_User::getUser(),$input);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -371,12 +396,16 @@ class OC_Filesystem{
|
||||
* @return bool
|
||||
*/
|
||||
static public function isValidPath($path) {
|
||||
$path = self::normalizePath($path);
|
||||
if(!$path || $path[0]!=='/') {
|
||||
$path='/'.$path;
|
||||
}
|
||||
if(strstr($path,'/../') || strrchr($path, '/') === '/..' ) {
|
||||
return false;
|
||||
}
|
||||
if(self::isFileBlacklisted($path)){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -386,20 +415,22 @@ class OC_Filesystem{
|
||||
* @param array $data from hook
|
||||
*/
|
||||
static public function isBlacklisted($data) {
|
||||
$blacklist = array('.htaccess');
|
||||
if (isset($data['path'])) {
|
||||
$path = $data['path'];
|
||||
} else if (isset($data['newpath'])) {
|
||||
$path = $data['newpath'];
|
||||
}
|
||||
if (isset($path)) {
|
||||
$filename = strtolower(basename($path));
|
||||
if (in_array($filename, $blacklist)) {
|
||||
$data['run'] = false;
|
||||
}
|
||||
$data['run'] = !self::isFileBlacklisted($path);
|
||||
}
|
||||
}
|
||||
|
||||
static public function isFileBlacklisted($path){
|
||||
$blacklist = array('.htaccess');
|
||||
$filename = strtolower(basename($path));
|
||||
return in_array($filename, $blacklist);
|
||||
}
|
||||
|
||||
/**
|
||||
* following functions are equivilent to their php buildin equivilents for arguments/return values.
|
||||
*/
|
||||
@@ -531,7 +562,7 @@ class OC_Filesystem{
|
||||
if ($root) { // reduce path to the required part of it (no 'username/files')
|
||||
$fakeRootView = new OC_FilesystemView($root);
|
||||
$count = 1;
|
||||
$path=str_replace(OC_App::getStorage("files")->getAbsolutePath($path), "", $fakeRootView->getAbsolutePath($path), $count);
|
||||
$path=str_replace(OC_App::getStorage("files")->getAbsolutePath(), "", $fakeRootView->getAbsolutePath($path), $count);
|
||||
}
|
||||
|
||||
$path = self::normalizePath($path);
|
||||
|
||||
+30
-8
@@ -47,11 +47,8 @@ class OC_FilesystemView {
|
||||
$this->fakeRoot=$root;
|
||||
}
|
||||
|
||||
public function getAbsolutePath($path) {
|
||||
if(!$path) {
|
||||
$path='/';
|
||||
}
|
||||
if($path[0]!=='/') {
|
||||
public function getAbsolutePath($path = '/') {
|
||||
if(!$path || $path[0]!=='/') {
|
||||
$path='/'.$path;
|
||||
}
|
||||
return $this->fakeRoot.$path;
|
||||
@@ -198,7 +195,7 @@ class OC_FilesystemView {
|
||||
return $this->basicOperation('filesize', $path);
|
||||
}
|
||||
public function readfile($path) {
|
||||
@ob_end_clean();
|
||||
OC_Util::obEnd();
|
||||
$handle=$this->fopen($path, 'rb');
|
||||
if ($handle) {
|
||||
$chunkSize = 8192;// 8 MB chunks
|
||||
@@ -251,6 +248,9 @@ class OC_FilesystemView {
|
||||
return $this->basicOperation('filemtime', $path);
|
||||
}
|
||||
public function touch($path, $mtime=null) {
|
||||
if(!is_null($mtime) and !is_numeric($mtime)){
|
||||
$mtime = strtotime($mtime);
|
||||
}
|
||||
return $this->basicOperation('touch', $path, array('write'), $mtime);
|
||||
}
|
||||
public function file_get_contents($path) {
|
||||
@@ -431,6 +431,9 @@ class OC_FilesystemView {
|
||||
$result = OC_Helper::streamCopy($source, $target);
|
||||
}
|
||||
if( $this->fakeRoot==OC_Filesystem::getRoot() ){
|
||||
// If the file to be copied originates within
|
||||
// the user's data directory
|
||||
|
||||
OC_Hook::emit(
|
||||
OC_Filesystem::CLASSNAME,
|
||||
OC_Filesystem::signal_post_copy,
|
||||
@@ -451,9 +454,28 @@ class OC_FilesystemView {
|
||||
OC_Filesystem::signal_post_write,
|
||||
array( OC_Filesystem::signal_param_path => $path2)
|
||||
);
|
||||
} else { // no real copy, file comes from somewhere else, e.g. version rollback -> just update the file cache and the webdav properties without all the other post_write actions
|
||||
OC_FileCache_Update::update($path2, $this->fakeRoot);
|
||||
} else {
|
||||
// If this is not a normal file copy operation
|
||||
// and the file originates somewhere else
|
||||
// (e.g. a version rollback operation), do not
|
||||
// perform all the other post_write actions
|
||||
|
||||
// Update webdav properties
|
||||
OC_Filesystem::removeETagHook(array("path" => $path2), $this->fakeRoot);
|
||||
|
||||
$splitPath2 = explode( '/', $path2 );
|
||||
|
||||
// Only cache information about files
|
||||
// that are being copied from within
|
||||
// the user files directory. Caching
|
||||
// other files, like VCS backup files,
|
||||
// serves no purpose
|
||||
if ( $splitPath2[1] == 'files' ) {
|
||||
|
||||
OC_FileCache_Update::update($path2, $this->fakeRoot);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -65,15 +65,8 @@ class OC_Group {
|
||||
*
|
||||
* Tries to create a new group. If the group name already exists, false will
|
||||
* be returned. Basic checking of Group name
|
||||
*
|
||||
* Allowed characters in the username are: "a-z", "A-Z", "0-9" and "_.@-"
|
||||
*/
|
||||
public static function createGroup( $gid ) {
|
||||
// Check the name for bad characters
|
||||
// Allowed are: "a-z", "A-Z", "0-9" and "_.@-"
|
||||
if( preg_match( '/[^a-zA-Z0-9 _\.@\-]/', $gid )) {
|
||||
return false;
|
||||
}
|
||||
// No empty group names!
|
||||
if( !$gid ) {
|
||||
return false;
|
||||
|
||||
+13
-2
@@ -100,6 +100,17 @@ class OC_Helper {
|
||||
return OC_Request::serverProtocol(). '://' . OC_Request::serverHost() . $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates an url for remote use
|
||||
* @param string $service id
|
||||
* @return string the url
|
||||
*
|
||||
* Returns a url to the given service.
|
||||
*/
|
||||
public static function linkToRemoteBase( $service ) {
|
||||
return self::linkTo( '', 'remote.php') . '/' . $service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates an absolute url for remote use
|
||||
* @param string $service id
|
||||
@@ -108,7 +119,7 @@ class OC_Helper {
|
||||
* Returns a absolute url to the given service.
|
||||
*/
|
||||
public static function linkToRemote( $service, $add_slash = true ) {
|
||||
return self::linkToAbsolute( '', 'remote.php') . '/' . $service . (($add_slash && $service[strlen($service)-1]!='/')?'/':'');
|
||||
return self::makeURLAbsolute(self::linkToRemoteBase($service)) . (($add_slash && $service[strlen($service)-1]!='/')?'/':'');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -294,7 +305,7 @@ class OC_Helper {
|
||||
self::copyr("$src/$file", "$dest/$file");
|
||||
}
|
||||
}
|
||||
}elseif(file_exists($src)) {
|
||||
}elseif(file_exists($src) && !OC_Filesystem::isFileBlacklisted($src)) {
|
||||
copy($src, $dest);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
"Application is not enabled" => "Die Anwendung ist nicht aktiviert",
|
||||
"Authentication error" => "Authentifizierungs-Fehler",
|
||||
"Token expired. Please reload page." => "Token abgelaufen. Bitte lade die Seite neu.",
|
||||
"seconds ago" => "Vor wenigen Sekunden",
|
||||
"seconds ago" => "Gerade eben",
|
||||
"1 minute ago" => "Vor einer Minute",
|
||||
"%d minutes ago" => "Vor %d Minuten",
|
||||
"today" => "Heute",
|
||||
|
||||
+12
-36
@@ -200,7 +200,7 @@ class OC_Migrate{
|
||||
$scan = scandir( $extractpath );
|
||||
// Check for export_info.json
|
||||
if( !in_array( 'export_info.json', $scan ) ) {
|
||||
OC_Log::write( 'migration', 'Invalid import file, export_info.json note found', OC_Log::ERROR );
|
||||
OC_Log::write( 'migration', 'Invalid import file, export_info.json not found', OC_Log::ERROR );
|
||||
return json_encode( array( 'success' => false ) );
|
||||
}
|
||||
$json = json_decode( file_get_contents( $extractpath . 'export_info.json' ) );
|
||||
@@ -235,12 +235,19 @@ class OC_Migrate{
|
||||
return json_encode( array( 'success' => false ) );
|
||||
}
|
||||
// Copy data
|
||||
if( !self::copy_r( $extractpath . $json->exporteduser, $datadir . '/' . self::$uid ) ) {
|
||||
return json_encode( array( 'success' => false ) );
|
||||
$userfolder = $extractpath . $json->exporteduser;
|
||||
$newuserfolder = $datadir . '/' . self::$uid;
|
||||
foreach(scandir($userfolder) as $file){
|
||||
if($file !== '.' && $file !== '..' && is_dir($file)){
|
||||
// Then copy the folder over
|
||||
OC_Helper::copyr($userfolder.'/'.$file, $newuserfolder.'/'.$file);
|
||||
}
|
||||
}
|
||||
// Import user app data
|
||||
if( !$appsimported = self::importAppData( $extractpath . $json->exporteduser . '/migration.db', $json, self::$uid ) ) {
|
||||
return json_encode( array( 'success' => false ) );
|
||||
if(file_exists($extractpath . $json->exporteduser . '/migration.db')){
|
||||
if( !$appsimported = self::importAppData( $extractpath . $json->exporteduser . '/migration.db', $json, self::$uid ) ) {
|
||||
return json_encode( array( 'success' => false ) );
|
||||
}
|
||||
}
|
||||
// All done!
|
||||
if( !self::unlink_r( $extractpath ) ) {
|
||||
@@ -304,37 +311,6 @@ class OC_Migrate{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief copies recursively
|
||||
* @param $path string path to source folder
|
||||
* @param $dest string path to destination
|
||||
* @return bool
|
||||
*/
|
||||
private static function copy_r( $path, $dest ) {
|
||||
if( is_dir($path) ) {
|
||||
@mkdir( $dest );
|
||||
$objects = scandir( $path );
|
||||
if( sizeof( $objects ) > 0 ) {
|
||||
foreach( $objects as $file ) {
|
||||
if( $file == "." || $file == ".." || $file == ".htaccess")
|
||||
continue;
|
||||
// go on
|
||||
if( is_dir( $path . '/' . $file ) ) {
|
||||
self::copy_r( $path .'/' . $file, $dest . '/' . $file );
|
||||
} else {
|
||||
copy( $path . '/' . $file, $dest . '/' . $file );
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
elseif( is_file( $path ) ) {
|
||||
return copy( $path, $dest );
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief tries to extract the import zip
|
||||
* @param $path string path to the zip
|
||||
|
||||
@@ -94,4 +94,5 @@ return array(
|
||||
'sgf' => 'application/sgf',
|
||||
'cdr' => 'application/coreldraw',
|
||||
'impress' => 'text/impress',
|
||||
'ai' => 'application/illustrator',
|
||||
);
|
||||
|
||||
@@ -33,6 +33,12 @@ abstract class OC_Minimizer {
|
||||
$cache->set($cache_key.'.gz', $gzout);
|
||||
OC_Response::setETagHeader($etag);
|
||||
}
|
||||
// on some systems (e.g. SLES 11, but not Ubuntu) mod_deflate and zlib compression will compress the output twice.
|
||||
// This results in broken core.css and core.js. To avoid it, we switch off zlib compression.
|
||||
// Since mod_deflate is still active, Apache will compress what needs to be compressed, i.e. no disadvantage.
|
||||
if(function_exists('apache_get_modules') && ini_get('zlib.output_compression') && in_array('mod_deflate', apache_get_modules())) {
|
||||
ini_set('zlib.output_compression', 'Off');
|
||||
}
|
||||
if ($encoding = OC_Request::acceptGZip()) {
|
||||
header('Content-Encoding: '.$encoding);
|
||||
$out = $gzout;
|
||||
|
||||
+90
-22
@@ -54,10 +54,13 @@ class Share {
|
||||
const FORMAT_STATUSES = -2;
|
||||
const FORMAT_SOURCES = -3;
|
||||
|
||||
const TOKEN_LENGTH = 32; // see db_structure.xml
|
||||
|
||||
private static $shareTypeUserAndGroups = -1;
|
||||
private static $shareTypeGroupUserUnique = 2;
|
||||
private static $backends = array();
|
||||
private static $backendTypes = array();
|
||||
private static $isResharingAllowed;
|
||||
|
||||
/**
|
||||
* @brief Register a sharing backend class that implements OCP\Share_Backend for an item type
|
||||
@@ -141,6 +144,20 @@ class Share {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the item shared by a token
|
||||
* @param string token
|
||||
* @return Item
|
||||
*/
|
||||
public static function getShareByToken($token) {
|
||||
$query = \OC_DB::prepare('SELECT * FROM `*PREFIX*share` WHERE `token` = ?',1);
|
||||
$result = $query->execute(array($token));
|
||||
if (\OC_DB::isError($result)) {
|
||||
\OC_Log::write('OCP\Share', \OC_DB::getErrorMessage($result) . ', token=' . $token, \OC_Log::ERROR);
|
||||
}
|
||||
return $result->fetchRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the shared items of item type owned by the current user
|
||||
* @param string Item type
|
||||
* @param int Format (optional) Format type must be defined by the backend
|
||||
@@ -169,7 +186,7 @@ class Share {
|
||||
* @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK
|
||||
* @param string User or group the item is being shared with
|
||||
* @param int CRUDS permissions
|
||||
* @return bool Returns true on success or false on failure
|
||||
* @return bool|string Returns true on success or false on failure, Returns token on success for links
|
||||
*/
|
||||
public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions) {
|
||||
$uidOwner = \OC_User::getUser();
|
||||
@@ -231,23 +248,33 @@ class Share {
|
||||
$shareWith['users'] = array_diff(\OC_Group::usersInGroup($group), array($uidOwner));
|
||||
} else if ($shareType === self::SHARE_TYPE_LINK) {
|
||||
if (\OC_Appconfig::getValue('core', 'shareapi_allow_links', 'yes') == 'yes') {
|
||||
// when updating a link share
|
||||
if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null, $uidOwner, self::FORMAT_NONE, null, 1)) {
|
||||
// If password is set delete the old link
|
||||
if (isset($shareWith)) {
|
||||
self::delete($checkExists['id']);
|
||||
} else {
|
||||
$message = 'Sharing '.$itemSource.' failed, because this item is already shared with a link';
|
||||
\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
|
||||
throw new \Exception($message);
|
||||
}
|
||||
// remember old token
|
||||
$oldToken = $checkExists['token'];
|
||||
//delete the old share
|
||||
self::delete($checkExists['id']);
|
||||
}
|
||||
|
||||
// Generate hash of password - same method as user passwords
|
||||
if (isset($shareWith)) {
|
||||
$forcePortable = (CRYPT_BLOWFISH != 1);
|
||||
$hasher = new \PasswordHash(8, $forcePortable);
|
||||
$shareWith = $hasher->HashPassword($shareWith.\OC_Config::getValue('passwordsalt', ''));
|
||||
}
|
||||
return self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions);
|
||||
|
||||
// Generate token
|
||||
if (isset($oldToken)) {
|
||||
$token = $oldToken;
|
||||
} else {
|
||||
$token = \OC_Util::generate_random_bytes(self::TOKEN_LENGTH);
|
||||
}
|
||||
$result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, $token);
|
||||
if ($result) {
|
||||
return $token;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$message = 'Sharing '.$itemSource.' failed, because sharing with links is not allowed';
|
||||
\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
|
||||
@@ -326,6 +353,22 @@ class Share {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unshare an item from all users, groups, and remove all links
|
||||
* @param string Item type
|
||||
* @param string Item source
|
||||
* @return Returns true on success or false on failure
|
||||
*/
|
||||
public static function unshareAll($itemType, $itemSource) {
|
||||
if ($shares = self::getItemShared($itemType, $itemSource)) {
|
||||
foreach ($shares as $share) {
|
||||
self::delete($share['id']);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unshare an item shared with the current user
|
||||
* @param string Item type
|
||||
@@ -466,6 +509,24 @@ class Share {
|
||||
throw new \Exception($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if resharing is allowed
|
||||
* @return Returns true if allowed or false
|
||||
*
|
||||
* Resharing is allowed by default if not configured
|
||||
*
|
||||
*/
|
||||
private static function isResharingAllowed() {
|
||||
if (!isset(self::$isResharingAllowed)) {
|
||||
if (\OC_Appconfig::getValue('core', 'shareapi_allow_resharing', 'yes') == 'yes') {
|
||||
self::$isResharingAllowed = true;
|
||||
} else {
|
||||
self::$isResharingAllowed = false;
|
||||
}
|
||||
}
|
||||
return self::$isResharingAllowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a list of collection item types for the specified item type
|
||||
* @param string Item type
|
||||
@@ -533,7 +594,7 @@ class Share {
|
||||
$itemTypes = $collectionTypes;
|
||||
}
|
||||
$placeholders = join(',', array_fill(0, count($itemTypes), '?'));
|
||||
$where .= ' WHERE item_type IN ('.$placeholders.'))';
|
||||
$where .= ' WHERE `item_type` IN ('.$placeholders.'))';
|
||||
$queryArgs = $itemTypes;
|
||||
} else {
|
||||
$where = ' WHERE `item_type` = ?';
|
||||
@@ -610,7 +671,7 @@ class Share {
|
||||
$queryArgs[] = $item;
|
||||
if ($includeCollections && $collectionTypes) {
|
||||
$placeholders = join(',', array_fill(0, count($collectionTypes), '?'));
|
||||
$where .= ' OR item_type IN ('.$placeholders.'))';
|
||||
$where .= ' OR `item_type` IN ('.$placeholders.'))';
|
||||
$queryArgs = array_merge($queryArgs, $collectionTypes);
|
||||
}
|
||||
}
|
||||
@@ -639,16 +700,16 @@ class Share {
|
||||
} else {
|
||||
if (isset($uidOwner)) {
|
||||
if ($itemType == 'file' || $itemType == 'folder') {
|
||||
$select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `file_source`, `path`, `permissions`, `stime`, `expiration`';
|
||||
$select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `file_source`, `path`, `permissions`, `stime`, `expiration`, `token`';
|
||||
} else {
|
||||
$select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `permissions`, `stime`, `file_source`, `expiration`';
|
||||
$select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `permissions`, `stime`, `file_source`, `expiration`, `token`';
|
||||
}
|
||||
} else {
|
||||
if ($fileDependent) {
|
||||
if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_FILE_APP || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) {
|
||||
$select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, `share_type`, `share_with`, `file_source`, `path`, `file_target`, `permissions`, `expiration`, `name`, `ctime`, `mtime`, `mimetype`, `size`, `encrypted`, `versioned`, `writable`';
|
||||
} else {
|
||||
$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`';
|
||||
$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`, `token`';
|
||||
}
|
||||
} else {
|
||||
$select = '*';
|
||||
@@ -658,6 +719,9 @@ class Share {
|
||||
$root = strlen($root);
|
||||
$query = \OC_DB::prepare('SELECT '.$select.' FROM `*PREFIX*share` '.$where, $queryLimit);
|
||||
$result = $query->execute($queryArgs);
|
||||
if (\OC_DB::isError($result)) {
|
||||
\OC_Log::write('OCP\Share', \OC_DB::getErrorMessage($result) . ', select=' . $select . ' where=' . $where, \OC_Log::ERROR);
|
||||
}
|
||||
$items = array();
|
||||
$targets = array();
|
||||
while ($row = $result->fetchRow()) {
|
||||
@@ -710,6 +774,10 @@ class Share {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Check if resharing is allowed, if not remove share permission
|
||||
if (isset($row['permissions']) && !self::isResharingAllowed()) {
|
||||
$row['permissions'] &= ~self::PERMISSION_SHARE;
|
||||
}
|
||||
$items[$row['id']] = $row;
|
||||
}
|
||||
if (!empty($items)) {
|
||||
@@ -817,7 +885,7 @@ class Share {
|
||||
* @param bool|array Parent folder target (optional)
|
||||
* @return bool Returns true on success or false on failure
|
||||
*/
|
||||
private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $parentFolder = null) {
|
||||
private static function put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, $parentFolder = null, $token = null) {
|
||||
$backend = self::getBackend($itemType);
|
||||
// Check if this is a reshare
|
||||
if ($checkReshare = self::getItemSharedWithBySource($itemType, $itemSource, self::FORMAT_NONE, null, true)) {
|
||||
@@ -828,7 +896,7 @@ class Share {
|
||||
throw new \Exception($message);
|
||||
}
|
||||
// Check if share permissions is granted
|
||||
if ((int)$checkReshare['permissions'] & self::PERMISSION_SHARE) {
|
||||
if (self::isResharingAllowed() && (int)$checkReshare['permissions'] & self::PERMISSION_SHARE) {
|
||||
if (~(int)$checkReshare['permissions'] & $permissions) {
|
||||
$message = 'Sharing '.$itemSource.' failed, because the permissions exceed permissions granted to '.$uidOwner;
|
||||
\OC_Log::write('OCP\Share', $message, \OC_Log::ERROR);
|
||||
@@ -874,7 +942,7 @@ class Share {
|
||||
$fileSource = null;
|
||||
}
|
||||
}
|
||||
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`, `parent`, `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`, `file_target`) VALUES (?,?,?,?,?,?,?,?,?,?,?)');
|
||||
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` (`item_type`, `item_source`, `item_target`, `parent`, `share_type`, `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`, `file_target`, `token`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)');
|
||||
// Share with a group
|
||||
if ($shareType == self::SHARE_TYPE_GROUP) {
|
||||
$groupItemTarget = self::generateTarget($itemType, $itemSource, $shareType, $shareWith['group'], $uidOwner, $suggestedItemTarget);
|
||||
@@ -895,7 +963,7 @@ class Share {
|
||||
} else {
|
||||
$groupFileTarget = null;
|
||||
}
|
||||
$query->execute(array($itemType, $itemSource, $groupItemTarget, $parent, $shareType, $shareWith['group'], $uidOwner, $permissions, time(), $fileSource, $groupFileTarget));
|
||||
$query->execute(array($itemType, $itemSource, $groupItemTarget, $parent, $shareType, $shareWith['group'], $uidOwner, $permissions, time(), $fileSource, $groupFileTarget, $token));
|
||||
// Save this id, any extra rows for this group share will need to reference it
|
||||
$parent = \OC_DB::insertid('*PREFIX*share');
|
||||
// Loop through all users of this group in case we need to add an extra row
|
||||
@@ -920,8 +988,8 @@ class Share {
|
||||
}
|
||||
// Insert an extra row for the group share if the item or file target is unique for this user
|
||||
if ($itemTarget != $groupItemTarget || (isset($fileSource) && $fileTarget != $groupFileTarget)) {
|
||||
$query->execute(array($itemType, $itemSource, $itemTarget, $parent, self::$shareTypeGroupUserUnique, $uid, $uidOwner, $permissions, time(), $fileSource, $fileTarget));
|
||||
\OC_DB::insertid('*PREFIX*share');
|
||||
$query->execute(array($itemType, $itemSource, $itemTarget, $parent, self::$shareTypeGroupUserUnique, $uid, $uidOwner, $permissions, time(), $fileSource, $fileTarget, $token));
|
||||
$id = \OC_DB::insertid('*PREFIX*share');
|
||||
}
|
||||
}
|
||||
if ($parentFolder === true) {
|
||||
@@ -945,7 +1013,7 @@ class Share {
|
||||
} else {
|
||||
$fileTarget = null;
|
||||
}
|
||||
$query->execute(array($itemType, $itemSource, $itemTarget, $parent, $shareType, $shareWith, $uidOwner, $permissions, time(), $fileSource, $fileTarget));
|
||||
$query->execute(array($itemType, $itemSource, $itemTarget, $parent, $shareType, $shareWith, $uidOwner, $permissions, time(), $fileSource, $fileTarget, $token));
|
||||
$id = \OC_DB::insertid('*PREFIX*share');
|
||||
if ($parentFolder === true) {
|
||||
$parentFolders['id'] = $id;
|
||||
|
||||
@@ -18,6 +18,9 @@ class OC_Request {
|
||||
if(OC::$CLI) {
|
||||
return 'localhost';
|
||||
}
|
||||
if(OC_Config::getValue('overwritehost', '')<>''){
|
||||
return OC_Config::getValue('overwritehost');
|
||||
}
|
||||
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
|
||||
if (strpos($_SERVER['HTTP_X_FORWARDED_HOST'], ",") !== false) {
|
||||
$host = trim(array_pop(explode(",", $_SERVER['HTTP_X_FORWARDED_HOST'])));
|
||||
@@ -40,6 +43,9 @@ class OC_Request {
|
||||
* Returns the server protocol. It respects reverse proxy servers and load balancers
|
||||
*/
|
||||
public static function serverProtocol() {
|
||||
if(OC_Config::getValue('overwriteprotocol', '')<>''){
|
||||
return OC_Config::getValue('overwriteprotocol');
|
||||
}
|
||||
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
|
||||
$proto = strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']);
|
||||
}else{
|
||||
|
||||
@@ -5,12 +5,19 @@ $hasMySQL = is_callable('mysql_connect');
|
||||
$hasPostgreSQL = is_callable('pg_connect');
|
||||
$hasOracle = is_callable('oci_connect');
|
||||
$datadir = OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data');
|
||||
|
||||
// Test if .htaccess is working
|
||||
$content = "deny from all";
|
||||
file_put_contents(OC::$SERVERROOT.'/data/.htaccess', $content);
|
||||
|
||||
$opts = array(
|
||||
'hasSQLite' => $hasSQLite,
|
||||
'hasMySQL' => $hasMySQL,
|
||||
'hasPostgreSQL' => $hasPostgreSQL,
|
||||
'hasOracle' => $hasOracle,
|
||||
'directory' => $datadir,
|
||||
'secureRNG' => OC_Util::secureRNG_available(),
|
||||
'htaccessWorking' => OC_Util::ishtaccessworking(),
|
||||
'errors' => array(),
|
||||
);
|
||||
|
||||
@@ -63,6 +70,9 @@ class OC_Setup {
|
||||
if(empty($options['dbname'])) {
|
||||
$error[] = "$dbprettyname enter the database name.";
|
||||
}
|
||||
if(substr_count($options['dbname'], '.') >= 1){
|
||||
$error[] = "$dbprettyname you may not use dots in the database name";
|
||||
}
|
||||
if($dbtype != 'oci' && empty($options['dbhost'])) {
|
||||
$error[] = "$dbprettyname set the database host.";
|
||||
}
|
||||
@@ -567,6 +577,10 @@ class OC_Setup {
|
||||
$content.= "RewriteRule ^apps/([^/]*)/(.*\.(css|php))$ index.php?app=$1&getfile=$2 [QSA,L]\n";
|
||||
$content.= "RewriteRule ^remote/(.*) remote.php [QSA,L]\n";
|
||||
$content.= "</IfModule>\n";
|
||||
$content.= "<IfModule mod_mime.c>\n";
|
||||
$content.= "AddType image/svg+xml svg svgz\n";
|
||||
$content.= "AddEncoding gzip svgz\n";
|
||||
$content.= "</IfModule>\n";
|
||||
$content.= "Options -Indexes\n";
|
||||
@file_put_contents(OC::$SERVERROOT.'/.htaccess', $content); //supress errors in case we don't have permissions for it
|
||||
|
||||
|
||||
+19
-3
@@ -159,9 +159,11 @@ class OC_Template{
|
||||
$this->vars['requestlifespan'] = OC_Util::$callLifespan;
|
||||
$parts = explode('/', $app); // fix translation when app is something like core/lostpassword
|
||||
$this->l10n = OC_L10N::get($parts[0]);
|
||||
header('X-Frame-Options: Sameorigin');
|
||||
header('X-XSS-Protection: 1; mode=block');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
|
||||
// Some headers to enhance security
|
||||
header('X-Frame-Options: Sameorigin');
|
||||
header('X-XSS-Protection: 1; mode=block');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
|
||||
$this->findTemplate($name);
|
||||
}
|
||||
@@ -480,4 +482,18 @@ class OC_Template{
|
||||
}
|
||||
return $content->printPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Print a fatal error page and terminates the script
|
||||
* @param string $error The error message to show
|
||||
* @param string $hint An option hint message
|
||||
*/
|
||||
public static function printErrorPage( $error, $hint = '' ) {
|
||||
$error['error']=$error;
|
||||
$error['hint']=$hint;
|
||||
$errors[]=$error;
|
||||
OC_Template::printGuestPage("", "error", array("errors" => $errors));
|
||||
die();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ class OC_TemplateLayout extends OC_Template {
|
||||
$jsfiles = self::findJavascriptFiles(OC_Util::$scripts);
|
||||
$this->assign('jsfiles', array(), false);
|
||||
if (!empty(OC_Util::$core_scripts)) {
|
||||
$this->append( 'jsfiles', OC_Helper::linkToRemote('core.js', false));
|
||||
$this->append( 'jsfiles', OC_Helper::linkToRemoteBase('core.js', false));
|
||||
}
|
||||
foreach($jsfiles as $info) {
|
||||
$root = $info[0];
|
||||
@@ -63,7 +63,7 @@ class OC_TemplateLayout extends OC_Template {
|
||||
$cssfiles = self::findStylesheetFiles(OC_Util::$styles);
|
||||
$this->assign('cssfiles', array());
|
||||
if (!empty(OC_Util::$core_styles)) {
|
||||
$this->append( 'cssfiles', OC_Helper::linkToRemote('core.css', false));
|
||||
$this->append( 'cssfiles', OC_Helper::linkToRemoteBase('core.css', false));
|
||||
}
|
||||
foreach($cssfiles as $info) {
|
||||
$root = $info[0];
|
||||
|
||||
+10
-4
@@ -182,7 +182,7 @@ class OC_User {
|
||||
$backend->createUser($uid,$password);
|
||||
OC_Hook::emit( "OC_User", "post_createUser", array( "uid" => $uid, "password" => $password ));
|
||||
|
||||
return true;
|
||||
return self::userExists($uid);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -204,12 +204,19 @@ class OC_User {
|
||||
foreach(self::$_usedBackends as $backend) {
|
||||
$backend->deleteUser($uid);
|
||||
}
|
||||
if (self::userExists($uid)) {
|
||||
return false;
|
||||
}
|
||||
// We have to delete the user from all groups
|
||||
foreach( OC_Group::getUserGroups( $uid ) as $i ) {
|
||||
OC_Group::removeFromGroup( $uid, $i );
|
||||
}
|
||||
// Delete the user's keys in preferences
|
||||
OC_Preferences::deleteUser($uid);
|
||||
|
||||
// Delete user files in /data/
|
||||
OC_Helper::rmdirr(OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ) . '/'.$uid.'/');
|
||||
|
||||
// Emit and exit
|
||||
OC_Hook::emit( "OC_User", "post_deleteUser", array( "uid" => $uid ));
|
||||
return true;
|
||||
@@ -363,8 +370,7 @@ class OC_User {
|
||||
* @param $password The password
|
||||
* @returns string
|
||||
*
|
||||
* Check if the password is correct without logging in the user
|
||||
* returns the user id or false
|
||||
* returns the path to the users home directory
|
||||
*/
|
||||
public static function getHome($uid) {
|
||||
foreach(self::$_usedBackends as $backend) {
|
||||
@@ -473,7 +479,7 @@ class OC_User {
|
||||
public static function setMagicInCookie($username, $token) {
|
||||
$secure_cookie = OC_Config::getValue("forcessl", false);
|
||||
setcookie("oc_username", $username, time()+60*60*24*15, '', '', $secure_cookie);
|
||||
setcookie("oc_token", $token, time()+60*60*24*15, '', '', $secure_cookie);
|
||||
setcookie("oc_token", $token, time()+60*60*24*15, '', '', $secure_cookie, true);
|
||||
setcookie("oc_remember_login", true, time()+60*60*24*15, '', '', $secure_cookie);
|
||||
}
|
||||
|
||||
|
||||
+90
-26
@@ -24,6 +24,11 @@ class OC_Util {
|
||||
$user = OC_User::getUser();
|
||||
}
|
||||
|
||||
// load all filesystem apps before, so no setup-hook gets lost
|
||||
if(!isset($RUNTIME_NOAPPS) || !$RUNTIME_NOAPPS) {
|
||||
OC_App::loadApps(array('filesystem'));
|
||||
}
|
||||
|
||||
// the filesystem will finish when $user is not empty,
|
||||
// mark fs setup here to avoid doing the setup from loading
|
||||
// OC_Filesystem
|
||||
@@ -47,25 +52,13 @@ class OC_Util {
|
||||
}
|
||||
//jail the user into his "home" directory
|
||||
OC_Filesystem::mount('OC_Filestorage_Local', array('datadir' => $user_root), $user);
|
||||
OC_Filesystem::init($user_dir);
|
||||
OC_Filesystem::init($user_dir, $user);
|
||||
$quotaProxy=new OC_FileProxy_Quota();
|
||||
$fileOperationProxy = new OC_FileProxy_FileOperations();
|
||||
OC_FileProxy::register($quotaProxy);
|
||||
OC_FileProxy::register($fileOperationProxy);
|
||||
// Load personal mount config
|
||||
if (is_file($user_root.'/mount.php')) {
|
||||
$mountConfig = include($user_root.'/mount.php');
|
||||
if (isset($mountConfig['user'][$user])) {
|
||||
foreach ($mountConfig['user'][$user] as $mountPoint => $options) {
|
||||
OC_Filesystem::mount($options['class'], $options['options'], $mountPoint);
|
||||
}
|
||||
}
|
||||
|
||||
$mtime=filemtime($user_root.'/mount.php');
|
||||
$previousMTime=OC_Preferences::getValue($user,'files','mountconfigmtime',0);
|
||||
if($mtime>$previousMTime) {//mount config has changed, filecache needs to be updated
|
||||
OC_FileCache::triggerUpdate($user);
|
||||
OC_Preferences::setValue($user,'files','mountconfigmtime',$mtime);
|
||||
}
|
||||
}
|
||||
self::loadUserMountPoints($user);
|
||||
OC_Hook::emit('OC_Filesystem', 'setup', array('user' => $user, 'user_dir' => $user_dir));
|
||||
}
|
||||
}
|
||||
@@ -74,6 +67,27 @@ class OC_Util {
|
||||
OC_Filesystem::tearDown();
|
||||
self::$fsSetup=false;
|
||||
}
|
||||
|
||||
public static function loadUserMountPoints($user) {
|
||||
$user_dir = '/'.$user.'/files';
|
||||
$user_root = OC_User::getHome($user);
|
||||
$userdirectory = $user_root . '/files';
|
||||
if (is_file($user_root.'/mount.php')) {
|
||||
$mountConfig = include($user_root.'/mount.php');
|
||||
if (isset($mountConfig['user'][$user])) {
|
||||
foreach ($mountConfig['user'][$user] as $mountPoint => $options) {
|
||||
OC_Filesystem::mount($options['class'], $options['options'], $mountPoint);
|
||||
}
|
||||
}
|
||||
|
||||
$mtime=filemtime($user_root.'/mount.php');
|
||||
$previousMTime=OC_Preferences::getValue($user,'files','mountconfigmtime',0);
|
||||
if($mtime>$previousMTime) {//mount config has changed, filecache needs to be updated
|
||||
OC_FileCache::triggerUpdate($user);
|
||||
OC_Preferences::setValue($user,'files','mountconfigmtime',$mtime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get the current installed version of ownCloud
|
||||
@@ -81,7 +95,7 @@ class OC_Util {
|
||||
*/
|
||||
public static function getVersion() {
|
||||
// hint: We only can count up. So the internal version number of ownCloud 4.5 will be 4.90.0. This is not visible to the user
|
||||
return array(4,90,00);
|
||||
return array(4,90,5);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,7 +103,7 @@ class OC_Util {
|
||||
* @return string
|
||||
*/
|
||||
public static function getVersionString() {
|
||||
return '4.5';
|
||||
return '4.5.4';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -287,7 +301,10 @@ class OC_Util {
|
||||
$errors[]=array('error'=>'PHP module zlib is not installed.<br/>','hint'=>'Please ask your server administrator to install the module.');
|
||||
$web_server_restart= false;
|
||||
}
|
||||
|
||||
if(!function_exists('iconv')) {
|
||||
$errors[]=array('error'=>'PHP module iconv is not installed.<br/>','hint'=>'Please ask your server administrator to install the module.');
|
||||
$web_server_restart= false;
|
||||
}
|
||||
if(!function_exists('simplexml_load_string')) {
|
||||
$errors[]=array('error'=>'PHP module SimpleXML is not installed.<br/>','hint'=>'Please ask your server administrator to install the module.');
|
||||
$web_server_restart= false;
|
||||
@@ -532,6 +549,11 @@ class OC_Util {
|
||||
|
||||
// creating a test file
|
||||
$testfile = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$filename;
|
||||
|
||||
if(file_exists($testfile)){// already running this test, possible recursive call
|
||||
return false;
|
||||
}
|
||||
|
||||
$fp = @fopen($testfile, 'w');
|
||||
@fwrite($fp, $testcontent);
|
||||
@fclose($fp);
|
||||
@@ -553,13 +575,25 @@ class OC_Util {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Generates random bytes with "openssl_random_pseudo_bytes" with a fallback for systems without openssl
|
||||
* Inspired by gorgo on php.net
|
||||
* @param Int with the length of the random
|
||||
* @return String with the random bytes
|
||||
/**
|
||||
* clear all levels of output buffering
|
||||
*/
|
||||
public static function obEnd(){
|
||||
while (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Generates a cryptographical secure pseudorandom string
|
||||
* @param Int with the length of the random string
|
||||
* @return String
|
||||
* Please also update secureRNG_available if you change something here
|
||||
*/
|
||||
public static function generate_random_bytes($length = 30) {
|
||||
|
||||
// Try to use openssl_random_pseudo_bytes
|
||||
if(function_exists('openssl_random_pseudo_bytes')) {
|
||||
$pseudo_byte = bin2hex(openssl_random_pseudo_bytes($length, $strong));
|
||||
if($strong == TRUE) {
|
||||
@@ -567,9 +601,16 @@ class OC_Util {
|
||||
}
|
||||
}
|
||||
|
||||
// fallback to mt_rand()
|
||||
// Try to use /dev/urandom
|
||||
$fp = @file_get_contents('/dev/urandom', false, null, 0, $length);
|
||||
if ($fp !== FALSE) {
|
||||
$string = substr(bin2hex($fp), 0, $length);
|
||||
return $string;
|
||||
}
|
||||
|
||||
// Fallback to mt_rand()
|
||||
$characters = '0123456789';
|
||||
$characters .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
||||
$characters .= 'abcdefghijklmnopqrstuvwxyz';
|
||||
$charactersLength = strlen($characters)-1;
|
||||
$pseudo_byte = "";
|
||||
|
||||
@@ -579,4 +620,27 @@ class OC_Util {
|
||||
}
|
||||
return $pseudo_byte;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Checks if a secure random number generator is available
|
||||
* @return bool
|
||||
*/
|
||||
public static function secureRNG_available() {
|
||||
|
||||
// Check openssl_random_pseudo_bytes
|
||||
if(function_exists('openssl_random_pseudo_bytes')) {
|
||||
openssl_random_pseudo_bytes(1, $strong);
|
||||
if($strong == TRUE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check /dev/urandom
|
||||
$fp = @file_get_contents('/dev/urandom', false, null, 0, 1);
|
||||
if ($fp !== FALSE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
|
||||
require_once '../lib/base.php';
|
||||
|
||||
$url='http://'.substr(OCP\Util::getServerHost().$_SERVER['REQUEST_URI'], 0, -17).'ocs/v1.php/';
|
||||
$url=OCP\Util::getServerProtocol().'://'.substr(OCP\Util::getServerHost().$_SERVER['REQUEST_URI'], 0, -17).'ocs/v1.php/';
|
||||
|
||||
echo('
|
||||
<providers>
|
||||
|
||||
@@ -37,14 +37,17 @@ $username = $_POST["username"];
|
||||
$password = $_POST["password"];
|
||||
|
||||
// Does the group exist?
|
||||
if( in_array( $username, OC_User::getUsers())) {
|
||||
if(OC_User::userExists($username)) {
|
||||
OC_JSON::error(array("data" => array( "message" => "User already exists" )));
|
||||
exit();
|
||||
}
|
||||
|
||||
// Return Success story
|
||||
try {
|
||||
OC_User::createUser($username, $password);
|
||||
if (!OC_User::createUser($username, $password)) {
|
||||
OC_JSON::error(array('data' => array( 'message' => 'User creation failed for '.$username )));
|
||||
exit();
|
||||
}
|
||||
foreach( $groups as $i ) {
|
||||
if(!OC_Group::groupExists($i)) {
|
||||
OC_Group::createGroup($i);
|
||||
|
||||
@@ -8,6 +8,11 @@ OCP\JSON::callCheck();
|
||||
|
||||
$username = $_POST["username"];
|
||||
|
||||
// A user shouldn't be able to delete his own account
|
||||
if(OC_User::getUser() === $username) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if(!OC_Group::inGroup(OC_User::getUser(), 'admin') && !OC_SubAdmin::isUserAccessible(OC_User::getUser(), $username)) {
|
||||
$l = OC_L10N::get('core');
|
||||
OC_JSON::error(array( 'data' => array( 'message' => $l->t('Authentication error') )));
|
||||
@@ -20,4 +25,4 @@ if( OC_User::deleteUser( $username )) {
|
||||
}
|
||||
else{
|
||||
OC_JSON::error(array("data" => array( "message" => $l->t("Unable to delete user") )));
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user