3

これまでのところ、SabreDAVでACL(パーミッション)を正常に実装することはできませんでした。

私は自分のAuth、Principal、CalDAVバックエンドを使用してCodeIgniterにSabreDAVを実装しました。これは、コントローラーからの実際のコードです。

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class CalDAV extends CI_Controller {

    public function _remap() {
        $this->load->library('SabreDAV');

        $authBackend = new SabreDAV_DAV_Auth_Backend_Tank_Auth;
        $principalBackend = new Sabre_DAVACL_PrincipalBackend_Click4Time;
        $calendarBackend = new Sabre_CalDAV_Backend_Click4Time;

        // Directory tree
        $tree = array(
            new Sabre_DAVACL_PrincipalCollection($principalBackend),
            new Sabre_CalDAV_CalendarRootNode($principalBackend, $calendarBackend)
        );      

        // The object tree needs in turn to be passed to the server class
        $server = new Sabre_DAV_Server($tree);

        // You are highly encouraged to set your WebDAV server base url. Without it,
        // SabreDAV will guess, but the guess is not always correct. Putting the
        // server on the root of the domain will improve compatibility. 
        $server->setBaseUri('/caldav/');

        // Authentication plugin
        $authPlugin = new Sabre_DAV_Auth_Plugin($authBackend, 'SabreDAV');
        $server->addPlugin($authPlugin);

        // CalDAV plugin
        $caldavPlugin = new Sabre_CalDAV_Plugin();
        $server->addPlugin($caldavPlugin);

        // ACL plugin
        $aclPlugin = new Sabre_DAVACL_Custom;
        $server->addPlugin($aclPlugin);

        // Support for html frontend
        $browser = new Sabre_DAV_Browser_Plugin();
        $server->addPlugin($browser);

        $server->exec();
    }
}

パーミッションを実装するための現在の試みは、カスタムACLプラグインを介して行われました。

<?php

class Sabre_DAVACL_Custom extends Sabre_DAVACL_Plugin {

    public $allowAccessToNodesWithoutACL = false;

    private function _getCurrentUserName() {
        $authPlugin = $this->server->getPlugin('auth');
        if (is_null($authPlugin)) return null;

        return $authPlugin->getCurrentUser();
    }

    public function getACL($node) {
        $user = $this->_getCurrentUserName();
        $path = $node->getName();

        if ($path == 'calendars' || $path == 'principals' || $path == 'root') {
            return array(
                array(
                    'privilege' => '{DAV:}read',
                    'principal' => 'principals/' . $user,
                    'protected' => true,
                )
            );
        }
        else if ($path == 'calendars/' . $user) {
            return array(
                array(
                    'privilege' => '{DAV:}read',
                    'principal' => 'principals/' . $user,
                    'protected' => true,
                )
            );
        }

        return array();
    }
}

このコードは、ユーザーが自分のカレンダーを表示することを許可する2番目のチェックを除いてほとんど機能します。$nodeのフルパス名を取得できません。

これは実装するのに間違った方法かもしれませんが、これがACLを実装する方法であることを確認するためのドキュメントを見つけることができませんでした。

4

1 に答える 1

4

私は別の試みを使用しています。あなたと同じようにプラグインを拡張しましたが、getSupportedPrivilegeSet($node)代わりに置き換えました。

sabredav 1.8.6では、次のようになります。

public function getSupportedPrivilegeSet($node) {

    if (is_string($node)) {
        $node = $this->server->tree->getNodeForPath($node);
    }

    if ($node instanceof IACL) {
        $result = $node->getSupportedPrivilegeSet();

        if ($result)
            return $result;
    }

    return self::getDefaultSupportedPrivilegeSet();

}

これで、私がより便利だと思ったパスの代わりにクラスを使用できます。

class DavCalAcl extends \Sabre\DAVACL\Plugin {

public function getSupportedPrivilegeSet($node) {       
    if (is_string($node)) {
        $node = $this->server->tree->getNodeForPath($node);
    }

    if($node instanceof \Sabre\CalDAV\Calendar || $node instanceof \Sabre\CalDAV\CalendarObject) {
        return array(
            array(
                'privilege'  => '{DAV:}read',
                'aggregates' => array(
                    array(
                        'privilege' => '{DAV:}read-acl',
                        'abstract'  => true,
                    ),
                    array(
                        'privilege' => '{DAV:}read-current-user-privilege-set',
                        'abstract'  => true,
                    ),
                ),
            )
        );
    }

    if ($node instanceof \Sabre\DAVACL\IACL) {
        $result = $node->getSupportedPrivilegeSet();
        if ($result)
            return $result;
    }

    return self::getDefaultSupportedPrivilegeSet();
}

}

これは、iCalにカレンダーを読み取り専用として認識させるための現在の試みです...私はまだそこにいませんが、オブジェクトをより適切に識別するのに役立つかもしれません

ノードの絶対パスが必要な場合は、いつでもルートに移動して現在のノードを検索し、そこにたどり着いたパスを記録することができると思います。私がチェックした限り、sabredavのノードは親またはルートプロパティをサポートしていません。

[アップデート]

getACL最善の方法は、プラグインでオーバーライドすることのようです。ここでは、ノードのクラスをテストして、デフォルトのオブジェクトによって返されるものの代わりに、本当に必要なものを返すことができます(たとえば、UserCalendars-> getACL()を見てください。

オブジェクトタイプに基づく読み取り専用の強制のための私の実用的なソリューションは次のとおりです。

class DavCalAcl extends \Sabre\DAVACL\Plugin {

    /**
     * Returns the full ACL list.
     *
     * Either a uri or a DAV\INode may be passed.
     *
     * null will be returned if the node doesn't support ACLs.
     *
     * @param string|DAV\INode $node
     * @return array
     */
    public function getACL($node) {

        if (is_string($node)) {
            $node = $this->server->tree->getNodeForPath($node);
        }
        if (!$node instanceof \Sabre\DAVACL\IACL) {
            return null;
        }

        if( $node instanceof \Sabre\CalDAV\Calendar ||
            $node instanceof \Sabre\CalDAV\CalendarObject ||
            $node instanceof \Sabre\CalDAV\UserCalendars
        ) {
            $acl = array(
                array(
                    'privilege' => '{DAV:}read',
                    'principal' => $node->getOwner(),
                    'protected' => true,
                ),
            );
        } else {
            $acl = $node->getACL();         
        }

        foreach($this->adminPrincipals as $adminPrincipal) {
            $acl[] = array(
                'principal' => $adminPrincipal,
                'privilege' => '{DAV:}all',
                'protected' => true,
            );
        }
        return $acl;

    }
}
于 2013-07-10T09:56:47.177 に答える