the first part of reimplementing has been done
now we have app object and singletons are only: log logn plugin and app git-svn-id: svn://ttmath.org/publicrep/winix/trunk@628 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
544
core/request.cpp
544
core/request.cpp
@@ -15,10 +15,13 @@
|
||||
#include "postparser.h"
|
||||
#include "cookieparser.h"
|
||||
#include "log.h"
|
||||
#include "data.h"
|
||||
#include "plugin.h"
|
||||
#include "misc.h"
|
||||
#include "db.h"
|
||||
#include "functions/functionbase.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Request::Request() : char_empty(0)
|
||||
@@ -27,6 +30,13 @@ Request::Request() : char_empty(0)
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
void Request::SetConfig(Config * pconfig)
|
||||
{
|
||||
config = pconfig;
|
||||
}
|
||||
|
||||
|
||||
void Request::Init()
|
||||
{
|
||||
compress.Init();
|
||||
@@ -125,7 +135,7 @@ void Request::SetCookie(const char * name, const char * value, tm * expires)
|
||||
if( expires )
|
||||
headers << "; expires=" << DateToStrCookie(expires) << " GMT";
|
||||
|
||||
headers << "; path=/; domain=." << data.base_server << "\r\n";
|
||||
headers << "; path=/; domain=." << config->base_server << "\r\n";
|
||||
}
|
||||
|
||||
|
||||
@@ -137,7 +147,7 @@ void Request::SetCookie(const char * name, long value, tm * expires)
|
||||
if( expires )
|
||||
headers << "; expires=" << DateToStrCookie(expires) << " GMT";
|
||||
|
||||
headers << "; path=/; domain=." << data.base_server << "\r\n";
|
||||
headers << "; path=/; domain=." << config->base_server << "\r\n";
|
||||
}
|
||||
|
||||
|
||||
@@ -327,6 +337,8 @@ return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// !! czy te parsery powinny byc skladowymi Request?
|
||||
void Request::ReadParameters()
|
||||
{
|
||||
// !! wrzucic jako skladowa klasy
|
||||
@@ -339,6 +351,7 @@ void Request::ReadParameters()
|
||||
{
|
||||
log << log3 << "Request: post content type: multipart/form-data" << logend;
|
||||
|
||||
post_multi_parser.SetConfig(config);
|
||||
post_multi_parser.Parse(in, post_table, post_file_table);
|
||||
}
|
||||
else
|
||||
@@ -390,21 +403,21 @@ void Request::SendSessionCookie()
|
||||
|
||||
if( !session->puser || !session->remember_me )
|
||||
{
|
||||
SetCookie(data.http_session_id_name.c_str(), session->id);
|
||||
SetCookie(config->http_session_id_name.c_str(), session->id);
|
||||
return;
|
||||
}
|
||||
|
||||
time_t t = time(0) + data.session_remember_max_idle;
|
||||
time_t t = time(0) + config->session_remember_max_idle;
|
||||
tm * expires = localtime(&t);
|
||||
|
||||
if( !expires )
|
||||
{
|
||||
// oops, something wrong
|
||||
SetCookie(data.http_session_id_name.c_str(), session->id);
|
||||
SetCookie(config->http_session_id_name.c_str(), session->id);
|
||||
return;
|
||||
}
|
||||
|
||||
SetCookie(data.http_session_id_name.c_str(), session->id, expires);
|
||||
SetCookie(config->http_session_id_name.c_str(), session->id, expires);
|
||||
}
|
||||
|
||||
|
||||
@@ -472,15 +485,15 @@ void Request::AddDebugInfo()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// !! to powinno isc do kontrolera app
|
||||
void Request::SendPage(bool compressing, const std::string & source_ref)
|
||||
{
|
||||
const std::string * source = &source_ref;
|
||||
|
||||
bool raw = request.is_item && request.item.content_type == Item::ct_raw && request.status == WINIX_ERR_OK &&
|
||||
request.pfunction && (request.pfunction->code == FUN_CAT || request.pfunction->code == FUN_RUN);
|
||||
bool raw = is_item && item.content_type == Item::ct_raw && status == WINIX_ERR_OK &&
|
||||
pfunction && (pfunction->fun.url == "cat" || pfunction->fun.url == "run");
|
||||
|
||||
if( data.html_filter && !raw )
|
||||
if( config->html_filter && !raw )
|
||||
{
|
||||
html_filter.TrimWhite(true);
|
||||
html_filter.BreakLines(60);
|
||||
@@ -502,7 +515,7 @@ void Request::SendAll()
|
||||
{
|
||||
const std::string & source = page.str();
|
||||
Header header = h_200;
|
||||
bool compressing = data.compression && role == responder && redirect_to.empty() && x_sendfile.empty() &&
|
||||
bool compressing = config->compression && role == responder && redirect_to.empty() && x_sendfile.empty() &&
|
||||
!browser_msie && !browser_konqueror &&
|
||||
accept_encoding_parser.AcceptDeflate() && source.size() >= 512;
|
||||
|
||||
@@ -567,514 +580,7 @@ return str_empty;
|
||||
}
|
||||
|
||||
|
||||
bool Request::CanChangeUser(const Item & item, long new_user_id)
|
||||
{
|
||||
if( !session )
|
||||
// session must be set
|
||||
return false;
|
||||
|
||||
if( session->puser && session->puser->super_user )
|
||||
// super user is allowed everything
|
||||
return true;
|
||||
|
||||
if( item.user_id != new_user_id )
|
||||
// only super user can change the owner of an item
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Request::CanChangeGroup(const Item & item, long new_group_id)
|
||||
{
|
||||
if( !session )
|
||||
// session must be set
|
||||
return false;
|
||||
|
||||
if( session->puser && session->puser->super_user )
|
||||
// super user is allowed everything
|
||||
return true;
|
||||
|
||||
if( item.group_id != new_group_id )
|
||||
{
|
||||
// user is allowed to change the group only if he is an owner of the item
|
||||
// he can change only into a group in which he is a member of, or into a 'no_group'
|
||||
|
||||
if( !session->puser )
|
||||
return false;
|
||||
|
||||
if( session->puser->id != item.user_id )
|
||||
return false;
|
||||
|
||||
if( new_group_id == -1 )
|
||||
return true;
|
||||
|
||||
if( !session->puser->IsMemberOf(new_group_id) )
|
||||
return false;
|
||||
|
||||
// is logged, is the owner of the item, is the member of the new group
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Request::CanChangePrivileges(const Item & item, int new_priv)
|
||||
{
|
||||
if( !session )
|
||||
// session must be set
|
||||
return false;
|
||||
|
||||
if( session->puser && session->puser->super_user )
|
||||
// super user is allowed everything
|
||||
return true;
|
||||
|
||||
if( item.privileges != new_priv )
|
||||
{
|
||||
// the owner of an item is allowed to change the privileges
|
||||
|
||||
if( !session->puser )
|
||||
return false;
|
||||
|
||||
if( session->puser->id != item.user_id )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Request::HasAccess(const Item & item, int mask)
|
||||
{
|
||||
if( !session )
|
||||
// session must be set
|
||||
return false;
|
||||
|
||||
if( session->puser && session->puser->super_user )
|
||||
// super user is allowed everything
|
||||
return true;
|
||||
|
||||
if( session->puser && session->puser->id == item.user_id )
|
||||
{
|
||||
// the owner
|
||||
return ((item.privileges >> 6) & mask) == mask;
|
||||
}
|
||||
|
||||
if( session->puser && session->puser->IsMemberOf(item.group_id) )
|
||||
{
|
||||
// group
|
||||
return ((item.privileges >> 3) & mask) == mask;
|
||||
}
|
||||
|
||||
// others
|
||||
|
||||
return (item.privileges & mask) == mask;
|
||||
}
|
||||
|
||||
|
||||
bool Request::HasReadAccess(const Item & item)
|
||||
{
|
||||
return HasAccess(item, 4);
|
||||
}
|
||||
|
||||
|
||||
bool Request::HasWriteAccess(const Item & item)
|
||||
{
|
||||
return HasAccess(item, 2);
|
||||
}
|
||||
|
||||
|
||||
bool Request::HasReadWriteAccess(const Item & item)
|
||||
{
|
||||
return HasAccess(item, 6); // r+w
|
||||
}
|
||||
|
||||
|
||||
bool Request::HasReadExecAccess(const Item & item)
|
||||
{
|
||||
if( session && session->puser && session->puser->super_user )
|
||||
{
|
||||
// there must be at least one 'x' (for the root)
|
||||
|
||||
return (item.privileges & 0111) != 0;
|
||||
}
|
||||
|
||||
return HasAccess(item, 5); // r+x
|
||||
}
|
||||
|
||||
|
||||
bool Request::HasReadExecAccessForRoot(const Item & item)
|
||||
{
|
||||
// there must be at least one 'x' (for the root)
|
||||
|
||||
return (item.privileges & 0111) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Request::HasReadExecAccessToPath(long dir_id)
|
||||
{
|
||||
while( true )
|
||||
{
|
||||
Item * pdir = data.dirs.GetDir(dir_id);
|
||||
|
||||
if( !pdir )
|
||||
return false;
|
||||
|
||||
if( !HasReadExecAccess(*pdir) )
|
||||
return false;
|
||||
|
||||
dir_id = pdir->parent_id;
|
||||
|
||||
if( dir_id == -1 )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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.pmount || data.mounts.pmount->type != 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;
|
||||
|
||||
if( !data.mounts.pmount->IsPar(Mount::par_createthread_on) )
|
||||
return true;
|
||||
|
||||
if( data.mounts.pmount->IsArg(Mount::par_createthread_on, request.dir_table.size()) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// returning true if we can create a ticket in the current directory
|
||||
bool Request::CanCreateTicket(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.pmount || data.mounts.pmount->type != Mount::ticket )
|
||||
return false;
|
||||
|
||||
|
||||
// checking for par_createticket_on mount option
|
||||
|
||||
if( !check_root && session && session->puser && session->puser->super_user )
|
||||
// super can create tickets regardless of the createticket_on option
|
||||
return true;
|
||||
|
||||
if( !data.mounts.pmount->IsPar(Mount::par_createticket_on) )
|
||||
return true;
|
||||
|
||||
if( data.mounts.pmount->IsArg(Mount::par_createticket_on, request.dir_table.size()) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Request::CanEditTicket()
|
||||
{
|
||||
// not logged users cannot edit tickets
|
||||
if( !request.session->puser )
|
||||
return false;
|
||||
|
||||
if( request.dir_table.empty() )
|
||||
return false;
|
||||
|
||||
if( request.is_item || !request.is_ticket )
|
||||
return false;
|
||||
|
||||
if( !HasWriteAccess(*request.dir_table.back()) )
|
||||
return false;
|
||||
|
||||
if( !data.mounts.pmount || data.mounts.pmount->type != Mount::ticket )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Request::CanRemove(const Item & item)
|
||||
{
|
||||
// !! temporarily (we're waiting for the sticky bit to be implemented)
|
||||
// not logged users cannot remove anything
|
||||
if( !request.session->puser )
|
||||
return false;
|
||||
|
||||
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.pmount->IsPar(Mount::par_only_root_remove) )
|
||||
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;
|
||||
|
||||
if( !data.mounts.pmount->IsPar(Mount::par_emacs_on) )
|
||||
return true;
|
||||
|
||||
if( data.mounts.pmount->IsArg(Mount::par_emacs_on, request.dir_table.size()) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
if( !data.mounts.pmount->IsPar(Mount::par_mkdir_on) )
|
||||
return true;
|
||||
|
||||
if( data.mounts.pmount->IsArg(Mount::par_mkdir_on, request.dir_table.size()) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Request::CanUseUpload(const Item & item, bool check_root)
|
||||
{
|
||||
// you can use 'upload' only in a directory
|
||||
if( item.type != Item::dir )
|
||||
return false;
|
||||
|
||||
// we must know where to store the file
|
||||
if( !data.mounts.pmount )
|
||||
return false;
|
||||
|
||||
if( data.mounts.pmount->fs == Mount::simplefs && data.auth_simplefs_dir.empty() )
|
||||
{
|
||||
log << log1 << "Request: can't use upload function, auth_simplefs_dir must be set in the config file" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( data.mounts.pmount->fs == Mount::hashfs && data.auth_hashfs_dir.empty() )
|
||||
{
|
||||
log << log1 << "Request: can't use upload function, auth_hashfs_dir must be set in the config file" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( data.auth_tmp_dir.empty() )
|
||||
{
|
||||
log << log1 << "Request: can't use upload function, auth_tmp_dir must be set in the config file" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !check_root && request.session->puser && request.session->puser->super_user )
|
||||
// super user can use upload everywhere
|
||||
return true;
|
||||
|
||||
if( !request.HasWriteAccess(item) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Request::CanUseHtml(long user_id)
|
||||
{
|
||||
return CanUse(user_id, "allow_html");
|
||||
}
|
||||
|
||||
|
||||
bool Request::CanUseBBCode(long user_id)
|
||||
{
|
||||
// logged users can use bbcode
|
||||
return (user_id != -1);
|
||||
}
|
||||
|
||||
|
||||
bool Request::CanUseRaw(long user_id)
|
||||
{
|
||||
return CanUse(user_id, "allow_raw");
|
||||
}
|
||||
|
||||
|
||||
bool Request::CanUse(long user_id, const char * group_name)
|
||||
{
|
||||
User * puser = data.users.GetUser(user_id);
|
||||
|
||||
if( !puser )
|
||||
return false;
|
||||
|
||||
if( puser->super_user )
|
||||
return true;
|
||||
|
||||
long group = data.groups.GetGroupId(group_name);
|
||||
|
||||
if( group == -1 )
|
||||
// there is no such a group
|
||||
return false;
|
||||
|
||||
if( puser->IsMemberOf(group) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool Request::MakePathSimpleFs(std::string & path, long dir_id, bool create_dir)
|
||||
{
|
||||
if( data.auth_simplefs_dir.empty() )
|
||||
{
|
||||
log << log1 << "Request: auth_simplefs_dir is not set in the config file" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !data.dirs.MakePath(dir_id, path) )
|
||||
return false;
|
||||
|
||||
if( create_dir && !CreateDirs(data.auth_simplefs_dir, path, 0755) )
|
||||
return false;
|
||||
|
||||
path.insert(0, data.auth_simplefs_dir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// the path depends on id
|
||||
bool Request::MakePathHashFs(std::string & path, long id, bool create_dir)
|
||||
{
|
||||
char buffer[50];
|
||||
char * hash = buffer;
|
||||
|
||||
// get 'id' as hexadecimal
|
||||
buffer[0] = '0';
|
||||
sprintf(buffer+1, "%lx", (unsigned long)id);
|
||||
|
||||
path = data.auth_hashfs_dir;
|
||||
if( path.empty() )
|
||||
{
|
||||
log << log1 << "Request: auth_hashfs_dir is not set in the config file" << logend;
|
||||
return false;
|
||||
}
|
||||
|
||||
path += '/';
|
||||
|
||||
// make sure that the length is even
|
||||
if( (strlen(hash) & 1) != 0 )
|
||||
hash = buffer + 1; // the first character was zero
|
||||
|
||||
// creating dirs without the last part
|
||||
// the last part is a part of a file
|
||||
for(size_t i=0 ; hash[i] != 0 ; i+=2)
|
||||
{
|
||||
path += hash[i];
|
||||
path += hash[i+1];
|
||||
|
||||
if( hash[i+2] != 0 )
|
||||
{
|
||||
if( create_dir && !CreateDir(path, 0755) )
|
||||
return false;
|
||||
|
||||
path += '/';
|
||||
}
|
||||
}
|
||||
|
||||
// one character more to make sure the path is unique
|
||||
// (we can have a directory without the character)
|
||||
path += "_";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// making a complete path to a static file
|
||||
bool Request::MakePath(const Item & item, std::string & path, bool create_dir)
|
||||
{
|
||||
bool res;
|
||||
|
||||
Mount * pmount = data.mounts.CalcMount(item.parent_id);
|
||||
|
||||
if( !pmount || pmount->fs == Mount::simplefs )
|
||||
{
|
||||
res = MakePathSimpleFs(path, item.parent_id, create_dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = MakePathHashFs(path, item.id, create_dir);
|
||||
}
|
||||
|
||||
if( res )
|
||||
path += item.url;
|
||||
else
|
||||
path.clear();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Request::MakePath(Item & item, bool create_dir)
|
||||
{
|
||||
return MakePath(item, item.auth_path, create_dir);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user