winix/functions/functions.cpp

417 lines
7.4 KiB
C++
Executable File

/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2010, Tomasz Sowa
* All rights reserved.
*
*/
#include "functions.h"
#include "core/log.h"
#include "core/misc.h"
#include "templates/templates.h"
void Functions::SetConfig(Config * pconfig)
{
config = pconfig;
}
void Functions::SetRequest(Request * prequest)
{
request = prequest;
}
void Functions::SetDb(Db * pdb)
{
db = pdb;
}
void Functions::SetSystem(System * psystem)
{
system = psystem;
}
void Functions::SetTemplates(Templates * ptemplates)
{
templates = ptemplates;
}
void Functions::SetNotify(Notify * pnotify)
{
notify = pnotify;
}
FunctionBase * Functions::Find(const std::string & function_name)
{
Table::iterator i = table.find(function_name);
if( i == table.end() )
return 0;
return i->second;
}
void Functions::SetObjects(FunctionBase * fun)
{
fun->SetConfig(config);
fun->SetRequest(request);
fun->SetDb(db);
fun->SetSystem(system);
fun->SetFunctions(this);
fun->SetTemplates(templates);
fun->SetNotify(notify);
}
void Functions::Add(FunctionBase * fun)
{
if( Find(fun->fun.url) )
{
log << log1 << "Functions: function " << fun->fun.url
<< " already exists (skipped)" << logend;
return;
}
table[fun->fun.url] = fun;
SetObjects(fun);
}
void Functions::Add(FunctionBase & fun)
{
Add(&fun);
}
void Functions::Create()
{
Add(fun_adduser);
Add(fun_cat);
Add(fun_chmod);
Add(fun_chown);
Add(fun_ckeditor);
Add(fun_cp);
Add(fun_createthread);
Add(fun_createticket);
Add(fun_default);
Add(fun_download);
Add(fun_editticket);
Add(fun_emacs);
Add(fun_last);
Add(fun_login);
Add(fun_logout);
Add(fun_ls);
Add(fun_mkdir);
Add(fun_mv);
Add(fun_node);
Add(fun_priv);
Add(fun_reload);
Add(fun_rm);
Add(fun_run);
Add(fun_subject);
Add(fun_thread);
Add(fun_ticket);
Add(fun_tinymce);
Add(fun_uname);
Add(fun_upload);
Add(fun_uptime);
Add(fun_who);
}
void Functions::Parse()
{
function_parser.Parse(request, db, this, system);
}
void Functions::SetDefaultFunctionForFile()
{
if( request->item.auth != Item::auth_none )
request->function = &fun_download;
else
if( system->HasReadExecAccess(request->item) )
request->function = &fun_run;
else
request->function = &fun_cat;
log << log3 << "Content: default function: " << request->function->fun.url << logend;
}
void Functions::SetDefaultFunctionForDir()
{
long default_item = request->dir_tab.back()->default_item;
if( default_item != -1 )
{
log << log3 << "Content: Default item: id: " << default_item << logend;
system->RedirectTo(default_item);
return;
}
if( system->mounts.pmount->type == Mount::thread )
{
request->function = &fun_thread;
log << log3 << "Content: default function: " << request->function->fun.url << logend;
}
else
if( system->mounts.pmount->type == Mount::ticket )
{
request->function = &fun_ticket;
log << log3 << "Content: default function: " << request->function->fun.url << logend;
}
else
{
// cms
request->function = &fun_ls;
log << log3 << "Content: default function: " << request->function->fun.url << logend;
}
}
void Functions::SetDefaultFunction()
{
if( request->is_item )
{
SetDefaultFunctionForFile();
}
else
{
SetDefaultFunctionForDir();
}
}
void Functions::MakeGet()
{
if( request->role == Request::authorizer )
{
// in authorizer mode only cat function is available
// (and must be default)
if( request->function )
{
request->status = WINIX_ERR_NO_ITEM;
log << log1 << "Content: in authorizer mode only 'cat' funtion is available and must "
"be default (not in the url)" << logend;
return;
}
request->function = &fun_cat;
}
if( !request->function )
SetDefaultFunction();
if( !request->redirect_to.empty() )
return;
if( !request->function )
{
request->status = WINIX_ERR_NO_FUNCTION;
log << log1 << "Functions: no function (neither cat nor ls)" << logend;
return;
}
if( !request->function->HasAccess() )
{
request->status = WINIX_ERR_PERMISSION_DENIED;
return;
}
request->function->MakeGet();
}
void Functions::MakePost()
{
if( request->role == Request::authorizer )
{
request->status = WINIX_ERR_PERMISSION_DENIED;
return;
}
if( !request->function )
SetDefaultFunction();
if( !request->function )
{
request->status = WINIX_ERR_NO_FUNCTION;
log << log1 << "Functions: MakePost: no function" << logend;
return;
}
if( !request->function->HasAccess() )
{
request->status = WINIX_ERR_PERMISSION_DENIED;
return;
}
request->function->MakePost();
}
void Functions::CheckGetPostTimes(time_t difference)
{
time_t now = std::time(0);
if( request->session->puser )
return;
if( request->method != Request::post )
return;
if( now - request->session->last_time_get >= (time_t)difference )
return;
if( request->AllPostVarEmpty() )
return;
request->session->spam_score += 1;
log << log1 << "Functions: spam +1: POST after GET sent too fast" << logend;
}
// returning true if the 'url' has to be changed
bool Functions::ReadItemUrlSubject(Item & item, Item::Type item_type)
{
bool with_url = false;
std::string * new_url = request->PostVar("url");
std::string * new_subject = request->PostVar("subject");
if( item_type == Item::file )
{
if( !request->is_item || (new_url && *new_url != item.url) )
with_url = true;
}
else
{
with_url = true;
}
if( new_url )
item.url = *new_url;
if( new_subject )
item.subject = *new_subject;
if( item.subject.empty() )
{
item.subject = request->dir_tab.back()->subject;
item.subject += "_msg_";
item.subject += ToStr(db->Size(request->dir_tab.back()->id, Item::file));
}
// if item.url is empty then it will be set from item.subject
system->PrepareUrl(item);
return with_url;
}
void Functions::ReadItemContentWithType(Item & item)
{
item.content_type = Item::ct_formatted_text; // default is formatted text
request->PostVar("itemcontent", request->item.content);
request->PostVar("contenttype", temp);
// ct_text and ct_formatted_text can use everyone
if( temp == "0" )
item.content_type = Item::ct_text;
else
if( temp == "1" )
item.content_type = Item::ct_formatted_text;
// those below need special privileges
if( !request->session->puser )
return;
long user_id = request->session->puser->id;
if( temp == "2" )
{
if( system->CanUseHtml(user_id) )
item.content_type = Item::ct_html;
}
else
if( temp == "3" )
{
if( system->CanUseBBCode(user_id) )
item.content_type = Item::ct_bbcode;
}
else
if( temp == "4" )
{
if( system->CanUseRaw(user_id) )
item.content_type = Item::ct_raw;
}
}
// item_type - the type of an item you are expecting to read
// returns true if the url has to be changed
// at the moment this is only checked for Item::file - for Item::dir it returns always true
bool Functions::ReadItem(Item & item, Item::Type item_type)
{
if( item_type == Item::none )
return false;
item.type = item_type;
item.parent_id = request->dir_tab.back()->id; // !! moze to dac jako parametr?
bool edit_with_url = ReadItemUrlSubject(item, item_type);
if( item_type == Item::file )
ReadItemContentWithType(item);
return edit_with_url;
}
void Functions::SetUser(Item & item)
{
if( request->session && request->session->puser )
{
item.user_id = request->session->puser->id;
item.guest_name.clear();
}
else
{
item.user_id = -1;
request->PostVar("guestname", item.guest_name);
}
item.group_id = request->dir_tab.back()->group_id;
}