2727namespace OCA \Files \Controller ;
2828
2929use OC_Files ;
30+ use OCA \Files \AppInfo \Application ;
3031use OCA \Files \Helper ;
3132use OCP \AppFramework \Controller ;
3233use OCP \AppFramework \Http \JSONResponse ;
34+ use OCP \AppFramework \Http \NotFoundResponse ;
3335use OCP \Files \NotFoundException ;
36+ use OCP \IConfig ;
3437use OCP \IRequest ;
3538use OCP \ISession ;
39+ use OCP \Security \ISecureRandom ;
40+ use function json_decode ;
41+ use function json_encode ;
3642
3743class AjaxController extends Controller {
3844 /** @var ISession */
3945 private $ session ;
46+ /** @var IConfig */
47+ private $ config ;
4048
41- public function __construct (string $ appName , IRequest $ request , ISession $ session ) {
49+ /** @var ISecureRandom */
50+ private $ secureRandom ;
51+
52+ public function __construct (
53+ string $ appName ,
54+ IRequest $ request ,
55+ ISession $ session ,
56+ IConfig $ config ,
57+ ISecureRandom $ secureRandom
58+ ) {
4259 parent ::__construct ($ appName , $ request );
4360 $ this ->session = $ session ;
4461 $ this ->request = $ request ;
62+ $ this ->config = $ config ;
63+ $ this ->secureRandom = $ secureRandom ;
4564 }
4665
4766 /**
@@ -67,26 +86,62 @@ public function getStorageStats(string $dir = '/'): JSONResponse {
6786 /**
6887 * @NoAdminRequired
6988 */
70- public function download ($ files , string $ dir = '' , string $ downloadStartSecret = '' ) {
89+ public function registerDownload ($ files , string $ dir = '' , string $ downloadStartSecret = '' ) {
7190 if (is_string ($ files )) {
7291 $ files = [$ files ];
7392 } elseif (!is_array ($ files )) {
7493 throw new \InvalidArgumentException ('Invalid argument for files ' );
7594 }
7695
96+ $ attempts = 0 ;
97+ do {
98+ if ($ attempts === 10 ) {
99+ throw new \RuntimeException ('Failed to create unique download token ' );
100+ }
101+ $ token = $ this ->secureRandom ->generate (15 );
102+ $ attempts ++;
103+ } while ($ this ->config ->getAppValue (Application::APP_ID , Application::DL_TOKEN_PREFIX . $ token , '' ) !== '' );
104+
105+ $ this ->config ->setAppValue (
106+ Application::APP_ID ,
107+ Application::DL_TOKEN_PREFIX . $ token ,
108+ json_encode ([
109+ 'files ' => $ files ,
110+ 'dir ' => $ dir ,
111+ 'downloadStartSecret ' => $ downloadStartSecret ,
112+ 'lastActivity ' => time ()
113+ ])
114+ );
115+
116+ return new JSONResponse (['token ' => $ token ]);
117+ }
118+
119+ /**
120+ * @NoAdminRequired
121+ * @NoCSRFRequired
122+ */
123+ public function download (string $ token ) {
124+ $ dataStr = $ this ->config ->getAppValue (Application::APP_ID , Application::DL_TOKEN_PREFIX . $ token , '' );
125+ if ($ dataStr === '' ) {
126+ return new NotFoundResponse ();
127+ }
77128 $ this ->session ->close ();
78129
79- if (strlen ($ downloadStartSecret ) <= 32
80- && (preg_match ('!^[a-zA-Z0-9]+$! ' , $ downloadStartSecret ) === 1 )
130+ $ data = json_decode ($ dataStr , true );
131+ $ data ['lastActivity ' ] = time ();
132+ $ this ->config ->setAppValue (Application::APP_ID , Application::DL_TOKEN_PREFIX . $ token , json_encode ($ data ));
133+
134+ if (strlen ($ data ['downloadStartSecret ' ]) <= 32
135+ && (preg_match ('!^[a-zA-Z0-9]+$! ' , $ data ['downloadStartSecret ' ]) === 1 )
81136 ) {
82- setcookie ('ocDownloadStarted ' , $ downloadStartSecret , time () + 20 , '/ ' );
137+ setcookie ('ocDownloadStarted ' , $ data [ ' downloadStartSecret ' ] , time () + 20 , '/ ' );
83138 }
84139
85140 $ serverParams = [ 'head ' => $ this ->request ->getMethod () === 'HEAD ' ];
86141 if (isset ($ _SERVER ['HTTP_RANGE ' ])) {
87142 $ serverParams ['range ' ] = $ this ->request ->getHeader ('Range ' );
88143 }
89144
90- OC_Files::get ($ dir , $ files , $ serverParams );
145+ OC_Files::get ($ data [ ' dir ' ] , $ data [ ' files ' ] , $ serverParams );
91146 }
92147}
0 commit comments