winix/core/content.cpp

567 lines
11 KiB
C++
Executable File

/*
* This file is a part of CMSLU -- Content Management System like Unix
* and is not publicly distributed
*
* Copyright (c) 2008, Tomasz Sowa
* All rights reserved.
*
*/
#include "content.h"
bool Content::Init()
{
templates.Read();
return true;
}
void Content::AddItem()
{
try
{
request.session->done = Done::added_item;
if( !request.session->puser || !request.session->puser->super_user )
// !! chwilowo tylko super user moze
throw Error(Error::permision_denied);
request.item.user_id = data.users.GetUserId( request.PostVar("user") );
request.item.group_id = data.groups.GetGroupId( request.PostVar("group") );
request.item.privileges = strtol( request.PostVar("privileges").c_str() , 0, 8);
request.item.subject = request.PostVar("subject");
request.item.content = request.PostVar("content");
request.item.parent_id = data.dirs.GetDirId( request.PostVar("directory") );
request.item.type = Item::file;
PrepareUrlSubject(request.item);
request.session->done_status = db.AddItem(request.item);
request.session->done_timer = 2;
request.session->item = request.item;
RedirectTo(request.item);
}
catch(const Error & e)
{
log << log1 << "Content: AddItem: Error: " << e << logend;
request.session->done_status = e;
request.session->done_timer = 1;
}
}
void Content::AssertPrivileges(Item & old_item, Item & new_item)
{
if( !request.CanChangeUser(old_item, new_item.user_id) )
throw Error(Error::cant_change_user);
if( !request.CanChangeGroup(old_item, new_item.group_id) )
throw Error(Error::cant_change_group);
if( !request.CanChangePrivileges(old_item, new_item.privileges) )
throw Error(Error::cant_change_privileges);
}
void Content::EditItem()
{
try
{
request.session->done = Done::edited_item;
request.item.id = atol( request.PostVar("id").c_str() );
request.item.user_id = data.users.GetUserId( request.PostVar("user") );
request.item.group_id = data.groups.GetGroupId( request.PostVar("group") );
request.item.privileges = strtol( request.PostVar("privileges").c_str() , 0, 8);
request.item.subject = request.PostVar("subject");
request.item.content = request.PostVar("content");
bool with_subject = false;
if( request.PostVar("old_subject") != request.item.subject )
with_subject = true;
request.item.parent_id = data.dirs.GetDirId( request.PostVar("directory") ); // !! moze nie byc takiego, zglosic komunikat
request.item.type = Item::file;
PrepareUrlSubject(request.item);
Item old_item;
db.GetPriv(old_item, request.item.id);
AssertPrivileges(old_item, request.item);
if( !request.HasWriteAccess(old_item) )
throw Error(Error::permision_denied);
request.session->done_status = db.EditItemById(request.item, with_subject);
}
catch(const Error & e)
{
log << log1 << "Content: EditItem: Error: " << e << logend;
request.session->done_status = e;
}
request.session->item = request.item;
request.session->done_timer = 2;
RedirectTo(request.item);
}
void Content::LogUser()
{
try
{
std::string & login = request.PostVar("login");
std::string & pass = request.PostVar("password");
long user_id;
if( db.CheckUser(login, pass, user_id) )
{
request.session->puser = data.users.GetUser(user_id);
if( !request.session->puser )
{
log << log1 << "Content: user: " << login << " is in the database but is not in data.users" << logend;
return;
}
request.session->is_logged = true;
request.session->user_id = user_id;
log << log2 << "User " << login << " (id: " << user_id << ") logged" << logend;
}
}
catch(const Error &)
{
}
}
void Content::MakeDirectoryStructure()
{
GetTable::size_type get_table_len = request.get_table.size();
long parent = -1;
for( get_index = 0 ; get_index < get_table_len ; ++get_index)
{
Item * pdir;
if( !data.dirs.GetDir(request.get_table[get_index], parent, &pdir) )
break;
parent = pdir->id;
request.cur_dir_table.push_back( *pdir );
}
// parent - last directory (or -1 if none)
request.dir = parent;
data.dirs.GetDirChilds(parent, request.dir_table);
}
Request::Result Content::StandardFunction(std::string & name)
{
Request::Result res = Request::err404;
// language polish
// in the future there'll be something here
// names of functions should not begin with an underscore '_'
if( name == "dodaj" )
res = Request::add_item;
else
if( name == "edytuj" )
res = Request::edit_item;
else
if( name == "id" )
res = Request::show_item_by_id;
else
if( name == "usun" )
res = Request::del_item;
else
if( name == "potwierdz" )
res = Request::confirm;
else
if( name == "wyloguj" )
res = Request::logout;
return res;
}
void Content::PrepareUrlSubject(Item & item)
{
SetUrlSubjectFromSubject(item);
if( StandardFunction(item.url) != Request::err404 )
{
// names of functions should not begin with an underscore '_'
// and we can simply add one '_' at the beginning
// and the name will be unique
item.url.insert(item.url.begin(), '_');
}
}
bool Content::MakeGetCheckDir()
{
if( get_index == request.get_table.size() )
{
// request was for a directory
////
if( !request.cur_dir_table.empty() && !request.HasReadAccess(request.cur_dir_table.back()) )
{
request.result = Request::err_per_denied;
return true;
}
////
db.GetItems(request.item_table, item);
// !! temporarily
long default_id = -1;
if( request.cur_dir_table.empty() )
{
default_id = data.dirs.root.default_item;
}
else
{
default_id = request.cur_dir_table.back().default_item;
}
if( default_id != -1 )
{
request.result = Request::show_item;
std::vector<Item>::iterator i;
for(i = request.item_table.begin() ; i != request.item_table.end() ; ++i)
{
if( i->id == default_id )
request.item_table[0] = *i;
}
request.item_table.resize(1);
}
else
if( data.one_item_is_showed &&
request.item_table.size() == 1 &&
request.item_table[0].type == Item::file )
{
request.result = Request::show_item;
}
else
{
request.result = Request::show_dir;
}
return true;
}
return false;
}
// zrobic tak ze gdzie podajemy cala liste aby nie ladowac contentu z bazy danych do itemow
void Content::MakeGet()
{
MakeDirectoryStructure();
item.Clear();
// request.dir is set by MakeDirectoryStructure()
item.parent_id = request.dir;
if( MakeGetCheckDir() )
return;
// request was for an item or a standard function
request.result = StandardFunction( request.get_table[get_index] );
if( request.result != Request::err404 )
{
// request for a standard function
++get_index;
return;
}
if( request.get_table[get_index].empty() )
// we do not have an empty url
// err404 at the end
return;
// if we want to search by url then request.get_table[get_index] should not be empty
item.url = request.get_table[get_index++];
db.GetItems(request.item_table, item);
if( request.item_table.empty() )
// err404 at the end
return;
////
if( request.HasReadAccess(request.item_table[0]) )// !! tymczasowo dla 0 tylko
request.result = Request::show_item;
else
request.result = Request::err_per_denied;
////
if( get_index == request.get_table.size() )
{
return;
}
// there is a standard function at the end
request.result = StandardFunction( request.get_table[get_index++] );
}
void Content::MakeAddItem()
{
if( !request.session->puser )
{
// not logged
request.item.Clear();
}
else
{
request.item.user_id = request.session->puser->id;
}
}
void Content::MakeEditItem()
{
if( !request.item_table.empty() )
request.item = request.item_table[0];
else
{
log << log1 << "Content: request.item_table should not be empty" << logend;
request.result = Request::err404;
}
}
void Content::AppendCurDir(std::string & dir)
{
std::vector<Item>::size_type a;
for(a=0 ; a<request.cur_dir_table.size() ; ++a)
{
dir += request.cur_dir_table[a].url;
dir += '/';
}
}
void Content::MakeShowItemById()
{
if( get_index == request.get_table.size() )
{
request.result = Request::err404;
}
else
{
long id = atol( request.get_table[get_index++].c_str() );
db.GetItem(request.item_table, id);
if( request.item_table.empty() )
request.result = Request::err404;
else
{
RedirectTo(request.item_table[0]);
}
}
}
void Content::MakeDelItem()
{
if( request.item_table.empty() )
{
request.result = Request::err404;
return;
}
if( !request.session->puser || !request.session->puser->super_user )
// !! chwilowo tylko super user moze
{
request.result = Request::err_per_denied;
request.CopyFirstItem();
return;
}
if( get_index == request.get_table.size() )
{
request.CopyFirstItem();
request.session->item = request.item;
if( db.DelItem( request.item ) )
{
request.session->done = Done::deleted_item;
request.session->done_status = Error::ok;
log << log2 << "Content: deleted item: subject: " << request.item.subject << ", id: " << request.item.id << logend;
}
else
{
request.session->done = Done::deleted_item;
request.session->done_status = Error::db_no_item;
}
request.result = Request::redirect;
request.str = data.base_url;
AppendCurDir(request.str);
request.session->done_timer = 2;
}
else
{
if( StandardFunction( request.get_table[get_index++] ) == Request::confirm )
{
request.result = Request::del_item_confirm;
request.CopyFirstItem();
}
else
request.result = Request::err404;
}
}
void Content::MakeLogout()
{
if( request.session->is_logged )
{
log << log2 << "User id: " << request.session->user_id << " logged out" << logend;
request.session->is_logged = false;
request.session->user_id = 0;
request.session->puser = 0;
}
request.result = Request::redirect;
std::string path;
data.dirs.MakePath(request.dir, path);
request.str = data.base_url + path;
if( !request.item_table.empty() )
request.str += request.item_table[0].url;
request.session->done = Done::loggedout;
request.session->done_timer = 2;
}
void Content::MakeStandardFunction()
{
if( request.result == Request::add_item )
{
MakeAddItem();
}
else
if( request.result == Request::edit_item )
{
MakeEditItem();
}
else
if( request.result == Request::show_item_by_id )
{
MakeShowItemById();
}
else
if( request.result == Request::del_item )
{
MakeDelItem();
}
else
if( request.result == Request::logout )
{
MakeLogout();
}
}
void Content::MakePost()
{
if( request.IsPostVar("add_item") )
AddItem();
else
if( request.IsPostVar("edit_item") )
EditItem();
else
if( request.IsPostVar("logging") )
LogUser();
}
void Content::Make()
{
MakePost();
if( request.result == Request::redirect )
return;
MakeGet();
MakeStandardFunction();
templates.Generate();
//request.PrintGetTable();
//request.PrintEnv();
//request.PrintIn();
}
void Content::RedirectTo(const Item & item)
{
std::string path;
request.result = Request::redirect;
data.dirs.MakePath(item.parent_id, path);
request.str = data.base_url + path + item.url;
}