some ezc functions from templates/item.cpp moved to Item and ItemContent

methods HasAccess() HasReadAccess() and similar moved from System to Item and ItemContent
master
Tomasz Sowa 2 years ago
parent ebd791a256
commit ec94dff7d7

@ -118,6 +118,9 @@ App::App()
plugin.SetWinixRequest(&winix_request);
req.SetConfig(&config);
req.set_connector(&model_connector);
functions.set_dependency(&winix_request);
// functions.set_config(&config);
@ -337,6 +340,7 @@ bool App::Init()
model_connector.set_winix_users(&system.users);
model_connector.set_winix_groups(&system.groups);
model_connector.set_winix_session_logger(nullptr); // will be set for each request
model_connector.set_winix_session(nullptr); // will be set for each request
if( !TryToMakeDatabaseMigration() )
return false;
@ -564,8 +568,13 @@ void App::ProcessRequestThrow()
cur.mount = system.mounts.CalcCurMount();
cur.session = session_manager.PrepareSession();
model_connector.set_winix_session(cur.session);
functions.CheckFunctionAndSymlink(); // here a function can be changed
cur.session = session_manager.CheckIfFunctionRequireSession();
model_connector.set_winix_session(cur.session);
SetLocale();
if( cur.session->new_session )
@ -624,6 +633,9 @@ void App::ProcessRequest()
{
try
{
cur.request->set_connector(model_connector);
model_connector.set_winix_request(cur.request);
cur.request->RequestStarts();
system.load_avg.StartRequest();
log << log2 << config.log_delimiter << logend;
@ -680,7 +692,11 @@ void App::ClearAfterRequest()
system.mounts.pmount = cur.mount; // IMPROVE ME system.mounts.pmount will be removed
// send_data_buf doesn't have to be cleared and it is better to not clear it (optimizing)
cur.request->item.set_connector(nullptr);
model_connector.set_winix_request(nullptr);
model_connector.set_winix_session(nullptr);
model_connector.set_winix_session_logger(nullptr);
cur.request->item.set_connector(nullptr); // it is needed?
log << logendrequest;
}

@ -81,13 +81,13 @@ return var_iter;
}
DirContainer::Iterator DirContainer::Begin()
DirContainer::ConstIterator DirContainer::Begin() const
{
return table.begin();
}
DirContainer::Iterator DirContainer::End()
DirContainer::ConstIterator DirContainer::End() const
{
return table.end();
}
@ -255,6 +255,17 @@ return i->second;
}
DirContainer::ConstIterator DirContainer::FindId(long id) const
{
TableId::const_iterator i = table_id.find(id);
if( i == table_id.end() )
return table.end();
return i->second;
}
DirContainer::ParentIterator DirContainer::ParentBegin()
{

@ -52,6 +52,7 @@ class DirContainer : public WinixBase
public:
typedef std::list<Item> Table;
typedef Table::iterator Iterator;
typedef Table::const_iterator ConstIterator;
typedef Table::size_type SizeType;
typedef std::map<long, Iterator> TableId;
@ -66,8 +67,8 @@ public:
Iterator GetEtc();
Iterator GetVar();
Iterator Begin();
Iterator End();
ConstIterator Begin() const;
ConstIterator End() const;
SizeType Size();
bool Empty();
Iterator PushBack(const Item & item);
@ -75,6 +76,7 @@ public:
void Clear();
Iterator FindId(long id);
ConstIterator FindId(long id) const;
bool DelById(long id);

@ -456,9 +456,20 @@ Item * Dirs::GetDir(long id)
DirContainer::Iterator i = dir_tab.FindId(id);
if( i == dir_tab.End() )
return 0;
return nullptr;
return &(*i);
return &(*i);
}
const Item * Dirs::GetDir(long id) const
{
DirContainer::ConstIterator i = dir_tab.FindId(id);
if( i == dir_tab.End() )
return nullptr;
return &(*i);
}

@ -109,6 +109,8 @@ public:
Item * GetDir(long id);
Item * AddDir(const Item & item);
const Item * GetDir(long id) const;
void CheckRootDir();
Item * CreateVarDir();

@ -77,7 +77,7 @@ class WinixRequest;
class Plugin;
struct Session;
class Session;
// move me to a different file

@ -55,7 +55,10 @@ Request::Request()
void Request::fields()
{
field(L"", L"dirs", dir_tab);
field(L"dirs", dir_tab);
field(L"is_item", is_item);
field(L"current_dir", &Request::current_dir);
}
@ -362,6 +365,13 @@ const std::wstring & Request::ParamValue(const std::wstring & param_name)
void Request::current_dir(morm::ModelWrapper ** model_wrapper)
{
*model_wrapper = new morm::ModelWrapperModel(dir_tab.back());
}
} // namespace Winix

@ -64,8 +64,11 @@ class FunctionBase;
struct Request : public WinixModel
class Request : public WinixModel
{
public:
// how many input headers can be put to in_headers struct
static const size_t MAX_INPUT_HEADERS = 32;
@ -413,6 +416,12 @@ private:
void ClearOutputStreams();
void current_dir(morm::ModelWrapper ** model_wrapper);
MORM_MEMBER_FIELD(Request)
};
@ -456,6 +465,8 @@ void Request::AddCookie(const NameType & name, const ValueType & value, pt::Date
} // namespace Winix
#endif

@ -53,8 +53,9 @@ namespace Winix
struct Session
class Session
{
public:
Session();
Session(const Session & ses);

@ -606,69 +606,31 @@ return true;
}
// private
bool System::HasAccess(const Item & item, int mask)
{
if( !cur->session )
// session must be set
return false;
if( cur->session->puser && cur->session->puser->super_user )
// super user is allowed everything
return true;
if( cur->session->puser && item.item_content.user_id != -1 && cur->session->puser->id == item.item_content.user_id )
{
// the owner
return ((item.item_content.privileges >> 9) & mask) == mask;
}
if( cur->session->puser && item.item_content.group_id != -1 && cur->session->puser->IsMemberOf(item.item_content.group_id) )
{
// group
return ((item.item_content.privileges >> 6) & mask) == mask;
}
if( cur->session->puser )
{
// others -- others logged people
return ((item.item_content.privileges >> 3) & mask) == mask;
}
// guests -- not logged people
return (item.item_content.privileges & mask) == mask;
}
// DEPRACATED
bool System::HasReadAccess(const Item & item)
{
return HasAccess(item, 4);
return item.item_content.has_read_access();
}
// DEPRACATED
bool System::HasWriteAccess(const Item & item)
{
return HasAccess(item, 2);
return item.item_content.has_write_access();
}
// DEPRACATED
bool System::HasReadWriteAccess(const Item & item)
{
return HasAccess(item, 6); // r+w
return item.item_content.has_read_write_access();
}
// DEPRACATED
bool System::HasReadExecAccess(const Item & item)
{
if( cur->session && cur->session->puser && cur->session->puser->super_user )
{
// there must be at least one 'x' (for the root)
// !! CHECK ME: is it applicable to directories too?
return (item.item_content.privileges & 01111) != 0;
}
return HasAccess(item, 5); // r+x
return item.item_content.has_read_exec_access();
}

@ -239,7 +239,6 @@ private:
std::vector<Item*> root_follow_dir_tab;
Item temp_follow_item;
bool HasAccess(const Item & item, int mask);
int NewPrivileges(int creation_mask);
bool CreateNewFileSimpleFs(Item & item);

@ -183,25 +183,25 @@ void TextStream<StringType>::Reserve(size_t len)
template<class StringType>
TextStream<StringType>::iterator TextStream<StringType>::begin()
typename TextStream<StringType>::iterator TextStream<StringType>::begin()
{
return buffer.begin();
}
template<class StringType>
TextStream<StringType>::iterator TextStream<StringType>::end()
typename TextStream<StringType>::iterator TextStream<StringType>::end()
{
return buffer.end();
}
template<class StringType>
TextStream<StringType>::const_iterator TextStream<StringType>::begin() const
typename TextStream<StringType>::const_iterator TextStream<StringType>::begin() const
{
return buffer.begin();
}
template<class StringType>
TextStream<StringType>::const_iterator TextStream<StringType>::end() const
typename TextStream<StringType>::const_iterator TextStream<StringType>::end() const
{
return buffer.end();
}

@ -104,6 +104,7 @@ void ThreadManager::Add(BaseThread * pbase, const wchar_t * thread_name)
data.model_connector.set_winix_users(nullptr);
data.model_connector.set_winix_groups(nullptr);
data.model_connector.set_winix_session_logger(nullptr);
data.model_connector.set_winix_session(nullptr);

@ -67,7 +67,12 @@ void Cat::MakeGet()
}
cur->request->send_as_attachment = cur->request->IsParam(L"attachment");
// IMPROVEME this will be put by a generic method from winix
// if output is html
cur->request->models.Add(L"item", cur->request->item);
////////////////////////////////////////////////////////////
}

@ -101,11 +101,17 @@ void Ls::MakeGet()
cur->request->models.Add(L"items", item_tab);
cur->request->models.Add(L"child_dirs", dir_tab);
}
// IMPROVEME this will be put by a generic method from winix
// if output is html
cur->request->models.Add(L"request", cur->request);
// IMPROVEME this will be put by a generic method from winix
// if output is html
cur->request->models.Add(L"request", cur->request);
if( cur->request->is_item )
{
cur->request->models.Add(L"item", cur->request->item);
}
////////////////////////////////////////////////////////////
}

@ -1,5 +1,8 @@
<div class="winix"[if winix_function_param_is "ckeditor_browse"] style="padding: 1.5em;"[end]>
[# we can add a winix function called 'image_browser' or similar]
[# such a function can be used for ckeditor and for ordinary browsing]
[# !! IMPROVE ME: move this html code to a ckeditor template]
[if winix_function_param_is "ckeditor_browse"]
@ -9,9 +12,9 @@
<ul class="uk-breadcrumb">
[for request.dirs]
<li>
<a href="[doc_base_url][request.dirs.link]ls/ckeditor_browse/CKEditor:itemcontent/CKEditorFuncNum:[ls_ckeditor_funnum_browse]">
[if cmp request.dirs.url ""]
[# !! IMPROVE ME it would be better to have a flag of some kind to indicate that this is a root dir]
<a href="[request.dirs.link]/ls/ckeditor_browse/CKEditor:itemcontent/CKEditorFuncNum:[ls_ckeditor_funnum_browse]">
[if request.dirs.is_root_dir]
[# rename ls_root_dir_name to root_dir_name as it can be used by other functions]
{ls_root_dir_name}
[else]
[request.dirs.url]
@ -23,7 +26,7 @@
</div>
<div class="uk-flex uk-margin-medium">
<div class="uk-width-1-4">
<div class="" style="margin-right: 40px;"> [# workaround: margin from first item from child_dirs overflows here]
[if child_dirs]
<ul class="uk-list uk-list-disc uk-list-collapse">
@ -65,7 +68,7 @@
<h1>{ls_header}</h1>
[# !! improve me: we need a 'l' flag to a file too, now it's working for dirs only]
[if not item_is]
[if not request.is_item]
[if winix_function_param_is "l"]
@ -83,9 +86,9 @@
[for child_dirs]
<tr>
<td>d</td>
<td>[child_dirs_privileges]</td>
<td>[child_dirs_user]</td>
<td>[child_dirs_group]</td>
<td>[child_dirs.content.privileges_octal]</td>
<td>[child_dirs.content.user_name]</td>
<td>[child_dirs.content.group_name]</td>
<td>
[if child_dirs.is_parent_for_current_dir]
<a href="[doc_base_url][dir_parent_without_slash][if winix_function_param_is "dirls"]/ls/l/dirls[end]">../</a>
@ -98,11 +101,11 @@
[for items]
<tr>
<td>[if items_type_is_symlink]l[else][if items_has_static_file]s[else]-[end][end]</td>
<td>[items_privileges]</td>
<td>[items_user]</td>
<td>[items_group]</td>
<td><a href="[doc_base_url][dir][items.url]">[items.url]</a>[if items_type_is_symlink] -> [items_link_to][end]</td>
<td>[if items.type_is_symlink]l[else][if items.has_static_file]s[else]-[end][end]</td>
<td>[items.content.privileges_octal]</td>
<td>[items.content.user_name]</td>
<td>[items.content.group_name]</td>
<td><a href="[doc_base_url][dir][items.url]">[items.url]</a>[if items.type_is_symlink] -> [items.content.link_to][end]</td>
</tr>
[end]
</table>

@ -37,6 +37,8 @@
#include "finder.h"
#include "core/request.h"
#include "templates/templates.h"
#include "core/session.h"
namespace Winix
@ -58,21 +60,32 @@ void Item::fields()
int type_helper = static_cast<int>(type);
field(L"id", id, morm::FT::no_insertable | morm::FT::no_updatable | morm::FT::primary_key);
field(L"parent_id", parent_id);
field(L"type", type_helper);
field(L"url", url);
field(L"subject", subject);
field(L"template", html_template);
field(L"sort_index", sort_index);
field(L"id", id, morm::FT::no_insertable | morm::FT::no_updatable | morm::FT::primary_key);
field(L"parent_id", parent_id);
field(L"type", type_helper);
field(L"url", url);
field(L"subject", subject);
field(L"template", html_template);
field(L"sort_index", sort_index);
field(L"content_id", L"content", item_content, morm::FT::foreign_key);
field(L"is", &Item::is);
field(L"dir_link", &Item::dir_link);
field(L"link", &Item::link);
field(L"dir_link", &Item::dir_link);
field(L"link", &Item::link);
field(L"is_parent_for_current_dir", &Item::is_parent_for_current_dir);
field(L"is_current_dir", &Item::is_current_dir);
field(L"is_root", &Item::is_root);
field(L"is_current_dir", &Item::is_current_dir);
field(L"is_root_dir", &Item::is_root_dir);
field(L"type_is_symlink", &Item::type_is_symlink);
field(L"type_is_file", &Item::type_is_file);
field(L"type_is_dir", &Item::type_is_dir);
field(L"type_is_none", &Item::type_is_none);
field(L"url_is", &Item::url_is);
field(L"can_be_removed", &Item::can_be_removed);
field(L"has_read_access", &Item::has_read_access);
field(L"has_write_access", &Item::has_write_access);
// may we should add a method setTypeFromInt(int t)?
@ -156,8 +169,6 @@ bool Item::update(morm::ModelData * model_data, bool update_whole_tree)
}
void Item::Clear()
{
id = -1;
@ -171,6 +182,244 @@ void Item::Clear()
}
bool Item::do_migration(int & current_table_version)
{
bool ok = true;
ok = ok && morm::Model::do_migration(current_table_version, 1, this, &Item::do_migration_to_1);
ok = ok && morm::Model::do_migration(current_table_version, 2, this, &Item::do_migration_to_2);
ok = ok && morm::Model::do_migration(current_table_version, 3, this, &Item::do_migration_to_3);
ok = ok && morm::Model::do_migration(current_table_version, 4, this, &Item::do_migration_to_4);
return ok;
}
bool Item::do_migration_to_1()
{
const char * str = R"sql(
CREATE TABLE core.item (
user_id integer,
group_id integer,
privileges integer,
date_creation timestamp without time zone,
date_modification timestamp without time zone,
parent_id bigint,
type smallint,
id integer NOT NULL,
url character varying(255),
content_id bigint,
subject character varying(255),
guest_name character varying(20),
modification_user_id integer,
template character varying(255),
link_to character varying(2048),
link_redirect smallint,
sort_index integer,
meta text,
ameta text
);
)sql";
db_query(str);
return true; // IMPROVEME remove me in the future: this is only for a moment until we do migration on all our sites
}
/*
* directories didn't have an ItemContent object, so now we create such objects
*/
bool Item::do_migration_to_2()
{
morm::Finder<Item> finder(model_connector);
std::list<Item> list = finder.
select().
where().
eq(L"type", static_cast<int>(Item::dir)).
eq(L"content_id", -1).
get_list();
pt::Log * log = model_connector->get_logger();
for(Item & item : list)
{
if( log )
{
(*log) << "Item: adding a content row corresponding to item id: " << item.id << ", type: " << (int)item.type << ", url: " << item.url
<< ", subject: " << item.subject << pt::Log::logend;
}
item.item_content.set_save_mode(morm::Model::DO_INSERT_ON_SAVE);
if( !item.save() )
return false;
}
return true;
}
bool Item::do_migration_to_3()
{
const char * str[] = {
"update core.content set user_id = (select user_id from core.item where item.content_id = content.id limit 1);",
"update core.content set group_id = (select group_id from core.item where item.content_id = content.id limit 1);",
"update core.content set guest_name = (select guest_name from core.item where item.content_id = content.id limit 1);",
"update core.content set modification_user_id = (select modification_user_id from core.item where item.content_id = content.id limit 1);",
"update core.content set privileges = (select privileges from core.item where item.content_id = content.id limit 1);",
"update core.content set date_creation = (select date_creation from core.item where item.content_id = content.id limit 1);",
"update core.content set date_modification = (select date_modification from core.item where item.content_id = content.id limit 1);",
"update core.content set link_to = (select link_to from core.item where item.content_id = content.id limit 1);",
"update core.content set link_redirect = (select link_redirect from core.item where item.content_id = content.id limit 1);",
"update core.content set meta = (select meta from core.item where item.content_id = content.id limit 1);",
"update core.content set meta_admin = (select ameta from core.item where item.content_id = content.id limit 1);",
};
size_t len = sizeof(str) / sizeof(const char*);
for(size_t i=0 ; i < len ; ++i)
{
if( !db_query(str[i]) )
{
return false;
}
}
return true;
}
bool Item::do_migration_to_4()
{
const char * str = R"sql(
alter table core.item
drop column user_id,
drop column group_id,
drop column guest_name,
drop column modification_user_id,
drop column privileges,
drop column date_creation,
drop column date_modification,
drop column link_to,
drop column link_redirect,
drop column meta,
drop column ameta;
)sql";
return db_query(str);
}
bool Item::can_remove_child(const User * current_user, long child_user_id) const
{
bool res = false;
if( type == Type::dir )
{
if( current_user && current_user->super_user )
{
res = true;
}
else
{
res = item_content.has_write_access(current_user);
if( res && item_content.is_sticky_bit_set() )
{
// IMPROVEME what about if child_user_id is -1 (guest)
res = (item_content.user_id == child_user_id);
}
}
}
return res;
}
bool Item::can_be_removed(const User * current_user) const
{
bool res = false;
const Dirs * dirs = get_dirs();
if( dirs && parent_id != -1 )
{
const Item * parent_dir = dirs->GetDir(parent_id);
if( parent_dir )
{
res = parent_dir->can_remove_child(current_user, id);
}
}
return res;
}
bool Item::can_remove_child(long child_user_id) const
{
return can_remove_child(get_current_user(), child_user_id);
}
bool Item::can_be_removed() const
{
return can_be_removed(get_current_user());
}
bool Item::has_read_access()
{
return item_content.has_read_access();
}
bool Item::has_write_access()
{
return item_content.has_write_access();
}
bool Item::type_is_symlink() const
{
return (type == Type::symlink);
}
bool Item::type_is_file() const
{
return (type == Type::file);
}
bool Item::type_is_dir() const
{
return (type == Type::dir);
}
bool Item::type_is_none() const
{
return (type == Type::none);
}
bool Item::is_root_dir() const
{
return (type == Type::dir && parent_id == -1);
}
CalcItemsHelper Item::calc_items_by_url(long parent_id, const std::wstring & url)
{
morm::Finder<CalcItemsHelper> finder(model_connector);
@ -241,7 +490,7 @@ void Item::propagate_connector()
// IMPROVEME move me to a better place
void Item::print_dir(Ezc::FunInfo<HtmlTextStream> & env)
void Item::print_dir(EzcEnv & env)
{
Request * req = get_request();
@ -254,7 +503,7 @@ void Item::print_dir(Ezc::FunInfo<HtmlTextStream> & env)
// IMPROVEME move me to a better place
void Item::print_dir_without_slash(Ezc::FunInfo<HtmlTextStream> & env)
void Item::print_dir_without_slash(EzcEnv & env)
{
Request * req = get_request();
@ -274,18 +523,7 @@ void Item::print_dir_without_slash(Ezc::FunInfo<HtmlTextStream> & env)
void Item::is(Ezc::FunInfo<HtmlTextStream> & env)
{
Request * req = get_request();
if( req )
{
env.res = req->is_item;
}
}
void Item::dir_link(Ezc::FunInfo<HtmlTextStream> & env)
void Item::dir_link(EzcEnv & env)
{
Dirs * dirs = get_dirs();
std::vector<Item*> dir_tab;
@ -300,7 +538,7 @@ void Item::dir_link(Ezc::FunInfo<HtmlTextStream> & env)
}
void Item::link(Ezc::FunInfo<HtmlTextStream> & env)
void Item::link(EzcEnv & env)
{
Config * config = get_config();
Request * req = get_request();
@ -328,176 +566,46 @@ void Item::link(Ezc::FunInfo<HtmlTextStream> & env)
}
void Item::is_parent_for_current_dir(Ezc::FunInfo<HtmlTextStream> & env)
bool Item::is_parent_for_current_dir() const
{
Request * req = get_request();
bool res = false;
const Request * req = get_request();
if( req )
{
if( req->dir_tab.size() > 1 )
{
env.res = (id == req->dir_tab[req->dir_tab.size() - 2]->id);
res = (id == req->dir_tab[req->dir_tab.size() - 2]->id);
}
}
}
void Item::is_current_dir(Ezc::FunInfo<HtmlTextStream> & env)
{
Request * req = get_request();
if( req )
{
env.res = (id == req->dir_tab.back()->id);
}
return res;
}
// rename to is_root_dir
void Item::is_root(Ezc::FunInfo<HtmlTextStream> & env)
bool Item::is_current_dir() const
{
Request * req = get_request();
bool res = false;
const Request * req = get_request();
if( req )
{
// add a test whether this is a directory (not a file or a symlink)
env.res = (parent_id == -1);
res = (id == req->dir_tab.back()->id);
}
}
bool Item::do_migration(int & current_table_version)
{
bool ok = true;
ok = ok && morm::Model::do_migration(current_table_version, 1, this, &Item::do_migration_to_1);
ok = ok && morm::Model::do_migration(current_table_version, 2, this, &Item::do_migration_to_2);
ok = ok && morm::Model::do_migration(current_table_version, 3, this, &Item::do_migration_to_3);
ok = ok && morm::Model::do_migration(current_table_version, 4, this, &Item::do_migration_to_4);
return ok;
}
bool Item::do_migration_to_1()
{
const char * str = R"sql(
CREATE TABLE core.item (
user_id integer,
group_id integer,
privileges integer,
date_creation timestamp without time zone,
date_modification timestamp without time zone,
parent_id bigint,
type smallint,
id integer NOT NULL,
url character varying(255),
content_id bigint,
subject character varying(255),
guest_name character varying(20),
modification_user_id integer,
template character varying(255),
link_to character varying(2048),
link_redirect smallint,
sort_index integer,
meta text,
ameta text
);
)sql";
db_query(str);
return true; // IMPROVEME remove me in the future: this is only for a moment until we do migration on all our sites
return res;
}
/*
* directories didn't have an ItemContent object, so now we create such objects
*/
bool Item::do_migration_to_2()
{
morm::Finder<Item> finder(model_connector);
std::list<Item> list = finder.
select().
where().
eq(L"type", static_cast<int>(Item::dir)).
eq(L"content_id", -1).
get_list();
pt::Log * log = model_connector->get_logger();
for(Item & item : list)
{
if( log )
{
(*log) << "Item: adding a content row corresponding to item id: " << item.id << ", type: " << (int)item.type << ", url: " << item.url
<< ", subject: " << item.subject << pt::Log::logend;
}
item.item_content.set_save_mode(morm::Model::DO_INSERT_ON_SAVE);
if( !item.save() )
return false;
}
return true;
}
bool Item::do_migration_to_3()
void Item::url_is(EzcEnv & env)
{
const char * str[] = {
"update core.content set user_id = (select user_id from core.item where item.content_id = content.id limit 1);",
"update core.content set group_id = (select group_id from core.item where item.content_id = content.id limit 1);",
"update core.content set guest_name = (select guest_name from core.item where item.content_id = content.id limit 1);",
"update core.content set modification_user_id = (select modification_user_id from core.item where item.content_id = content.id limit 1);",
"update core.content set privileges = (select privileges from core.item where item.content_id = content.id limit 1);",
"update core.content set date_creation = (select date_creation from core.item where item.content_id = content.id limit 1);",
"update core.content set date_modification = (select date_modification from core.item where item.content_id = content.id limit 1);",
"update core.content set link_to = (select link_to from core.item where item.content_id = content.id limit 1);",
"update core.content set link_redirect = (select link_redirect from core.item where item.content_id = content.id limit 1);",
"update core.content set meta = (select meta from core.item where item.content_id = content.id limit 1);",
"update core.content set meta_admin = (select ameta from core.item where item.content_id = content.id limit 1);",
};
size_t len = sizeof(str) / sizeof(const char*);
for(size_t i=0 ; i < len ; ++i)
{
if( !db_query(str[i]) )
{
return false;
}
}
return true;
env.res = (url == env.par);
}
bool Item::do_migration_to_4()
{
const char * str = R"sql(
alter table core.item
drop column user_id,
drop column group_id,
drop column guest_name,
drop column modification_user_id,
drop column privileges,
drop column date_creation,
drop column date_modification,
drop column link_to,
drop column link_redirect,
drop column meta,
drop column ameta;
)sql";
return db_query(str);
}
} // namespace Winix

@ -46,6 +46,7 @@
#include "funinfo.h"
#include "templates/htmltextstream.h"
#include "templates/misc.h"
@ -183,16 +184,23 @@ public:
void propagate_connector();
bool can_remove_child(const User * current_user, long child_user_id) const;
bool can_be_removed(const User * current_user) const;
bool can_remove_child(long child_user_id) const;
bool can_be_removed() const;
void print_dir(Ezc::FunInfo<HtmlTextStream> & env);
void print_dir_without_slash(Ezc::FunInfo<HtmlTextStream> & env);
bool has_read_access();
bool has_write_access();
bool type_is_symlink() const;
bool type_is_file() const;
bool type_is_dir() const;
bool type_is_none() const;
bool is_root_dir() const;
bool is_parent_for_current_dir() const;
bool is_current_dir() const;
void is(Ezc::FunInfo<HtmlTextStream> & env);
void dir_link(Ezc::FunInfo<HtmlTextStream> & env);
void link(Ezc::FunInfo<HtmlTextStream> & env);
void is_parent_for_current_dir(Ezc::FunInfo<HtmlTextStream> & env);
void is_current_dir(Ezc::FunInfo<HtmlTextStream> & env);
void is_root(Ezc::FunInfo<HtmlTextStream> & env);
protected:
@ -204,7 +212,17 @@ protected:
bool do_migration_to_3();
bool do_migration_to_4();
void print_dir(EzcEnv & env);
void print_dir_without_slash(EzcEnv & env);
void dir_link(EzcEnv & env);
void link(EzcEnv & env);
void url_is(EzcEnv & env);
MORM_MEMBER_FIELD(Item)
};

@ -37,6 +37,9 @@
#include "core/misc.h"
#include "templates/misc.h"
#include "core/bbcodeparser.h"
#include "core/request.h"
#include "core/users.h"
#include "core/groups.h"
namespace Winix
@ -83,7 +86,23 @@ void ItemContent::fields()
field(L"meta_admin", meta_admin);
field(L"print_content", &ItemContent::print_content);
field(L"has_static_file", &ItemContent::has_static_file);
field(L"privileges_octal", &ItemContent::privileges_octal);
field(L"user_name", &ItemContent::user_name);
field(L"group_name", &ItemContent::group_name);
field(L"type_is", &ItemContent::type_is);
field(L"is_empty", &ItemContent::is_empty);
field(L"file_type_is_none", &ItemContent::file_type_is_none);
field(L"file_type_is_image", &ItemContent::file_type_is_image);
field(L"file_type_is_video", &ItemContent::file_type_is_video);
field(L"file_type_is_sound", &ItemContent::file_type_is_sound);
field(L"has_thumb", &ItemContent::has_thumb);
// IMPROVEME prepare a setter functions which tests whether content_raw_type_helper and content_parsed_type_helper are correct values
content_raw_type = static_cast<ContentType>(content_raw_type_helper);
content_parsed_type = static_cast<ContentType>(content_parsed_type_helper);
}
@ -153,66 +172,6 @@ void ItemContent::Clear()
}
/*
* we're using the HtmlFilter only for those contents
*
*/
bool ItemContent::CanContentBeHtmlFiltered(ItemContent::ContentType ct)
{
return ct == ct_text || ct == ct_formatted_text || ct == ct_html || ct == ct_bbcode;
}
bool ItemContent::CanContentBeHtmlFiltered()
{
return CanContentBeHtmlFiltered(content_raw_type);
}
void ItemContent::print_content(HtmlTextStream & out, const std::wstring & content, ItemContent::ContentType content_type, bool is_html_filter_on)
{
using TemplatesFunctions::R;
if( is_html_filter_on && !ItemContent::CanContentBeHtmlFiltered(content_type) )
out << R("<nofilter>");
if( content_type == ItemContent::ct_text )
{
out << content;
}
else
if( content_type == ItemContent::ct_formatted_text )
{
TemplatesFunctions::HtmlEscapeFormTxt(out, content);
}
else
if( content_type == ItemContent::ct_bbcode )
{
static std::wstring out_temp;
out_temp.clear();
out_temp.reserve(content.size()*2);
BBCODEParser bbcode_parser; // IMPROVE ME move me to a better place
bbcode_parser.Filter(content.c_str(), out_temp);
out << R(out_temp);
}
else
{
// ct_html, ct_other
out << R(content);
}
if( is_html_filter_on && !ItemContent::CanContentBeHtmlFiltered(content_type) )
out << R("</nofilter>");
}
void ItemContent::print_content(Ezc::FunInfo<HtmlTextStream> & env)
{
print_content(env.out, content_raw, content_raw_type, true); // IMPROVE ME get the 'true' from the config (config->html_filter)
}
bool ItemContent::do_migration(int & current_table_version)
{
@ -305,6 +264,268 @@ bool ItemContent::do_migration_to_3()
}
bool ItemContent::has_access(const User * current_user, int mask) const
{
if( current_user )
{
if( current_user->super_user )
{
// super user is allowed everything
return true;
}
if( user_id != -1 && current_user->id == user_id )
{
// the owner
return ((privileges >> 9) & mask) == mask;
}
if( group_id != -1 && current_user->IsMemberOf(group_id) )
{
// group
return ((privileges >> 6) & mask) == mask;
}
// others -- others logged users
return ((privileges >> 3) & mask) == mask;
}
// guests -- not logged users
return (privileges & mask) == mask;
}
bool ItemContent::has_read_access(const User * current_user) const
{
return has_access(current_user, 4); // r
}
bool ItemContent::has_write_access(const User * current_user) const
{
return has_access(current_user, 2); // w
}
bool ItemContent::has_read_write_access(const User * current_user) const
{
return has_access(current_user, 6); // r+w
}
bool ItemContent::has_read_exec_access(const User * current_user) const
{
if( current_user && current_user->super_user )
{
// there must be at least one 'x' (for the root)
// !! CHECK ME: is it applicable to directories too?
return (privileges & 01111) != 0;
}
return has_access(current_user, 5); // r+x
}
bool ItemContent::has_read_access() const
{
return has_read_access(get_current_user());
}
bool ItemContent::has_write_access() const
{
return has_write_access(get_current_user());
}
bool ItemContent::has_read_write_access() const
{
return has_read_write_access(get_current_user());
}
bool ItemContent::has_read_exec_access() const
{
return has_read_exec_access(get_current_user());
}
bool ItemContent::is_sticky_bit_set() const
{
int mask = 010000;
return (privileges & mask) == mask;
}
/*
* we're using the HtmlFilter only for those contents
*
*/
bool ItemContent::CanContentBeHtmlFiltered(ItemContent::ContentType ct)
{
return ct == ct_text || ct == ct_formatted_text || ct == ct_html || ct == ct_bbcode;
}
bool ItemContent::CanContentBeHtmlFiltered()
{
return CanContentBeHtmlFiltered(content_raw_type);
}
void ItemContent::print_content(HtmlTextStream & out, const std::wstring & content, ItemContent::ContentType content_type, bool is_html_filter_on)
{
using TemplatesFunctions::R;
if( is_html_filter_on && !ItemContent::CanContentBeHtmlFiltered(content_type) )
out << R("<nofilter>");
if( content_type == ItemContent::ct_text )
{
out << content;
}
else
if( content_type == ItemContent::ct_formatted_text )
{
TemplatesFunctions::HtmlEscapeFormTxt(out, content);
}
else
if( content_type == ItemContent::ct_bbcode )
{
static std::wstring out_temp;
out_temp.clear();
out_temp.reserve(content.size()*2);
BBCODEParser bbcode_parser; // IMPROVE ME move me to a better place
bbcode_parser.Filter(content.c_str(), out_temp);
out << R(out_temp);
}
else
{
// ct_html, ct_other
out << R(content);
}
if( is_html_filter_on && !ItemContent::CanContentBeHtmlFiltered(content_type) )
out << R("</nofilter>");
}
void ItemContent::print_content(EzcEnv & env)
{
print_content(env.out, content_raw, content_raw_type, true); // IMPROVE ME get the 'true' from the config (config->html_filter)
}
void ItemContent::has_static_file(EzcEnv & env)
{
env.res = file_type != WINIX_ITEM_FILETYPE_NONE && !file_path.empty();
}
void ItemContent::privileges_octal(EzcEnv & env)
{
env.out << Toa(privileges, 8);
}
void ItemContent::user_name(EzcEnv & env)
{
Users * users = get_users();
if( users )
{
User * puser = users->GetUser(user_id);
TemplatesFunctions::print_user_name(env, puser, guest_name);
}
}
void ItemContent::group_name(EzcEnv & env)
{
Groups * groups = get_groups();
if( groups <