/* * This file is a part of Winix * and is not publicly distributed * * Copyright (c) 2008-2013, Tomasz Sowa * All rights reserved. * */ #include #include #include #include #include "upload.h" #include "core/misc.h" #include "core/plugin.h" #include "functions/functions.h" #include "templates/templates.h" #include "utf8/utf8.h" namespace Fun { Upload::Upload() { fun.url = L"upload"; } void Upload::Init() { json_serializer.TreatAsTable(L"infospace"); json_serializer.TreatAsNumeric(L"size"); } bool Upload::HasAccess(const Item & item) { // you can use 'upload' only in a directory if( item.type != Item::dir ) return false; if( config->upload_dir.empty() ) { log << log1 << "Request: can't use upload function, upload_dir must be set in the config file" << logend; return false; } if( cur->session->puser && cur->session->puser->super_user ) // super user can use upload everywhere return true; if( !system->HasWriteAccess(item) ) return false; return true; } bool Upload::HasAccess() { if( cur->request->is_item || !HasAccess(*cur->request->dir_tab.back()) ) return false; return true; } bool Upload::UploadSaveStaticFile(const Item & item, const std::wstring & tmp_filename) { if( !system->MakeFilePath(item, path, false, true, config->upload_dirs_chmod) ) { cur->request->status = WINIX_ERR_PERMISSION_DENIED; return false; } if( RenameFile(tmp_filename, path) ) { log << log1 << "Upload: uploaded a new file: " << path << logend; return true; } else { log << log1 << "Upload: can't move the tmp file from: " << tmp_filename << ", to: " << path << logend; cur->request->status = WINIX_ERR_PERMISSION_DENIED; return false; } } void Upload::ResizeImage(Item & item) { Image::Scale scale = system->image.GetImageScale(item.parent_id); system->image.Resize(item.id, scale.cx, scale.cy, scale.aspect_mode, scale.quality); } void Upload::CreateThumb(Item & item) { Image::Scale scale = system->image.GetThumbScale(item.parent_id); system->image.CreateThumb(item.id, scale.cx, scale.cy, scale.aspect_mode, scale.quality); } void Upload::UploadFile(Item & item, const std::wstring & tmp_filename) { // we should add the file beforehand to get the proper item.id cur->request->status = system->AddFile(item, 0, false); if( cur->request->status == WINIX_ERR_OK ) { if( system->CreateNewFile(item) ) { if( UploadSaveStaticFile(item, tmp_filename) ) { cur->request->status = db->EditFileById(item, item.id); plugin.Call(WINIX_FILE_ADDED, &item); if( item.file_type == WINIX_ITEM_FILETYPE_IMAGE ) { if( config->image_resize ) ResizeImage(item); if( config->create_thumb ) CreateThumb(item); } if( is_jquery_upload ) cur->request->item_tab.push_back(item); } else { db->DelItem(item); } } } } bool Upload::FunUploadCheckAbuse() { if( !system->rebus.CheckRebus() ) { cur->request->status = WINIX_ERR_INCORRECT_REBUS; return false; } functions->CheckGetPostTimes(4); if( cur->session->spam_score > 0 ) { cur->request->status = WINIX_ERR_SPAM; log << log1 << "Content: ignoring due to suspected spamming" << logend; return false; } return true; } void Upload::UploadMulti() { cur->request->item.Clear(); // clearing and setting date cur->request->item.parent_id = cur->request->dir_tab.back()->id; cur->request->item.type = Item::file; cur->request->item.privileges = system->NewFilePrivileges(); functions->SetUser(cur->request->item); PostFileTab::iterator i = cur->request->post_file_tab.begin(); for( ; i != cur->request->post_file_tab.end() ; ++i) { const wchar_t * file_name = i->second.filename.c_str(); cur->request->item.subject = file_name; cur->request->item.url = file_name; cur->request->item.file_type = SelectFileType(file_name); cur->request->item.file_size = i->second.file_size; functions->PrepareUrl(cur->request->item); UploadFile(cur->request->item, i->second.tmp_filename); i->second.tmp_filename.clear(); } if( is_jquery_upload ) CreateAnswer(); else system->RedirectToLastDir(); } void Upload::UploadSingle() { const std::wstring & new_subject = cur->request->PostVar(L"subject"); const std::wstring & new_url = cur->request->PostVar(L"url"); bool has_subject = !new_subject.empty(); bool has_url = !new_url.empty(); functions->ReadItem(cur->request->item, Item::file); // ReadItem() changes the url if it is empty functions->SetUser(cur->request->item); cur->request->item.privileges = system->NewFilePrivileges(); PostFile & post_file = cur->request->post_file_tab.begin()->second; const wchar_t * file_name = post_file.filename.c_str(); cur->request->item.file_type = SelectFileType(file_name); cur->request->item.file_size = post_file.file_size; if( !has_subject ) cur->request->item.subject = file_name; if( !has_url ) { cur->request->item.url = file_name; functions->PrepareUrl(cur->request->item); } UploadFile(cur->request->item, post_file.tmp_filename); post_file.tmp_filename.clear(); if( is_jquery_upload ) CreateAnswer(); else if( cur->request->status == WINIX_ERR_OK ) system->RedirectTo(cur->request->item, L"/cat"); } void Upload::MakePost() { cur->request->item_tab.clear(); is_jquery_upload = cur->request->IsParam(L"jquery_upload"); if( cur->request->post_file_tab.empty() ) { cur->request->status = WINIX_ERR_PERMISSION_DENIED; return; } if( !FunUploadCheckAbuse() ) return; if( cur->request->post_file_tab.size() > 1 ) UploadMulti(); else UploadSingle(); } void Upload::CreateAnswer() { Request & req = *cur->request; req.info.name = L"infospace"; // 'infospace' will be serialized to an array for(size_t i=0 ; iCreateItemLink(req.item_tab[i], link); std::wstring & del_url = file.Add(L"delete_url", link); del_url += L"/rm/jquery_upload"; file.Add(L"delete_type", L"POST"); if( req.item_tab[i].file_type == WINIX_ITEM_FILETYPE_IMAGE ) { std::wstring & thumb = file.Add(L"thumbnail_url", link); if( req.item_tab[i].has_thumb ) thumb += L"/-/thumb"; } } cur->request->return_json = true; cur->request->return_info_only = true; cur->request->info_serializer = &json_serializer; } void Upload::MakeGet() { if( cur->request->IsParam(L"jquery_upload") ) { query.Clear(); query.WhereParentId(cur->request->dir_tab.back()->id); query.WhereType(Item::file); query.WhereFileType(WINIX_ITEM_FILETYPE_NONE, false); db->GetItems(cur->request->item_tab, query); CreateAnswer(); } } } // namespace