summaryrefslogblamecommitdiffstats
path: root/app/class/object.class.php
blob: cfc452cbeb89720db82a9c4cb65c163fd7d989e0 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

     













                                                                     
                                         
                                    





                                         

                                          


                  
                                                                   



























                                                                   
                                  



                           


                                  

                                          
                         


















                                                                                                







                                        

                                                              







































                                                                                                                                          

                                                              











































                                                                                                                















                                                                                                                







                                                                                                                                                     
     

      









                                                         











                                                                                              







                                                     
                                                   




                                     







                                                               

      










                                                













                                                                                                    

      
                                                                 





















































































































































































































































































































                                                                

 














                                                                  
  
<?php

/*
 * SCROTT Copyright (C) 2016 Malf Furious
 *
 * Scrott is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * Scrott is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
 * License for more details.
 */

require_once "class/framework.class.php";
require_once "class/user.class.php";

/*
 * Base class for Scrott database objects
 */
abstract class Object extends Framework
{
    var $DEFAULT_OBJECT_PERMISSIONS = 120;

    /*
     * Constructor
     */
    function __construct($childTable = "object", $childCols = null)
    {
        $this->db = $this->getDbConnection();

        $this->table = "object";
        $this->cols = array(
            "guid",
            "perms",
            "owner",
            "parent",
            "name",
            "timeCreated",
            "timeUpdated",
            "type"
        );

        $this->childTable = $this->db->esc($childTable);
        $this->childCols = array();

        if (is_array($childCols))
        {
            foreach ($childCols as $col)
                $this->childCols[] = $this->db->esc($col);
        }
    }

    /*
     * Populate this object with data from the DB with a given GUID
     */
    function loadObj($guid = null)
    {
        if (is_null($guid))
            return;

        if (!$this->isGUID($guid))
            return;

        $escdGuid = $this->db->esc($guid);

        /* Base fields */
        $query = "SELECT * FROM `" . $this->table . "` WHERE `guid` = '" . $escdGuid . "'";
        $result = $this->db->query($query)[0];

        foreach ($this->cols as $col)
        {
            if (isset($result[$col]))
                $this->$col = $result[$col];
        }

        /* Child Table fields */
        $query = "SELECT * FROM `" . $this->childTable . "` WHERE `guid` = '" . $escdGuid . "'";
        $result = $this->db->query($query)[0];

        foreach ($this->childCols as $col)
        {
            if (isset($result[$col]))
                $this->$col = $result[$col];
        }
    }

    /*
     * Write this object to the database
     */
    function saveObj()
    {
        if (isset($this->guid))
        {
            $this->timeUpdated = $this->getCurrentTimestamp();

            /* Update Base */
            $updateStr = "";

            foreach ($this->cols as $col)
            {
                if (!isset($this->$col))
                    continue;

                $updateStr .= "`" . $col . "` = '" . $this->db->esc($this->$col) . "', ";
            }

            if (strlen($updateStr) > 0)
            {
                $updateStr = substr($updateStr, 0, -2); // remove ", " from the end
                $query = "UPDATE `" . $this->table . "` SET " . $updateStr . " WHERE `guid` = '" . $this->db->esc($this->guid) . "'";
                $this->db->query($query);
            }

            /* Update Child */
            $updateStr = "";

            foreach ($this->childCols as $col)
            {
                if (!isset($this->$col))
                    continue;

                $updateStr .= "`" . $col . "` = '" . $this->db->esc($this->$col) . "', ";
            }

            if (strlen($updateStr) > 0)
            {
                $updateStr = substr($updateStr, 0, -2); // remove ", " from the end
                $query = "UPDATE `" . $this->childTable . "` SET " . $updateStr . " WHERE `guid` = '" . $this->db->esc($this->guid) . "'";
                $this->db->query($query);
            }
        }

        else
        {
            $this->guid = $this->getNewGUID();
            $this->timeCreated = $this->getCurrentTimestamp();
            $this->timeUpdated = $this->timeCreated;

            /* Insert Base */
            $colsStr = "";
            $valsStr = "";

            foreach ($this->cols as $col)
            {
                if (!isset($this->$col))
                    continue;

                $colsStr .= "`" . $col . "`, ";
                $valsStr .= "'" . $this->db->esc($this->$col) . "', ";
            }

            if (strlen($colsStr) > 0)
            {
                $colsStr = substr($colsStr, 0, -2); // remove ", "
                $valsStr = substr($valsStr, 0, -2);
                $query = "INSERT INTO `" . $this->table . "` (" . $colsStr . ") VALUES (" . $valsStr . ")";
                $this->db->query($query);
            }

            /* Insert Child */
            $colsStr = "";
            $valsStr = "";

            foreach ($this->childCols as $col)
            {
                if (!isset($this->$col))
                    continue;

                $colsStr .= "`" . $col . "`, ";
                $valsStr .= "'" . $this->db->esc($this->$col) . "', ";
            }

            if (strlen($colsStr) > 0)
            {
                $colsStr = substr($colsStr, 0, -2); // remove ", "
                $valsStr = substr($valsStr, 0, -2);
                $query = "INSERT INTO `" . $this->childTable . "` (" . $colsStr . ") VALUES (" . $valsStr . ")";
                $this->db->query($query);
            }
        }
    }

    /*
     * Remove this object from the database
     */
    function delObj()
    {
        if (!isset($this->guid))
            return;

        /* Delete Base */
        $query = "DELETE FROM `" . $this->table . "` WHERE `guid` = '" . $this->db->esc($this->guid) . "'";
        $this->db->query($query);

        /* Delete Child */
        $query = "DELETE FROM `" . $this->childTable . "` WHERE `guid` = '" . $this->db->esc($this->guid) . "'";
        $this->db->query($query);

        /* obj_member garbage collection */
        $query = "DELETE FROM `obj_member` WHERE `guid` = '" . $this->db->esc($this->guid) . "' OR `member` = '" . $this->db->esc($this->guid) . "'";
        $this->db->query($query);

        /* msg_read garbage collection */
        $query = "DELETE FROM `msg_read` WHERE `guid` = '" . $this->db->esc($this->guid) . "' OR `user` = '" . $this->db->esc($this->guid) . "'";
        $this->db->query($query);
    }

    /*
     * Get current timestamp for object database purposes
     */
    function getCurrentTimestamp()
    {
        $query = "SELECT now() AS stamp";
        $result = $this->db->query($query);
        return $result[0]['stamp'];
    }

    /*
     * Check whether given GUID exists
     */
    function isGUID($guid)
    {
        $query = "SELECT `guid` FROM `object` WHERE `guid` = '" . $this->db->esc($guid) . "'";
        $result = $this->db->query($query);

        if (count($result) > 0)
            return true;

        return false;
    }

    /*
     * Get a new, unique GUID for a new system object
     */
    function getNewGUID()
    {
        do
        {
            $guid = substr($this->getBlob(), 0, 8);
        }
        while ($this->isGUID($guid));

        return $guid;
    }

    /*
     * Get a random sha256 blob
     */
    function getBlob()
    {
        return hash("sha256", openssl_random_pseudo_bytes(64));
    }

    /*
     * Get a user object for this object's owner
     */
    function getOwner()
    {
        if (isset($this->owner))
            return new User($this->owner);

        return null;
    }

    /*
     * Get an array of all members of this object
     */
    function getMembers()
    {
        $query = "SELECT member FROM obj_member WHERE guid = '" . $this->db->esc($this->guid) . "'";
        $result = $this->db->query($query);

        $members = array();

        foreach ($result as $m)
            $members[] = new User($m['member']);

        return $members;
    }

    /*
     * Check if given user (or group) is the owner of this object
     */
    function isOwner($ug)
    {
        return $this->getOwner()->guid == $ug->guid;
    }

    /*
     * Check if given user (or group) is a member of this object
     */
    function isMember($ug)
    {
        foreach ($this->getMembers() as $member)
        {
            if ($member->guid == $ug->guid)
                return true;
        }

        return false;
    }

    /*
     * Check if given user has permissions for this object
     */
    function canAccess($user)
    {
        if ($user->admin)
            return true;

        if ($this->isOwner($user))
            return true;

        if ($this->isMember($user))
            return true;

        if ($this->perms & 0x004) // accessible by public
            return true;

        if ($this->parent != "")
        {
            $parent = new DBObject($this->parent);

            if ($parent->canAccessSub($user))
                return true;
        }
        else if ($this->owner != $this->guid)
        {
            $owner = new DBObject($this->owner);

            if ($owner->canAccessSub($user))
                return true;
        }

        return false;
    }

    /*
     * Check if given user has permissions for this object
     */
    function canModify($user)
    {
        if ($user->admin)
            return true;

        if ($this->isOwner($user))
            return true;

        if ($this->isMember($user) && $this->perms & 0x100)
            return true;

        if ($this->parent != "")
        {
            $parent = new DBObject($this->parent);

            if ($parent->canModifySub($user))
                return true;
        }
        else if ($this->owner != $this->guid)
        {
            $owner = new DBObject($this->owner);

            if ($owner->canModifySub($user))
                return true;
        }

        return false;
    }

    /*
     * Check if given user has permissions for this object
     */
    function canModifyMembers($user)
    {
        if ($user->admin)
            return true;

        if ($this->isOwner($user))
            return true;

        if ($this->isMember($user) && $this->perms & 0x080)
            return true;

        if ($this->parent != "")
        {
            $parent = new DBObject($this->parent);

            if ($parent->canModifySubMembers($user))
                return true;
        }
        else if ($this->owner != $this->guid)
        {
            $owner = new DBObject($this->owner);

            if ($owner->canModifySubMembers($user))
                return true;
        }

        return false;
    }

    /*
     * Check if given user has permissions for this object
     */
    function canModifyPermissions($user)
    {
        if ($user->admin)
            return true;

        if ($this->isOwner($user))
            return true;

        if ($this->parent != "")
        {
            $parent = new DBObject($this->parent);

            if ($parent->canModifySubPermissions($user))
                return true;
        }
        else if ($this->owner != $this->guid)
        {
            $owner = new DBObject($this->owner);

            if ($owner->canModifySubPermissions($user))
                return true;
        }

        return false;
    }

    /*
     * Check if given user has permissions for this object
     */
    function canAccessSub($user)
    {
        if ($user->admin)
            return true;

        if ($this->isOwner($user))
            return true;

        if ($this->isMember($user) && $this->perms & 0x040)
            return true;

        if ($this->perms & 0x002) // accessible by public
            return true;

        if ($this->parent != "")
        {
            $parent = new DBObject($this->parent);

            if ($parent->canAccessSub($user))
                return true;
        }
        else if ($this->owner != $this->guid)
        {
            $owner = new DBObject($this->owner);

            if ($owner->canAccessSub($user))
                return true;
        }

        return false;
    }

    /*
     * Check if given user has permissions for this object
     */
    function canCreateSub($user)
    {
        if ($user->admin)
            return true;

        if ($this->isOwner($user))
            return true;

        if ($this->isMember($user) && $this->perms & 0x020)
            return true;

        if ($this->perms & 0x001) // accessible by public
            return true;

        if ($this->parent != "")
        {
            $parent = new DBObject($this->parent);

            if ($parent->canCreateSub($user))
                return true;
        }
        else if ($this->owner != $this->guid)
        {
            $owner = new DBObject($this->owner);

            if ($owner->canCreateSub($user))
                return true;
        }

        return false;
    }

    /*
     * Check if given user has permissions for this object
     */
    function canModifySub($user)
    {
        if ($user->admin)
            return true;

        if ($this->isOwner($user))
            return true;

        if ($this->isMember($user) && $this->perms & 0x010)
            return true;

        if ($this->parent != "")
        {
            $parent = new DBObject($this->parent);

            if ($parent->canModifySub($user))
                return true;
        }
        else if ($this->owner != $this->guid)
        {
            $owner = new DBObject($this->owner);

            if ($owner->canModifySub($user))
                return true;
        }

        return false;
    }

    /*
     * Check if given user has permissions for this object
     */
    function canModifySubMembers($user)
    {
        if ($user->admin)
            return true;

        if ($this->isOwner($user))
            return true;

        if ($this->isMember($user) && $this->perms & 0x008)
            return true;

        if ($this->parent != "")
        {
            $parent = new DBObject($this->parent);

            if ($parent->canModifySubMembers($user))
                return true;
        }
        else if ($this->owner != $this->guid)
        {
            $owner = new DBObject($this->owner);

            if ($owner->canModifySubMembers($user))
                return true;
        }

        return false;
    }

    /*
     * Check if given user has permissions for this object
     */
    function canModifySubPermissions($user)
    {
        if ($user->admin)
            return true;

        if ($this->isOwner($user))
            return true;

        if ($this->parent != "")
        {
            $parent = new DBObject($this->parent);

            if ($parent->canModifySubPermissions($user))
                return true;
        }
        else if ($this->owner != $this->guid)
        {
            $owner = new DBObject($this->owner);

            if ($owner->canModifySubPermissions($user))
                return true;
        }

        return false;
    }
}

/*
 * Concrete Database Object which can be used in a polymorphic way
 */
class DBObject extends Object
{
    /*
     * Constructor
     */
    function __construct($guid = null)
    {
        parent::__construct();
        $this->loadObj($guid);
    }
}

?>