From 4fe3d4339f6f22f866c35f2253257e448e8a29b0 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Tue, 16 Feb 2010 00:37:00 +0000 Subject: [PATCH] added: parameter 'r' to priv function all directories and files can be changed git-svn-id: svn://ttmath.org/publicrep/winix/trunk@586 e52654a7-88a9-db11-a3e9-0013d4bc506e --- content/content.h | 15 ++- content/priv.cpp | 220 ++++++++++++++++++++++++++++----------- content/thread.cpp | 3 +- core/db.cpp | 13 ++- core/db.h | 1 + core/dirs.cpp | 19 ++++ core/dirs.h | 3 + html/fun_priv.html | 92 +++++++++++++--- html/fun_thread.html | 40 ++++--- locale/en | 5 + locale/pl | 4 + static/layout1/winix.css | 9 ++ templates/dir.cpp | 12 +++ templates/priv.cpp | 11 ++ templates/templates.cpp | 3 + templates/templates.h | 3 + 16 files changed, 347 insertions(+), 106 deletions(-) diff --git a/content/content.h b/content/content.h index a6a8af1..dc6bb9a 100755 --- a/content/content.h +++ b/content/content.h @@ -100,9 +100,20 @@ class Content void Mkdir(Item & item, bool add_to_dir_table); long PostFunDefaultParsePath(); void PostFunDefault(); + + bool PrivCheckAccess(); + void PrivLog(const char * what, const std::string & url, long user, long group, int priv); void PostFunPriv(); - void PostFunPriv(Item & item); - + void PrivFilesInDir(long parent_id); + void PrivDir(long parent_id); + void FunPriv(Item & item, long user_id, long group_id, int privileges); + bool ReadPriv(const char * user_in, const char * group_in, const char * priv_in, long & user_id, long & group_id, int & priv); + void PrivDir(); + void PrivOneItem(); + + long user_id_file, group_id_file, user_id_dir, group_id_dir; + int priv_file, priv_dir; + bool FunCreateThreadCheckAccess(); bool FunCreateThreadCheckAbuse(); void ReadThread(Thread & thread); diff --git a/content/priv.cpp b/content/priv.cpp index 2418f16..6783129 100755 --- a/content/priv.cpp +++ b/content/priv.cpp @@ -14,82 +14,182 @@ #include "../core/data.h" -void Content::PostFunPriv(Item & item) +bool Content::PrivCheckAccess() { - try + // we do not check permissions here + // permissions depends on the user, group, and privileges + // but we cannot use parameter 'r' on files + // and only logged users can change permissions + + if( !request.session->puser || (request.is_item && request.IsParam("r")) ) { - std::string * user = request.PostVar("user"); - std::string * group = request.PostVar("group"); - std::string * priv = request.PostVar("privileges"); - - if( !user || !group || !priv ) - { - log << log3 << "Content: PostFunPriv: there is no some post variables" << logend; - // some kind of error to report? - // !! wstawic nowy kod bledu i rzucic wyjatek jego (usunac powyzszy wpis log takze) - return; - } - - long user_id = data.users.GetUserId( *user ); - long group_id = data.groups.GetGroupId( *group ); - int privileges = strtol( priv->c_str() , 0, 8); - - if( user_id==item.user_id && group_id==item.group_id && privileges==item.privileges ) - { - log << log3 << "Content: PostFunPriv: nothing to change" << logend; - throw Error(Error::ok); - } - - if( !request.CanChangeUser(item, user_id) ) - throw Error(Error::cant_change_user); - - if( !request.CanChangeGroup(item, group_id) ) - throw Error(Error::cant_change_group); - - if( !request.CanChangePrivileges(item, privileges) ) - throw Error(Error::cant_change_privileges); - - item.user_id = user_id; - item.group_id = group_id; - item.privileges = privileges; - - request.session->done = Done::privileged_item; - request.session->done_status = db.EditPrivById(item, item.id); - } - catch(const Error & e) - { - request.session->done_status = e; + request.status = Error::permission_denied; + return false; } - if( request.session->done_status == Error::ok ) - { - request.session->item = item; - request.session->done_timer = 2; - RedirectTo(item); - } - else - { - log << log1 << "Content: PostFunPriv: Error: " << static_cast(request.session->done_status) << logend; - } - - request.status = request.session->done_status; +return true; } +void Content::FunPriv(Item & item, long user_id, long group_id, int privileges) +{ + if( user_id==item.user_id && group_id==item.group_id && privileges==item.privileges ) + return; + + if( !request.CanChangeUser(item, user_id) ) + { + log << log3 << "Content: can't change the user" << logend; + return; + } + + if( !request.CanChangeGroup(item, group_id) ) + { + log << log3 << "Content: can't change the group" << logend; + return; + } + + if( !request.CanChangePrivileges(item, privileges) ) + { + log << log3 << "Content: can't change privileges" << logend; + return; + } + + item.user_id = user_id; + item.group_id = group_id; + item.privileges = privileges; + + request.session->done_status = db.EditPrivById(item, item.id); +} + + +void Content::PrivLog(const char * what, const std::string & url, long user, long group, int priv) +{ + log << log3 << "Content: " + << what << url + << ", user: " << user + << ", group: " << group + << ", priv: " << priv + << logend; +} + + + +void Content::PrivFilesInDir(long parent_id) +{ + request.item_table.clear(); + db.GetItems(request.item_table, parent_id, Item::file, false, false, true); + + std::vector::iterator i = request.item_table.begin(); + + for( ; i != request.item_table.end() ; ++i) + { + PrivLog("changed file: ", i->url, user_id_file, group_id_file, priv_file); + FunPriv(*i, user_id_file, group_id_file, priv_file); + } +} + + +// recurrence +void Content::PrivDir(long parent_id) +{ + PrivFilesInDir(parent_id); + + + DirContainer::ParentIterator i = data.dirs.FindFirstParent(parent_id); + + for( ; i != data.dirs.ParentEnd() ; i = data.dirs.NextParent(i) ) + { + PrivLog("changed dir: ", i->second->url, user_id_dir, group_id_dir, priv_dir); + FunPriv(*(i->second), user_id_dir, group_id_dir, priv_dir); + PrivDir(i->second->id); + } +} + + +bool Content::ReadPriv(const char * user_in, const char * group_in, const char * priv_in, + long & user_id, long & group_id, int & priv) +{ + std::string * user_str = request.PostVar(user_in); + std::string * group_str = request.PostVar(group_in); + std::string * priv_str = request.PostVar(priv_in); + + if( !user_str || !group_str || !priv_str ) + { + log << log1 << "Content: PostFunPriv: there is no some post variables" << logend; + return false; + } + + user_id = data.users.GetUserId( *user_str ); + group_id = data.groups.GetGroupId( *group_str ); + priv = strtol( priv_str->c_str() , 0, 8); + +return true; +} + + +void Content::PrivDir() +{ + if( !ReadPriv("userfile", "groupfile", "privilegesfile", user_id_file, group_id_file, priv_file) ) + return; + + if( !ReadPriv("userdir", "groupdir", "privilegesdir", user_id_dir, group_id_dir, priv_dir) ) + return; + + if( request.IsPostVar("changecurrentdir") ) + { + PrivLog("changed dir: ", request.dir_table.back()->url, user_id_dir, group_id_dir, priv_dir); + FunPriv(*request.dir_table.back(), user_id_dir, group_id_dir, priv_dir); + } + + // go through all directories (recurrence) + PrivDir(request.dir_table.back()->id); + + RedirectToLastDir(); +} + + + +// changing only one item (either a dir or file) +void Content::PrivOneItem() +{ + if( !ReadPriv("user", "group", "privileges", user_id_file, group_id_file, priv_file) ) + return; + + if( request.is_item ) + { + FunPriv(request.item, user_id_file, group_id_file, priv_file); + RedirectTo(request.item); + } + else + { + FunPriv(*request.dir_table.back(), user_id_file, group_id_file, priv_file); + RedirectToLastDir(); + } +} + + + void Content::PostFunPriv() { - if( request.is_item ) - PostFunPriv( request.item ); + if( !PrivCheckAccess() ) + return; + + + if( request.IsParam("r") ) + { + PrivDir(); + } else - PostFunPriv( *request.dir_table.back() ); + { + PrivOneItem(); + } } void Content::FunPriv() { - // we do not check permissions here - // permissions depends on the user, group, and privileges + PrivCheckAccess(); } diff --git a/content/thread.cpp b/content/thread.cpp index 05caa20..be05679 100755 --- a/content/thread.cpp +++ b/content/thread.cpp @@ -47,8 +47,9 @@ void Content::FunThread() db.GetItems(request.item_table, request.dir_table.back()->id, Item::file, true, true, asc); db.GetThreads(request.dir_table.back()->id, request.thread_tab); - + CheckAccessToItems(); + std::sort(request.thread_tab.begin(), request.thread_tab.end(), FunThreadSort); } diff --git a/core/db.cpp b/core/db.cpp index e3cd945..2840b63 100755 --- a/core/db.cpp +++ b/core/db.cpp @@ -799,6 +799,8 @@ void Db::GetItems(std::vector & item_table, long parent_id, Item::Type typ item_table.clear(); PGresult * r = 0; + item_table.clear(); + try { AssertConnection(); @@ -859,7 +861,10 @@ return res; } -// !! ta chyba nie uzywana juz? +// !! zamienic nazwe na GetFile? +// !! cos tu pomyslec innego, ta metoda nie musi pobierac tablicy za argument +// i tak istnieje tylko jedna pozycja o okreslonym id +// mozna zwracac bool i pobierac referencje na item void Db::GetItem(std::vector & item_table, long id) { PGresult * r = 0; @@ -1020,8 +1025,6 @@ 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; @@ -1033,7 +1036,8 @@ bool result = false; AssertConnection(); std::ostringstream query; - query << "select user_id, group_id, privileges, subject, content, guest_name from core.item left join core.content on item.content_id = content.id where item.id='" << id << "';"; // !! tymczasowo odczytujemy z content i subject + query << "select user_id, group_id, privileges, guest_name from core.item" + << " where item.id='" << id << "';"; r = AssertQuery( query.str() ); AssertResultStatus(r, PGRES_TUPLES_OK); @@ -1092,6 +1096,7 @@ return result; + Error Db::DelDirById(long id) { Error result = Error::ok; diff --git a/core/db.h b/core/db.h index d58b39b..54103cf 100755 --- a/core/db.h +++ b/core/db.h @@ -51,6 +51,7 @@ public: void GetItems(std::vector & item_table, long parent_id, Item::Type type, bool with_subject, bool with_content, bool sort_asc); + // !! pobiera tylko jeden item (cos wymyslec innego z nazwa albo argumentem) void GetItem(std::vector & item_table, long id); diff --git a/core/dirs.cpp b/core/dirs.cpp index 8c8842c..1488ba4 100755 --- a/core/dirs.cpp +++ b/core/dirs.cpp @@ -104,6 +104,25 @@ return true; } +DirContainer::ParentIterator Dirs::FindFirstParent(long parent_id) +{ + DirContainer::ParentIterator i = dir_table.FindFirstParent(parent_id); + +return i; +} + + +DirContainer::ParentIterator Dirs::NextParent(DirContainer::ParentIterator i) +{ + return dir_table.NextParent(i); +} + + +DirContainer::ParentIterator Dirs::ParentEnd() +{ + return dir_table.ParentEnd(); +} + // dodatkowo moze metoda AppendPath dodajaca sciezke do biezacego stringa? // albo tutaj stringa nie czyscic? diff --git a/core/dirs.h b/core/dirs.h index 355f96d..3233a62 100755 --- a/core/dirs.h +++ b/core/dirs.h @@ -37,6 +37,9 @@ public: static void SplitPath(const std::string & path, std::string & dir, std::string & file); + DirContainer::ParentIterator FindFirstParent(long parent_id); + DirContainer::ParentIterator NextParent(DirContainer::ParentIterator i); + DirContainer::ParentIterator ParentEnd(); // these methods return null if there is no such a dir Item * GetRootDir(); diff --git a/html/fun_priv.html b/html/fun_priv.html index 1edb319..08df4a2 100755 --- a/html/fun_priv.html +++ b/html/fun_priv.html @@ -6,35 +6,93 @@ {error_code}: [done_status]

[end] +[is-no winix_function_param_is "r"]
{priv_form_legend} - - - - - + + + + +
{user}: - -
{group}: - -
{permissions}:
{user}: + +
{group}: + +
{permissions}:
+[else] + +
+
+ {priv_form_legend} +

{priv_change_in_dir}: [dir]

+ +

{priv_for_all_files}:

+ + + + + + +
{user}: + +
{group}: + +
{permissions}:
+ + +

{priv_for_all_dirs}:

+ + + + + + +
{user}: + +
{group}: + +
{permissions}:
+ + + + +
+
+ +[end] diff --git a/html/fun_thread.html b/html/fun_thread.html index f2e930b..2e414cf 100755 --- a/html/fun_thread.html +++ b/html/fun_thread.html @@ -1,33 +1,29 @@ -[if-one thread_can_create] - [is mount_page_is "subject"][dir_last_subject][end] - [is mount_page_is "info"][dir_last_info][end] - +[is mount_page_is "subject"][dir_last_subject][end] +[is mount_page_is "info"][dir_last_info][end] + +[if-one thread_can_create] - - [if-one thread_tab] - - - [for thread_tab] - - - - - - [end] -
{thread_table_title}{thread_table_author}{thread_table_replies}{thread_table_last_post}
[thread_tab_subject][thread_tab_author][thread_tab_answers][thread_tab_last_item_date_modification_nice] ([thread_tab_last_item_user])
+[end] + +[if-one thread_tab] + + + [for thread_tab] + + + + + [end] +
{thread_table_title}{thread_table_author}{thread_table_replies}{thread_table_last_post}
[thread_tab_subject][thread_tab_author][thread_tab_answers][thread_tab_last_item_date_modification_nice] ([thread_tab_last_item_user])
[end] + [if-one thread_is] - [is mount_page_is "subject"][dir_last_subject][end] - [is mount_page_is "info"][dir_last_info][end] - [if-one dir_can_use_emacs]
  • {thread_reply_in_this_thread}
  • diff --git a/locale/en b/locale/en index ed80d57..30eedb7 100755 --- a/locale/en +++ b/locale/en @@ -114,6 +114,11 @@ mkdir_form_legend = Make directory form priv_header = Permissions priv_was_error = We are sorry but there were errors while changing permissions. priv_form_legend = Permissions +priv_change_in_dir = Change permissions for all items in the following directory +priv_for_all_files = For all files to +priv_for_all_dirs = For all directories to +priv_change_current_dir = Change also the current directory + reload_header = Reload reload_was_error = We are sorry but there were errors while reloading. diff --git a/locale/pl b/locale/pl index 7c238b4..af82148 100755 --- a/locale/pl +++ b/locale/pl @@ -113,6 +113,10 @@ mkdir_form_legend = Wype priv_header = Zmień uprawnienia dostępu priv_was_error = Przykro nam ale wystąpiły błędy podczas zmiany uprawnień. priv_form_legend = Uprawnienia +priv_change_in_dir = Zmień hurtowo uprawnienia w katalogu +priv_for_all_files = Dla wszystkich plików na +priv_for_all_dirs = Dla wszystkich katalogów na +priv_change_current_dir = Zmień także sam katalog bieżący reload_header = Przeładuj reload_was_error = Przykro nam ale wystąpiły błędy podczas ponownego wczytywania. diff --git a/static/layout1/winix.css b/static/layout1/winix.css index ecd72bf..b35e4c0 100755 --- a/static/layout1/winix.css +++ b/static/layout1/winix.css @@ -488,9 +488,18 @@ font-size: 0.8em; } +table.withoutborder th { +border: 0; +padding: 0 1em 0 0; +text-align: left; +font-weight: bold; +vertical-align: middle; +} + table.withoutborder td { border: 0; padding: 0 1em 0 0; +vertical-align: middle; } diff --git a/templates/dir.cpp b/templates/dir.cpp index 6860e5c..9f0c9fc 100755 --- a/templates/dir.cpp +++ b/templates/dir.cpp @@ -31,6 +31,18 @@ void dir(Info & i) } +void dir_without_slash(Info & i) +{ + for(size_t a=0 ; aurl); + + if( a < request.dir_table.size()-1 ) + i.out << '/'; + } +} + + //!! moze wystarczy sprawdzac tylko ostatni katalog? // bo inaczej i tak bylo by 'access denied' void dir_can_read_exec(Info & i) diff --git a/templates/priv.cpp b/templates/priv.cpp index 1e7735d..76ed1e2 100755 --- a/templates/priv.cpp +++ b/templates/priv.cpp @@ -252,8 +252,19 @@ void priv_privileges(Info & i) } +void priv_privileges_for_files(Info & i) +{ + //!! bedzie uzyte umask + i.out << std::setbase(8) << (int)0644 << std::setbase(10); +} +void priv_privileges_for_dirs(Info & i) +{ + //!! bedzie uzyte umask + i.out << std::setbase(8) << (int)0755 << std::setbase(10); +} + } // namespace TemplatesFunctions diff --git a/templates/templates.cpp b/templates/templates.cpp index 2c15bd3..cc9c1dd 100755 --- a/templates/templates.cpp +++ b/templates/templates.cpp @@ -251,6 +251,7 @@ void Templates::CreateFunctions() dir */ functions.Insert("dir", dir); + functions.Insert("dir_without_slash", dir_without_slash); functions.Insert("dir_can_read_exec", dir_can_read_exec); functions.Insert("dir_can_write", dir_can_write); functions.Insert("dir_can_remove", dir_can_remove); @@ -306,6 +307,8 @@ void Templates::CreateFunctions() functions.Insert("priv_group_tab_isdefault", priv_group_tab_isdefault); functions.Insert("priv_privileges", priv_privileges); + functions.Insert("priv_privileges_for_files", priv_privileges_for_files); + functions.Insert("priv_privileges_for_dirs", priv_privileges_for_dirs); /* diff --git a/templates/templates.h b/templates/templates.h index aed597a..ea1f8d2 100755 --- a/templates/templates.h +++ b/templates/templates.h @@ -166,6 +166,7 @@ namespace TemplatesFunctions dir */ void dir(Info & i); + void dir_without_slash(Info & i); void dir_can_read_exec(Info & i); void dir_can_write(Info & i); void dir_can_remove(Info & i); @@ -218,6 +219,8 @@ namespace TemplatesFunctions void priv_group_tab_isdefault(Info & i); void priv_privileges(Info & i); + void priv_privileges_for_files(Info & i); + void priv_privileges_for_dirs(Info & i); /*