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"]
+[else]
+
+
+
+[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]
-
- {thread_table_title} | {thread_table_author} | {thread_table_replies} | {thread_table_last_post} |
- [for thread_tab]
-
- [thread_tab_subject] |
- [thread_tab_author] | [thread_tab_answers] |
- [thread_tab_last_item_date_modification_nice] ([thread_tab_last_item_user]) |
-
- [end]
-
+[end]
+
+[if-one thread_tab]
+
+ {thread_table_title} | {thread_table_author} | {thread_table_replies} | {thread_table_last_post} |
+ [for thread_tab]
+
+ [thread_tab_subject] |
+ [thread_tab_author] | [thread_tab_answers] |
+ [thread_tab_last_item_date_modification_nice] ([thread_tab_last_item_user]) |
+
[end]
+
[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]