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
This commit is contained in:
Tomasz Sowa 2010-02-16 00:37:00 +00:00
parent a276fb6b79
commit 4fe3d4339f
16 changed files with 347 additions and 106 deletions

View File

@ -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);

View File

@ -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<int>(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<Item>::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();
}

View File

@ -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);
}

View File

@ -799,6 +799,8 @@ void Db::GetItems(std::vector<Item> & 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> & 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;

View File

@ -51,6 +51,7 @@ public:
void GetItems(std::vector<Item> & 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> & item_table, long id);

View File

@ -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?

View File

@ -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();

View File

@ -6,35 +6,93 @@
{error_code}: [done_status]</p>
[end]
[is-no winix_function_param_is "r"]
<form id="additem" method="post" action="[doc_base_url][dir][if-one item_is][item_url]/[end]priv">
<fieldset>
<legend>{priv_form_legend}</legend>
<table class="withoutborder">
<tr><td>{user}:</td><td>
<select name="user" class="users">
[for priv_user_tab]
<option[if-one priv_user_tab_isdefault] selected[end]>[priv_user_tab_name]</option>
[end]
</select>
</td></tr>
<tr><td>{group}: </td><td>
<select name="group" class="groups">
[for priv_group_tab]
<option[if-one priv_group_tab_isdefault] selected[end]>[priv_group_tab_name]</option>
[end]
</select>
</td></tr>
<tr><td>{permissions}:</td><td><input class="privileges" type="text" name="privileges" value="[priv_privileges]"></td></tr>
<tr><th>{user}:</th><td>
<select name="user" class="users">
[for priv_user_tab]
<option[if-one priv_user_tab_isdefault] selected[end]>[priv_user_tab_name]</option>
[end]
</select>
</td></tr>
<tr><th>{group}: </th><td>
<select name="group" class="groups">
[for priv_group_tab]
<option[if-one priv_group_tab_isdefault] selected[end]>[priv_group_tab_name]</option>
[end]
</select>
</td></tr>
<tr><th>{permissions}:</th><td><input class="privileges" type="text" name="privileges" value="[priv_privileges]"></td></tr>
</table>
<input class="submit" type="submit" value="{change}">
</fieldset>
</form>
[else]
<form id="additem" method="post" action="[doc_base_url][dir]priv/r">
<fieldset>
<legend>{priv_form_legend}</legend>
<p class="withnext">{priv_change_in_dir}: [dir]</p>
<h2>{priv_for_all_files}:</h2>
<table class="withoutborder">
<tr><th>{user}:</th><td>
<select name="userfile" class="users">
[for priv_user_tab]
<option[if-one priv_user_tab_isdefault] selected[end]>[priv_user_tab_name]</option>
[end]
</select>
</td></tr>
<tr><th>{group}: </th><td>
<select name="groupfile" class="groups">
[for priv_group_tab]
<option[if-one priv_group_tab_isdefault] selected[end]>[priv_group_tab_name]</option>
[end]
</select>
</td></tr>
<tr><th>{permissions}:</th><td><input class="privileges" type="text" name="privilegesfile" value="[priv_privileges_for_files]"></td></tr>
</table>
<h2>{priv_for_all_dirs}:</h2>
<table class="withoutborder">
<tr><th>{user}:</th><td>
<select name="userdir" class="users">
[for priv_user_tab]
<option[if-one priv_user_tab_isdefault] selected[end]>[priv_user_tab_name]</option>
[end]
</select>
</td></tr>
<tr><th>{group}: </th><td>
<select name="groupdir" class="groups">
[for priv_group_tab]
<option[if-one priv_group_tab_isdefault] selected[end]>[priv_group_tab_name]</option>
[end]
</select>
</td></tr>
<tr><th>{permissions}:</th><td><input class="privileges" type="text" name="privilegesdir" value="[priv_privileges_for_dirs]"></td></tr>
</table>
<label><input type="checkbox" name="changecurrentdir">{priv_change_current_dir}: [dir_without_slash]</label>
<input class="submit" type="submit" value="{change}">
</fieldset>
</form>
[end]

View File

@ -1,33 +1,29 @@
[if-one thread_can_create]
[is mount_page_is "subject"]<h1[is mount_page_is "info"] class="withinfo"[end]>[dir_last_subject]</h1>[end]
[is mount_page_is "info"][dir_last_info][end]
[is mount_page_is "subject"]<h1[is mount_page_is "info"] class="withinfo"[end]>[dir_last_subject]</h1>[end]
[is mount_page_is "info"][dir_last_info][end]
[if-one thread_can_create]
<ul class="itemmenu">
[if-one thread_can_create]
<li><a href="[doc_base_url][dir]createthread">{thread_create_new}</a></li>
[end]
[if-one thread_can_create]<li><a href="[doc_base_url][dir]createthread">{thread_create_new}</a></li>[end]
</ul>
[if-one thread_tab]
<table class="forum">
<tr><th>{thread_table_title}</th><th>{thread_table_author}</th><th>{thread_table_replies}</th><th>{thread_table_last_post}</th></tr>
[for thread_tab]
<tr>
<td><a href="[doc_base_url][dir][thread_tab_url]">[thread_tab_subject]</a></td>
<td class="smallfont">[thread_tab_author]</td><td class="smallfont">[thread_tab_answers]</td>
<td class="smallfont">[thread_tab_last_item_date_modification_nice] ([thread_tab_last_item_user])</td>
</tr>
[end]
</table>
[end]
[if-one thread_tab]
<table class="forum">
<tr><th>{thread_table_title}</th><th>{thread_table_author}</th><th>{thread_table_replies}</th><th>{thread_table_last_post}</th></tr>
[for thread_tab]
<tr>
<td><a href="[doc_base_url][dir][thread_tab_url]">[thread_tab_subject]</a></td>
<td class="smallfont">[thread_tab_author]</td><td class="smallfont">[thread_tab_answers]</td>
<td class="smallfont">[thread_tab_last_item_date_modification_nice] ([thread_tab_last_item_user])</td>
</tr>
[end]
</table>
[end]
[if-one thread_is]
[is mount_page_is "subject"]<h1[is mount_page_is "info"] class="withinfo"[end]>[dir_last_subject]</h1>[end]
[is mount_page_is "info"][dir_last_info][end]
[if-one dir_can_use_emacs]
<ul class="itemmenu">
<li><a href="[doc_base_url][dir]emacs">{thread_reply_in_this_thread}</a></li>

View File

@ -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.

View File

@ -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.

View File

@ -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;
}

View File

@ -31,6 +31,18 @@ void dir(Info & i)
}
void dir_without_slash(Info & i)
{
for(size_t a=0 ; a<request.dir_table.size() ; ++a)
{
HtmlEscape(i.out, request.dir_table[a]->url);
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)

View File

@ -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

View File

@ -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);
/*

View File

@ -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);
/*