Skip to content

Commit

Permalink
Merge pull request #1 from owncloud/group-manager
Browse files Browse the repository at this point in the history
Implement group backend
  • Loading branch information
Vincent Petry authored Dec 13, 2016
2 parents dad0d07 + d64a029 commit 4ae443d
Show file tree
Hide file tree
Showing 13 changed files with 1,181 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,6 @@ nbproject
# Mac OS
.DS_Store

# test files
clover.xml

59 changes: 59 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
language: php
php:
- 5.6
- 7.0
- 7.1

env:
global:
- CORE_BRANCH=master
- APP_NAME=customgroups
matrix:
- DB=sqlite

branches:
only:
- master

before_install:
- wget https://github.com/raw/owncloud/administration/master/travis-ci/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB

# Add some output debugging information
- cd ../core
- ./occ check
- ./occ status
- ./occ app:list

script:
- cd apps/$APP_NAME/

# Test the app
- sh -c "if [ '$JSTESTS' != '1' -a '$CODECHECK' = '1' ]; then make test-codecheck; fi"
- sh -c "if [ '$JSTESTS' != '1' -a '$CODECHECK' = '1' ]; then make test-codecheck; fi"
- sh -c "if [ '$JSTESTS' != '1' -a '$CODECHECK' = '2' ]; then make test-codecheck-deprecations; fi"

# Run phpunit tests
- sh -c "if [ '$JSTESTS' != '1' -a '$CODECHECK' != '1' -a '$CODECHECK' != '2' ]; then make test-php; fi"

# Create and upload coverage report
- sh -c "if [ '$JSTESTS' != '1' -a '$CODECHECK' != '1' -a '$CODECHECK' != '2' ]; then make test-upload-coverage; fi"

# Run Javascript unit tests
- make test-js

matrix:
include:
- php: 5.6
env: DB=mysql
- php: 5.6
env: DB=pgsql
- php: 5.6
env: DB=mysql;CODECHECK=1
- php: 5.6
env: DB=mysql;CODECHECK=2
- php: 5.6
env: DB=mysql;JSTESTS=1
allow_failures:
- env: DB=mysql;CODECHECK=2
fast_finish: true
50 changes: 45 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
# Makefile for building the project
# Makefile

OWNCLOUD_PATH=$(CURDIR)/../..
OCC=$(OWNCLOUD_PATH)/occ
PHPUNIT=$(OWNCLOUD_PATH)/lib/composer/phpunit/phpunit/phpunit

app_name=customgroups
project_dir=$(CURDIR)/../$(app_name)
build_dir=$(CURDIR)/build
doc_files=README.md
src_files=
src_dirs=appinfo controller css img js l10n lib templates
src_dirs=appinfo lib
all_src=$(src_files) $(src_dirs) $(doc_files)
market_dir=$(build_dir)/market

.PHONY: all
all: dist market
all: market

.PHONE: market
market: dist
cd $(build_dir); tar cvzf $(app_name).tar.gz $(app_name)
rm -Rf $(market_dir); mkdir -p $(market_dir)
mv $(build_dir)/$(app_name).tar.gz $(market_dir)


$(build_dir)/$(app_name):
rm -Rf $@; mkdir -p $@
cp -R $(all_src) $@
Expand All @@ -29,6 +33,42 @@ dist: $(build_dir)/$(app_name)
distclean: clean

.PHONY: clean
clean:
clean: clean-test
rm -rf $(build_dir)

.PHONY: clean-test
clean-test:
rm tests/unit/clover.xml
rm tests/unit/*.phar

.PHONY: test-syntax
test-syntax:
for F in $(shell find . -name \*.php); do \
php -l "$$F" || exit $?; \
done

.PHONY: test-codecheck
test-codecheck: test-syntax
$(OCC) app:check-code $(app_name) -c private -c strong-comparison

.PHONY: test-codecheck-deprecations
test-codecheck-deprecations:
$(OCC) app:check-code $(app_name) -c deprecation

.PHONY: test-php
test-php: test-syntax
$(OCC) app:enable $(app_name)
cd tests/unit && $(PHPUNIT) --configuration phpunit.xml

.PHONY: test-upload-coverage
test-upload-coverage:
cd tests/unit && wget https://scrutinizer-ci.com/ocular.phar; php ocular.phar code-coverage:upload --format=php-clover clover.xml

.PHONY: test-js
test-js:
@echo No JS unit tests currently
#cd tests/js && npm install --deps; node_modules/karma/bin/karma start karma.config.js --single-run;

.PHONY: test
test: test-codecheck test-codecheck-deprecations test-php test-js

3 changes: 2 additions & 1 deletion appinfo/Migrations/Version20161209151129.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ private function createGroupsTable(Schema $schema) {
$table->addColumn('group_id', 'integer', [
'autoincrement' => true,
'unsigned' => true,
'notnull' => true,
'length' => 4,
]);
$table->addColumn('uri', 'string', [
Expand All @@ -42,8 +43,8 @@ private function createMembersTable(Schema $schema) {
$prefix = $this->connection->getPrefix();
$table = $schema->createTable("${prefix}custom_group_member");
$table->addColumn('group_id', 'integer', [
'autoincrement' => true,
'unsigned' => true,
'notnull' => true,
'length' => 4,
]);
$table->addColumn('user_id', 'string', [
Expand Down
2 changes: 2 additions & 0 deletions appinfo/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@
*
*/

$app = new \OCA\CustomGroups\Application();
$app->registerGroupBackend();
2 changes: 2 additions & 0 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<info>
<id>customgroups</id>
<name>User-defined custom groups</name>
<namespace>CustomGroups</namespace>
<description>Let users create and manage custom groups for sharing.</description>
<website>https://github.com/owncloud/customgroups/</website>
<bugs>https://github.com/owncloud/customgroups/issues</bugs>
Expand All @@ -11,6 +12,7 @@
<version>0.1</version>
<types>
<authentication/>
<dav/>
</types>
<use-migrations>true</use-migrations>
<dependencies>
Expand Down
38 changes: 38 additions & 0 deletions lib/Application.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php
/**
* @author Vincent Petry <pvince81@owncloud.com>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/

namespace OCA\CustomGroups;

use OCP\AppFramework\App;

class Application extends App {
public function __construct (array $urlParams = array()) {
parent::__construct('customgroups', $urlParams);
}

/**
* Register the group manager
*/
public function registerGroupBackend() {
$backend = $this->getContainer()->query('\OCA\CustomGroups\CustomGroupsBackend');
$this->getContainer()->getServer()->getGroupManager()->addBackend($backend);
}
}
176 changes: 176 additions & 0 deletions lib/CustomGroupsBackend.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
<?php
/**
* @author Vincent Petry <pvince81@owncloud.com>
*
* @copyright Copyright (c) 2016, ownCloud GmbH.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/

namespace OCA\CustomGroups;

/**
* Group backend for custom groups for integration with core
*/
class CustomGroupsBackend implements \OCP\GroupInterface {

const GROUP_ID_PREFIX = 'customgroup_';

/**
* @var CustomGroupsDatabaseHandler
*/
private $handler;

public function __construct(
CustomGroupsDatabaseHandler $handler
) {
$this->handler = $handler;
}

/**
* Checks if backend implements actions.
*
* @param int $actions bitwise-or'ed actions
* @return boolean
*/
public function implementsActions($actions) {
return ($actions & self::GROUP_DETAILS) !== 0;
}

/**
* Checks whether the user is member of a group or not.
*
* @param string $uid uid of the user
* @param string $gid gid of the group
* @return bool
*/
public function inGroup($uid, $gid) {
$numericGroupId = $this->extractNumericGroupId($gid);
if (is_null($numericGroupId)) {
return false;
}

return $this->handler->inGroup($uid, $numericGroupId);
}

/**
* Get all groups a user belongs to
*
* @param string $uid Name of the user
* @return array an array of group names
*/
public function getUserGroups($uid) {
$groups = $this->handler->getUserGroups($uid);
return array_map(function($numericGroupId) {
return $this->formatGroupId($numericGroupId);
}, $groups);
}

/**
* Returns a list with all groups.
* The search string will match any part of the display name
* field.
*
* @param string $search search string
* @param int $limit limit or -1 to disable
* @param int $offset offset
* @return array an array of group names
*
*/
public function getGroups($search = '', $limit = -1, $offset = 0) {
$groups = $this->handler->searchGroups($search, $limit, $offset);
return array_map(function($groupInfo) {
return $this->formatGroupId($groupInfo['group_id']);
}, $groups);
}

/**
* Checks if a group exists
*
* @param string $gid group id
* @return bool true if the group exists, false otherwise
*/
public function groupExists($gid) {
return !is_null($this->getGroupDetails($gid));
}

/**
* Returns the info for a given group.
*
* @param string $gid group id
* @return array|null group info or null if not found
*/
public function getGroupDetails($gid) {
$numericGroupId = $this->extractNumericGroupId($gid);
if (is_null($numericGroupId)) {
return null;
}

$group = $this->handler->getGroup($numericGroupId);
if (is_null($group)) {
return null;
}
return [
'gid' => $this->formatGroupId($group['group_id']),
'displayName' => $group['display_name'],
];
}

/**
* Returns a list of all users in a group
*
* @param string $gid
* @param string $search
* @param int $limit
* @param int $offset
* @return array an array of user ids
*/
public function usersInGroup($gid, $search = '', $limit = -1, $offset = 0) {
// not exposed to regular user management
return [];
}

/**
* Extracts the numeric id from the group id string with
* the format "customgroup_$id"
*
* @param string $gid group id in format "customgroup_$id"
* @return extracted numeric id or null if the format did not match
*/
private function extractNumericGroupId($gid) {
$len = strlen(self::GROUP_ID_PREFIX);
$prefixPart = substr($gid, 0, $len);
if ($prefixPart !== self::GROUP_ID_PREFIX) {
return null;
}

$numericPart = substr($gid, $len);

if (!is_numeric($numericPart)) {
return null;
}
return (int)$numericPart;
}

/**
* Formats the given numeric group id to a string
*
* @param int $numericId numeric group id
* @return formatted id in format "customgroup_$id"
*/
private function formatGroupId($numericId) {
return self::GROUP_ID_PREFIX . $numericId;
}
}
Loading

0 comments on commit 4ae443d

Please sign in to comment.