added: forum

added: mount params can have arguments (in parentheses)
added: mount params: withheader, withinfo, restrictcreatethread, only_root_can_remove,
       can_use_emacs_on(level), can_use_mkdir_on(level), 
added: table Item has 'subject' column now
removed: column 'subject' from table Content




git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@505 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
2009-06-05 20:29:06 +00:00
parent 3d001e7458
commit 1eb42446f8
38 changed files with 1357 additions and 369 deletions

View File

@@ -30,12 +30,12 @@ lastcontainer.o: lastcontainer.h log.h
log.o: log.h
main.o: requestcontroller.h ../content/content.h ../core/item.h
main.o: ../templates/templates.h ../../ezc/src/ezc.h
main.o: ../templates/patterncacher.h ../app/templates.h sessionmanager.h
main.o: sessioncontainer.h session.h done.h item.h error.h log.h user.h
main.o: functionparser.h requesttypes.h ../app/content.h data.h dirs.h
main.o: dircontainer.h users.h ugcontainer.h groups.h group.h functions.h
main.o: function.h lastcontainer.h mounts.h mount.h request.h thread.h db.h
main.o: config.h ../confparser/confparser.h
main.o: ../templates/patterncacher.h ../app/templates.h ../core/thread.h
main.o: sessionmanager.h sessioncontainer.h session.h done.h item.h error.h
main.o: log.h user.h functionparser.h requesttypes.h ../app/content.h data.h
main.o: dirs.h dircontainer.h users.h ugcontainer.h groups.h group.h
main.o: functions.h function.h lastcontainer.h mounts.h mount.h request.h
main.o: thread.h db.h config.h ../confparser/confparser.h
misc.o: misc.h item.h log.h
mount.o: mount.h
mountparser.o: mountparser.h mount.h item.h error.h log.h data.h dirs.h
@@ -47,17 +47,19 @@ mounts.o: lastcontainer.h request.h requesttypes.h session.h done.h error.h
mounts.o: thread.h mountparser.h
request.o: request.h requesttypes.h session.h done.h item.h error.h log.h
request.o: user.h function.h thread.h getparser.h httpsimpleparser.h
request.o: postparser.h cookieparser.h
request.o: postparser.h cookieparser.h data.h dirs.h dircontainer.h users.h
request.o: ugcontainer.h groups.h group.h functions.h lastcontainer.h
request.o: mounts.h mount.h
requestcontroller.o: requestcontroller.h ../content/content.h ../core/item.h
requestcontroller.o: ../templates/templates.h ../../ezc/src/ezc.h
requestcontroller.o: ../templates/patterncacher.h ../app/templates.h
requestcontroller.o: sessionmanager.h sessioncontainer.h session.h done.h
requestcontroller.o: item.h error.h log.h user.h functionparser.h
requestcontroller.o: requesttypes.h ../app/content.h data.h dirs.h
requestcontroller.o: dircontainer.h users.h ugcontainer.h groups.h group.h
requestcontroller.o: functions.h function.h lastcontainer.h mounts.h mount.h
requestcontroller.o: request.h thread.h postparser.h httpsimpleparser.h
requestcontroller.o: cookieparser.h
requestcontroller.o: ../core/thread.h sessionmanager.h sessioncontainer.h
requestcontroller.o: session.h done.h item.h error.h log.h user.h
requestcontroller.o: functionparser.h requesttypes.h ../app/content.h data.h
requestcontroller.o: dirs.h dircontainer.h users.h ugcontainer.h groups.h
requestcontroller.o: group.h functions.h function.h lastcontainer.h mounts.h
requestcontroller.o: mount.h request.h thread.h postparser.h
requestcontroller.o: httpsimpleparser.h cookieparser.h
session.o: session.h done.h item.h error.h log.h user.h
sessioncontainer.o: sessioncontainer.h session.h done.h item.h error.h log.h
sessioncontainer.o: user.h data.h dirs.h dircontainer.h users.h ugcontainer.h

View File

@@ -361,6 +361,7 @@ void Db::CheckAllUrlSubject()
{
AssertConnection();
std::ostringstream query, query2;
// !! subject zostal wrzucony do tabeli item
query << "select item.id, subject from core.item left join core.content on item.content_id = content.id where url is null or url=''";
r = AssertQuery(query.str());
@@ -419,16 +420,17 @@ Error Db::AddItemIntoItem(Item & item)
{
AssertConnection();
std::ostringstream query;
query << "insert into core.item (user_id, group_id, privileges, date_creation, date_modification, type, parent_id, content_id, default_item, url) values (";
query << '\'' << item.user_id << "', ";
query << '\'' << item.group_id << "', ";
query << '\'' << item.privileges << "', ";
query << '\'' << ConvertTime(item.date_creation) << "', ";
query << "insert into core.item (user_id, group_id, privileges, date_creation, date_modification, type, parent_id, content_id, default_item, subject, url) values (";
query << '\'' << item.user_id << "', ";
query << '\'' << item.group_id << "', ";
query << '\'' << item.privileges << "', ";
query << '\'' << ConvertTime(item.date_creation) << "', ";
query << '\'' << ConvertTime(item.date_modification) << "', ";
query << '\'' << static_cast<int>(item.type) << "', ";
query << '\'' << item.parent_id << "', ";
query << '\'' << item.content_id << "', ";
query << '\'' << item.default_item << "', ";
query << '\'' << static_cast<int>(item.type) << "', ";
query << '\'' << item.parent_id << "', ";
query << '\'' << item.content_id << "', ";
query << '\'' << item.default_item << "', ";
query << '\'' << Escape(item.subject) << "', ";
url_without_id = AddItemCreateUrlSubject(item);
@@ -468,10 +470,9 @@ Error Db::AddItemIntoContent(Item & item)
{
AssertConnection();
std::ostringstream query;
query << "insert into core.content (subject, content, content_type) values (";
query << '\'' << Escape(item.subject) << "', ";
query << '\'' << Escape(item.content) << "', ";
query << '\'' << item.content_type << "');";
query << "insert into core.content (content, content_type) values (";
query << '\'' << Escape(item.content) << "', ";
query << '\'' << item.content_type << "');";
r = AssertQuery(query.str());
AssertResultStatus(r, PGRES_COMMAND_OK);
@@ -511,8 +512,7 @@ return result;
// !! with_subject zamienic na with_url
Error Db::EditItemInItem(Item & item, bool with_subject)
Error Db::EditItemInItem(Item & item, bool with_url)
{
PGresult * r = 0;
Error result = Error::ok;
@@ -522,22 +522,23 @@ Error Db::EditItemInItem(Item & item, bool with_subject)
{
AssertConnection();
std::ostringstream query;
query << "update core.item set (user_id, group_id, privileges, date_creation, date_modification, type, default_item, parent_id";
query << "update core.item set (user_id, group_id, privileges, date_creation, date_modification, type, default_item, parent_id, subject";
if( with_subject )
if( with_url )
query << ", url";
query << ") = (";
query << '\'' << item.user_id << "', ";
query << '\'' << item.group_id << "', ";
query << '\'' << item.privileges << "', ";
query << '\'' << ConvertTime(item.date_creation) << "', ";
query << '\'' << item.user_id << "', ";
query << '\'' << item.group_id << "', ";
query << '\'' << item.privileges << "', ";
query << '\'' << ConvertTime(item.date_creation) << "', ";
query << '\'' << ConvertTime(item.date_modification) << "', ";
query << '\'' << static_cast<int>(item.type) << "', ";
query << '\'' << item.default_item << "', ";
query << '\'' << item.parent_id << "' ";
query << '\'' << static_cast<int>(item.type) << "', ";
query << '\'' << item.default_item << "', ";
query << '\'' << item.parent_id << "', ";
query << '\'' << Escape(item.subject) << "' ";
if( with_subject )
if( with_url )
{
url_without_id = AddItemCreateUrlSubject(item);
@@ -552,7 +553,7 @@ Error Db::EditItemInItem(Item & item, bool with_subject)
r = AssertQuery(query.str());
AssertResultStatus(r, PGRES_COMMAND_OK);
if( with_subject && !url_without_id )
if( with_url && !url_without_id )
ToString(item.url, item.id);
}
catch(const Error & e)
@@ -576,9 +577,8 @@ Error Db::EditItemInContent(Item & item)
{
AssertConnection();
std::ostringstream query;
query << "update core.content set (subject, content, content_type) = (";
query << "update core.content set (content, content_type) = (";
query << '\'' << Escape(item.subject) << "', ";
query << '\'' << Escape(item.content) << "', ";
query << '\'' << item.content_type << "' ";
@@ -664,9 +664,8 @@ return result;
// item.id must be set
// !! with_subject zamienic na with_url
// !! moze nazwa poprostu EditItem (nie trzeba tego ById) ? (sprawdzic czy nie koliduje z inna nazwa)
Error Db::EditItemById(Item & item, bool with_subject)
Error Db::EditItemById(Item & item, bool with_url)
{
Error result = Error::ok;
@@ -681,7 +680,7 @@ Error Db::EditItemById(Item & item, bool with_subject)
result = EditItemInContent(item);
if( result == Error::ok )
result = EditItemInItem(item, with_subject);
result = EditItemInItem(item, with_url);
}
return result;
@@ -691,7 +690,7 @@ return result;
// item.url and item.parent_id must be set
// doesn't work with directiories
Error Db::EditItemByUrl(Item & item, bool with_subject)
Error Db::EditItemByUrl(Item & item, bool with_url)
{
Error result = EditItemGetId(item);
@@ -700,7 +699,7 @@ Error Db::EditItemByUrl(Item & item, bool with_subject)
result = EditItemInContent(item);
if( result == Error::ok )
result = EditItemInItem(item, with_subject);
result = EditItemInItem(item, with_url);
}
return result;
@@ -747,33 +746,48 @@ return result;
PGresult * Db::GetItemsQuery(Item & item_ref, bool asc)
PGresult * Db::GetItemsQuery(long parent_id, Item::Type type, bool with_subject, bool with_content, bool sort_asc)
{
std::ostringstream query;
query << "select * from core.item left join core.content on item.content_id = content.id where type!='0' and parent_id='" << item_ref.parent_id << "'";
query << "select item.id, user_id, group_id, privileges, date_creation, date_modification, url, type, parent_id, content_id, default_item";
if( item_ref.id != -1 )
query << " and item.id='" << item_ref.id << "'";
if( type != Item::dir )
{
if( with_subject )
query << ", subject";
if( with_content )
query << ", content, content_type";
}
if( !item_ref.url.empty() )
query << " and url='" << Escape(item_ref.url) << "'";
query << " from core.item";
if( type != Item::dir && with_content )
query << " left join core.content on item.content_id = content.id";
query << " where parent_id='" << parent_id << "'";
query << " order by item.date_modification";
if( type == Item::dir )
query << " and type='0'";
if( type == Item::file )
query << " and type='1'";
if( asc )
query << " order by item.date_creation";
if( sort_asc )
query << " asc";
else
query << " desc";
query << ';';
return AssertQuery(query.str());
}
void Db::GetItems(std::vector<Item> & item_table, Item & item_ref, bool asc)
void Db::GetItems(std::vector<Item> & item_table, long parent_id, Item::Type type, bool with_subject, bool with_content, bool sort_asc)
{
item_table.clear();
PGresult * r = 0;
@@ -782,7 +796,7 @@ void Db::GetItems(std::vector<Item> & item_table, Item & item_ref, bool asc)
{
AssertConnection();
r = GetItemsQuery(item_ref, asc);
r = GetItemsQuery(parent_id, type, with_subject, with_content, sort_asc);
AssertResultStatus(r, PGRES_TUPLES_OK);
Item item;
@@ -930,7 +944,8 @@ long Db::GetDirId(long parent_id, const std::string & url)
// !! w tej metodzie odczytujemy tylko uprawnienia?
// bo w tej chwili jest caly item odczytywany
bool Db::GetPriv(Item & item, long id)
{
bool result = false;
@@ -1380,7 +1395,7 @@ Error Db::GetThreadByDirId(long dir_id, Thread & thread)
AssertConnection();
std::ostringstream query;
query << "select id, dir_id, subject, closed from core.thread where thread.dir_id = " << dir_id << ";";
query << "select thread.id, thread.parent_id, thread.dir_id, thread.closed, thread.items, thread.last_item, item.date_modification, item.user_id from core.thread left join core.item on thread.last_item = item.id where thread.dir_id = '" << dir_id << "';";
r = AssertQuery( query.str() );
AssertResultStatus(r, PGRES_TUPLES_OK);
@@ -1391,20 +1406,81 @@ Error Db::GetThreadByDirId(long dir_id, Thread & thread)
log << log1 << "Db: there is more than one thread with dir_id: " << dir_id << logend;
else
if( rows == 0 )
{
log << log1 << "Db: there is no a thread with dir_id: " << dir_id << logend;
throw Error(Error::no_thread);
}
int cid = AssertColumn(r, "id");
int cdir_id = AssertColumn(r, "dir_id");
int csubject = AssertColumn(r, "subject");
int cclosed = AssertColumn(r, "closed");
int cid = AssertColumn(r, "id");
int cparent_id = AssertColumn(r, "parent_id");
int cdir_id = AssertColumn(r, "dir_id");
int cclosed = AssertColumn(r, "closed");
int citems = AssertColumn(r, "items");
int clast_item = AssertColumn(r, "last_item");
int cdate_modification = PQfnumber(r, "date_modification");
int cuser_id = PQfnumber(r, "user_id");
thread.id = atol( AssertValue(r, 0, cid) );
thread.parent_id = atol( AssertValue(r, 0, cparent_id) );
thread.dir_id = atol( AssertValue(r, 0, cdir_id) );
thread.closed = atol( AssertValue(r, 0, cclosed) ) == 0 ? false : true;
thread.items = atol( AssertValue(r, 0, citems) );
thread.last_item.id = atol( AssertValue(r, 0, clast_item) );
thread.last_item.date_modification = ConvertTime( Db::AssertValue(r, 0, cdate_modification) );
thread.last_item.user_id = atol( Db::AssertValue(r, 0, cuser_id) );
}
catch(const Error & e)
{
status = e;
}
ClearResult(r);
thread.id = atol( AssertValue(r, 0, cid) );
thread.dir_id = atol( AssertValue(r, 0, cdir_id) );
thread.subject = AssertValue(r, 0, csubject);
thread.closed = atol( AssertValue(r, 0, cclosed) ) == 0 ? false : true;
return status;
}
Error Db::GetThreads(long parent_id, std::vector<Thread> & thread_tab)
{
PGresult * r = 0;
Error status = Error::ok;
try
{
AssertConnection();
std::ostringstream query;
query << "select thread.id, thread.parent_id, thread.dir_id, thread.closed, thread.items, thread.last_item, item.date_modification, item.user_id "
"from core.thread left join core.item on thread.last_item = item.id "
"where thread.parent_id = '" << parent_id << "' order by date_modification asc;";
r = AssertQuery( query.str() );
AssertResultStatus(r, PGRES_TUPLES_OK);
int rows = PQntuples(r);
Thread thread;
int cid = AssertColumn(r, "id");
int cparent_id = AssertColumn(r, "parent_id");
int cdir_id = AssertColumn(r, "dir_id");
int cclosed = AssertColumn(r, "closed");
int citems = AssertColumn(r, "items");
int clast_item = AssertColumn(r, "last_item");
int cdate_modification = PQfnumber(r, "date_modification");
int cuser_id = PQfnumber(r, "user_id");
for(int i=0 ; i<rows ; ++i)
{
thread.id = atol( AssertValue(r, i, cid) );
thread.parent_id = atol( AssertValue(r, i, cparent_id) );
thread.dir_id = atol( AssertValue(r, i, cdir_id) );
thread.closed = atol( AssertValue(r, i, cclosed) ) == 0 ? false : true;
thread.items = atol( AssertValue(r, i, citems) );
thread.last_item.id = atol( AssertValue(r, i, clast_item) );
thread.last_item.date_modification = ConvertTime( Db::AssertValue(r, i, cdate_modification) );
thread.last_item.user_id = atol( Db::AssertValue(r, i, cuser_id) );
thread_tab.push_back(thread);
}
}
catch(const Error & e)
{
@@ -1420,6 +1496,7 @@ return status;
Error Db::AddThread(Thread & thread)
{
PGresult * r = 0;
@@ -1429,10 +1506,12 @@ Error Db::AddThread(Thread & thread)
{
AssertConnection();
std::ostringstream query;
query << "insert into core.thread (dir_id, subject, closed) values (";
query << "insert into core.thread (parent_id, dir_id, closed, items, last_item) values (";
query << '\'' << thread.parent_id << "', ";
query << '\'' << thread.dir_id << "', ";
query << '\'' << Escape(thread.subject) << "', ";
query << '\'' << (thread.closed ? 1 : 0 ) << "'); ";
query << '\'' << (thread.closed ? 1 : 0 ) << "', ";
query << '\'' << thread.items << "', ";
query << '\'' << thread.last_item.id << "'); ";
r = AssertQuery(query.str());
AssertResultStatus(r, PGRES_COMMAND_OK);
@@ -1451,3 +1530,27 @@ return status;
}
Error Db::EditThreadAddItem(long dir_id, long item_id)
{
PGresult * r = 0;
Error status = Error::ok;
try
{
AssertConnection();
std::ostringstream query;
query << "update core.thread set (last_item, items) = ('" << item_id << "', items+1) where dir_id='" << dir_id << "';";
r = AssertQuery(query.str());
AssertResultStatus(r, PGRES_COMMAND_OK);
}
catch(const Error & e)
{
status = e;
}
ClearResult(r);
return status;
}

View File

@@ -45,11 +45,15 @@ public:
void Init(const std::string & database, const std::string & user, const std::string & pass);
bool CheckUser(std::string & login, std::string & password, long & user_id);
Error AddItem(Item & item);
Error EditItemById(Item & item, bool with_subject = true);
Error EditItemByUrl(Item & item, bool with_subject = true);
Error EditItemById(Item & item, bool with_url = true);
Error EditItemByUrl(Item & item, bool with_url = true);
void CheckAllUrlSubject();
void GetItems(std::vector<Item> & item_table, Item & item_ref, bool asc = true);
void GetItems(std::vector<Item> & item_table, long parent_id, Item::Type type, bool with_subject, bool with_content, bool sort_asc);
void GetItem(std::vector<Item> & item_table, long id);
bool GetPriv(Item & item, long id);
Error EditPrivById(Item & item, long id);
@@ -78,7 +82,9 @@ public:
Error AddThread(Thread & thread);
Error GetThreadByDirId(long dir_id, Thread & thread);
Error GetThreads(long parent_id, std::vector<Thread> & thread_tab);
Error EditThreadAddItem(long dir_id, long item_id);
protected:
PGconn * pg_conn;
@@ -103,14 +109,14 @@ protected:
Error AddItemIntoContent(Item & item);
Error AddItemIntoItem(Item & item);
Error EditItemInItem(Item & item, bool with_subject);
Error EditItemInItem(Item & item, bool with_url);
Error EditItemInContent(Item & item);
Error EditItemGetId(Item & item);
Error EditItemGetContentId(Item & item);
void CheckAllUrlSubjectModifyItem(Item & item);
PGresult * GetItemsQuery(Item & item_ref, bool asc = true);
PGresult * GetItemsQuery(long parent_id, Item::Type type, bool with_subject, bool with_content, bool sort_asc);
bool DelItemDelItem(const Item & item);
void DelItemDelContent(const Item & item);

View File

@@ -32,19 +32,23 @@ std::string content;
std::string url;
// 0 - simple txt
// 1 - formatted txt
// 2 - html
// 3 - bbcode
int content_type;
enum Type
{
dir = 0,
file = 1,
none = 1000
};
Type type;
//item_type;

View File

@@ -40,11 +40,6 @@ return true;
LastContainer::LastContainer()
{
}
LastContainer::Iterator LastContainer::Begin()
{

View File

@@ -60,10 +60,6 @@ public:
public:
// !! nie potrzebny, skasowac po stworzeniu jednej biblioteki cmslu.a
// chwilowo bez tego wystepuja problemy z linkowaniem
LastContainer();
Iterator Begin();
Iterator End();
void UserLogin(long user_id, const std::string & name, unsigned int ip, long session_id);

View File

@@ -56,10 +56,9 @@ void print_syntax()
int main(int argv, char ** argc)
{
std::srand(std::time(0));
if( argv != 2 )

View File

@@ -64,6 +64,8 @@ std::string::iterator i;
*i = '_';
}
}
ToSmall(item.url);
if( item.url.empty() )
item.url = "bez_nazwy"; // !! wrzucic do pliku konfiguracyjnego
@@ -157,21 +159,38 @@ return c;
}
bool HtmlTryChar(std::ostringstream & out, int c)
{
if( c == '<' )
{
out << "&lt;";
return true;
}
else
if( c == '>' )
{
out << "&gt;";
return true;
}
else
if( c == '&' )
{
out << "&amp;";
return true;
}
return false;
}
void HtmlEscape(std::ostringstream & out, const std::string & in)
{
std::string::const_iterator i;
for(i = in.begin() ; i != in.end() ; ++i)
{
if( *i == '<' )
out << "&lt;";
else
if( *i == '>' )
out << "&gt;";
else
if( *i == '&' )
out << "&amp;";
else
if( !HtmlTryChar(out, *i) )
out << *i;
}
}
@@ -187,6 +206,52 @@ return out.str();
}
void HtmlEscapeFormTxt(std::ostringstream & out, const std::string & in)
{
std::string::const_iterator i;
int was_enter = 0; // how many enteres there were before
out << "<p>";
for(i = in.begin() ; i != in.end() ; ++i)
{
if( !HtmlTryChar(out, *i) )
{
if( *i == 13 )
// skipping stupid characters (\r\n\ in dos mode)
continue;
if( *i == 10 )
{
++was_enter;
}
else
{
if( was_enter == 1 )
out << "<br>\n";
else
if( was_enter > 1 )
out << "</p>\n<p>";
out << *i;
was_enter = 0;
}
}
}
out << "</p>\n";
}
std::string HtmlEscapeFormTxt(const std::string & in)
{
std::ostringstream out;
HtmlEscapeFormTxt(out, in);
return out.str();
}
const char * DateToStr(int year, int month, int day, int hour, int min, int sec)
{
@@ -213,7 +278,7 @@ static char buffer[100];
const char * DateToStr(tm * ptm)
{
return DateToStr(ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
return DateToStr(ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
}
@@ -243,4 +308,53 @@ return buffer;
}
bool IsWhite(int s)
{
if( s==' ' || s=='\t' || s==13 )
return true;
return false;
}
void TrimWhite(std::string & s)
{
std::string::size_type i;
if( s.empty() )
return;
// looking for white characters at the end
for(i=s.size()-1 ; i>0 && IsWhite(s[i]) ; --i);
if( i==0 && IsWhite(s[i]) )
{
// the whole string has white characters
s.clear();
return;
}
// deleting white characters at the end
if( i != s.size() - 1 )
s.erase(i+1, std::string::npos);
// looking for white characters at the beginning
for(i=0 ; i<s.size() && IsWhite(s[i]) ; ++i);
// deleting white characters at the beginning
if( i != 0 )
s.erase(0, i);
}
void ToSmall(std::string & s)
{
std::string::size_type i;
for(i=0 ; i<s.size() ; ++i)
{
if( s[i]>='A' && s[i]<='Z' )
s[i] = s[i] - 'A' + 'a';
}
}

View File

@@ -30,10 +30,17 @@ void CorrectUrl(Item & item);
void SetUrlFromSubject(Item & item);
void HtmlEscape(std::ostringstream & out, const std::string & in);
void HtmlEscapeFormTxt(std::ostringstream & out, const std::string & in);
std::string HtmlEscape(const std::string & in);
std::string HtmlEscapeFormTxt(const std::string & in);
const char * DateToStr(int year, int month, int day, int hour, int min, int sec);
const char * DateToStr(tm * ptm);
const char * DateToStr(time_t t);
const char * IpToStr(unsigned int ip_);
bool IsWhite(int s);
void TrimWhite(std::string & s);
void ToSmall(std::string & s);
#endif

View File

@@ -32,7 +32,7 @@ const char * Mount::TypeToStr()
case thread:
sprintf(buffer, "thread");
break;
break;
default:
sprintf(buffer, "the name is not set");
@@ -43,7 +43,7 @@ return buffer;
}
bool Mount::ParseStrParam(const std::string & param)
bool Mount::ParseStrParam(const std::string & param, const std::vector<int> & args)
{
Param p = none;
@@ -53,12 +53,30 @@ bool Mount::ParseStrParam(const std::string & param)
if( param == "desc" )
p = desc;
else
if( param == "withheader" )
p = withheader;
else
if( param == "withinfo" )
p = withinfo;
else
if( param == "restrictcreatethread" )
p = restrictcreatethread;
else
if( param == "only_root_can_remove" )
p = only_root_can_remove;
else
if( param == "can_use_emacs_on" )
p = can_use_emacs_on;
else
if( param == "can_use_mkdir_on" )
p = can_use_mkdir_on;
else
if( param == "none" )
return true;
else
return false;
param_table.insert(p);
param_table.insert( std::make_pair(p, args) );
return true;
}
@@ -66,10 +84,35 @@ return true;
bool Mount::IsParam(Param p)
{
std::set<Param>::iterator i = param_table.find(p);
ParamTable::iterator i = param_table.find(p);
if( i == param_table.end() )
return false;
return true;
}
bool Mount::IsParam(Param p, int * first_arg)
{
ParamTable::iterator i = param_table.find(p);
if( i == param_table.end() )
{
*first_arg = -1;
return false;
}
if( !i->second.empty() )
*first_arg = i->second[0];
else
*first_arg = -1;
return true;
}
void Mount::ClearParams()
{
param_table.clear();
}

View File

@@ -11,8 +11,9 @@
#ifndef headerfilecmslucoremount
#define headerfilecmslucoremount
#include <set>
#include <map>
#include <string>
#include <vector>
class Mount
@@ -31,7 +32,13 @@ public:
{
none = 0,
asc,
desc
desc,
withheader,
withinfo,
restrictcreatethread,
only_root_can_remove,
can_use_emacs_on,
can_use_mkdir_on
};
@@ -40,11 +47,14 @@ public:
Mount();
const char * TypeToStr();
bool ParseStrParam(const std::string & param);
bool ParseStrParam(const std::string & param, const std::vector<int> & args);
bool IsParam(Param p);
bool IsParam(Param p, int * first_arg);
void ClearParams();
private:
std::set<Param> param_table;
typedef std::map<Param, std::vector<int> > ParamTable;
ParamTable param_table;
};

View File

@@ -52,17 +52,77 @@ void MountParser::ReadWord(std::string & res)
}
void MountParser::ReadParam(std::string & res)
bool MountParser::ReadParamArg(int & out)
{
res.clear();
SkipWhite();
while( *pinput && *pinput!=10 && *pinput!=',' && !IsWhite(*pinput) )
char * new_pos;
long temp = strtol(pinput, &new_pos, 10);
if( pinput == new_pos )
return false;
pinput = new_pos;
SkipWhite();
// here can we make a test whether the temp is greater from 'int' type
out = (int)temp;
return true;
}
void MountParser::ReadParamArgs(std::vector<int> & args)
{
int arg;
while( ReadParamArg(arg) )
{
args.push_back(arg);
log << log3 << "MP: mount param arg: " << arg << logend;
if( *pinput == ',' )
++pinput;
}
}
void MountParser::ReadParam(std::string & res, std::vector<int> & args)
{
SkipWhite();
res.clear();
args.clear();
while( *pinput && *pinput!=10 && *pinput!=',' && *pinput!='(' && !IsWhite(*pinput) )
{
res += *pinput;
++pinput;
}
if( *pinput==',' )
if( res.empty() )
return;
// reading arguments
SkipWhite();
if( *pinput == '(' )
{
++pinput;
ReadParamArgs(args);
if( *pinput != ')' )
{
// there should be ')' at the end
// temporarily we do nothing
}
else
{
++pinput;
}
}
if( *pinput == ',' )
++pinput;
}
@@ -118,11 +178,11 @@ void MountParser::ReadMountPoint()
void MountParser::ReadMountParams()
{
SkipWhite();
mount.ClearParams();
for( ReadParam(temp) ; !temp.empty() ; ReadParam(temp) )
for( ReadParam(temp, param_args) ; !temp.empty() ; ReadParam(temp, param_args) )
{
if( !mount.ParseStrParam(temp) )
if( !mount.ParseStrParam(temp, param_args) )
{
log << log1 << "MP: unknown mount param: " << temp << logend;
err = Error::mount_no_param;

View File

@@ -12,6 +12,9 @@
#include <map>
#include <string>
#include <vector>
#include <stdlib.h>
#include <limits.h>
#include "mount.h"
#include "item.h"
@@ -32,7 +35,9 @@ private:
void SkipWhite();
void SkipLine();
void ReadWord(std::string & res);
void ReadParam(std::string & res);
bool ReadParamArg(int & out);
void ReadParamArgs(std::vector<int> & args);
void ReadParam(std::string & res, std::vector<int> & args);
void ReadMountType();
void ReadMountPoint();
void ReadMountParams();
@@ -40,6 +45,8 @@ private:
const char * pinput;
std::string temp;
std::vector<int> param_args;
Mount mount;

View File

@@ -19,7 +19,10 @@ void Mounts::ReadMounts()
MountParser mp;
// !! tymczasowo - bedzie odczyt z bazy z /etc/fstab
std::string temp = "thread /news desc";
std::string temp =
"cms / withheader, withinfo \n"
"thread /news desc, withheader, withinfo, restrictcreatethread(-1) \n"
"thread /forum asc, withinfo, restrictcreatethread(3), only_root_can_remove, can_use_emacs_on(4), can_use_mkdir_on(3)";
Error err = mp.Parse(temp, mount_table);
@@ -34,12 +37,27 @@ void Mounts::ReadMounts()
/*
Mount Mounts::GetCurrentMountPoint()
{
return current_dir;
}
*/
Mount::Type Mounts::CurrentMountType()
{
return current_dir.type;
}
bool Mounts::CurrentMountIsParam(Mount::Param p)
{
return current_dir.IsParam(p);
}
bool Mounts::CurrentMountIsParam(Mount::Param p, int * first_arg)
{
return current_dir.IsParam(p, first_arg);
}
void Mounts::MountCmsForRoot()

View File

@@ -24,7 +24,15 @@ public:
void ReadMounts();
void CalculateCurrentMountType();
Mount GetCurrentMountPoint();
// !! nie lepiej aby zwracal tutaj referencje albo wskaznik na biezacy punkt?
// !! w Mount mamy strukture std::set
//Mount GetCurrentMountPoint();
Mount::Type CurrentMountType();
bool CurrentMountIsParam(Mount::Param p);
bool CurrentMountIsParam(Mount::Param p, int * first_arg);
void MountCmsForRoot();

View File

@@ -12,7 +12,7 @@
#include "postparser.h"
#include "cookieparser.h"
#include "log.h"
#include "data.h"
Request::Request() : char_empty(0)
@@ -66,7 +66,10 @@ void Request::Clear()
status = Error::ok;
is_thread = false;
thread.Clear();
thread_tab.clear();
}
@@ -491,4 +494,160 @@ bool Request::HasReadExecAccess(const Item & item)
}
// returning true if we can create a thread in the current directory
bool Request::CanCreateThread(bool check_root)
{
if( request.dir_table.empty() )
return false;
if( request.is_item )
return false;
if( !HasWriteAccess(*request.dir_table.back()) )
return false;
if( data.mounts.CurrentMountType() != Mount::thread )
return false;
if( !check_root && session && session->puser && session->puser->super_user )
// super can create thread regardless of the restrictcreatethread option
return true;
// !! w przyszlosci mozna odczytywac wiecej parametrow od restrictcreatethread
// tymczasowo wykorzystujemy tylko pierwszy
int level;
if( data.mounts.CurrentMountIsParam(Mount::restrictcreatethread, &level) )
{
if( level == -1 )
return false;
// we can only allow on a specific level
if( int(request.dir_table.size()) != level )
return false;
}
return true;
}
bool Request::CanRemove(const Item & item)
{
if( item.parent_id == -1 )
{
// rm for the root dir
// only the superuser can do it
if( !request.session->puser || !request.session->puser->super_user )
return false;
}
else
{
Item * last_but_one_dir = data.dirs.GetDir(item.parent_id);
if( !last_but_one_dir )
// ops, there is no a parent dir
return false;
if( !request.HasWriteAccess(*last_but_one_dir) )
return false;
}
if( data.mounts.CurrentMountIsParam(Mount::only_root_can_remove) )
// this can be deleted only be a root
if( !request.session->puser || !request.session->puser->super_user )
return false;
return true;
}
bool Request::CanUseEmacs(const Item & item, bool check_root)
{
if( !check_root && request.session->puser && request.session->puser->super_user )
// super user can use emacs everywhere
return true;
if( !request.HasWriteAccess(item) )
return false;
int level;
if( data.mounts.CurrentMountIsParam(Mount::can_use_emacs_on, &level) )
if( level != int(request.dir_table.size()) )
return false;
return true;
}
bool Request::CanUseMkdir(const Item & item, bool check_root)
{
// you can create a directory only in a directory
if( item.type != Item::dir )
return false;
if( !check_root && request.session->puser && request.session->puser->super_user )
// super user can use mkdir everywhere
return true;
if( !request.HasWriteAccess(item) )
return false;
int level;
if( data.mounts.CurrentMountIsParam(Mount::can_use_mkdir_on, &level) )
if( level != int(request.dir_table.size()) )
return false;
return true;
}
bool Request::CanUseHtml(long user_id)
{
User * puser = data.users.GetUser(user_id);
if( !puser )
return false;
if( puser->super_user )
// super user can use html
return true;
long group = data.groups.GetGroupId("allow_html");
if( group == -1 )
// there is no such a group
return false;
if( puser->IsMemberOf(group) )
return true;
return false;
}
bool Request::CanUseBBCode(long user_id)
{
User * puser = data.users.GetUser(user_id);
if( !puser )
return false;
if( puser->super_user )
// super user can use bbcode
return true;
long group = data.groups.GetGroupId("allow_bbcode");
if( group == -1 )
// there is no such a group
return false;
if( puser->IsMemberOf(group) )
return true;
return false;
}

View File

@@ -111,8 +111,12 @@ struct Request
//std::vector<Item> dir_table2;
// current thread (if exists)
bool is_thread;
Thread thread;
std::vector<Thread> thread_tab;
// this string is used for many purposes such as redirecting
std::string str;
@@ -156,7 +160,13 @@ struct Request
bool HasReadWriteAccess(const Item & item);
bool HasReadExecAccess(const Item & item);
bool CanCreateThread(bool check_root = false);
bool CanRemove(const Item & item);
bool CanUseEmacs(const Item & item, bool check_root = false);
bool CanUseMkdir(const Item & item, bool check_root = false);
bool CanUseHtml(long user_id);
bool CanUseBBCode(long user_id);
private:
// used to set some env_* variables into it, when the server didn't set that variable

View File

@@ -19,17 +19,26 @@ class Thread
public:
long id;
// !! parent_id potrzebne w ogole jest?
long parent_id;
long dir_id;
std::string subject;
bool closed;
// how many items there are inside
long items;
// last item in the directory (this variable is mainly for reading)
// at the moment only used: id, date_modification, user_id
Item last_item;
void Clear()
{
id = dir_id = -1;
id = parent_id = dir_id = -1;
last_item.Clear();
closed = false;
subject.clear();
items = 0;
}
Thread()