diff options
-rw-r--r-- | CONTRIBUTING.md | 32 | ||||
-rw-r--r-- | core/css/multiselect.css | 27 | ||||
-rw-r--r-- | core/js/multiselect.js | 231 | ||||
-rw-r--r-- | core/templates/logout.php | 1 | ||||
-rwxr-xr-x | settings/admin.php | 10 | ||||
-rw-r--r-- | settings/ajax/disableapp.php | 1 | ||||
-rw-r--r-- | settings/ajax/enableapp.php | 1 | ||||
-rw-r--r-- | settings/ajax/setsecurity.php | 13 | ||||
-rw-r--r-- | settings/js/admin.js | 4 | ||||
-rw-r--r-- | settings/js/users.js | 5 | ||||
-rw-r--r-- | settings/routes.php | 4 | ||||
-rw-r--r-- | settings/templates/admin.php | 27 |
12 files changed, 294 insertions, 62 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000000..a27c3e81ccc --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,32 @@ +## Submitting issues + +If you have questions about how to use ownCloud, please direct these to the [mailing list][mailinglist] or our [forum][forum]. We are also available on [IRC][irc]. + +### Guidelines +* Search the existing issues first, it's likely that your issue was already reported. +* Ensure that you're in the right repository, apps are likely to be developed in the apps repo and our client in the mirall repo. +* An example demonstrating your problem, is likely to get an answer faster. + +If your issue appears to be a bug, and hasn't been reported, open a new issue. **Please ensure that you're in the right repository. This is *only* for bugs in the core code**. For other reports: Please check if there is a [better suited repository](https://github.com/owncloud), like our [app](https://github.com/owncloud/apps) or [mirall (desktop client)](https://github.com/owncloud/mirall) repo. + +Help us to maximize the effort we can spend fixing issues and adding new features, by not reporting duplicate issues. + +[mailinglist]: https://mail.kde.org/mailman/listinfo/owncloud +[forum]: http://forum.owncloud.org/ +[irc]: http://webchat.freenode.net/?channels=owncloud&uio=d4 + +## Contributing to Source Code + +Thanks for wanting to contribute source code to ownCloud. That's great! + +Before we're able to merge your code into the ownCloud core, you need to sign our [Contributor Agreement][agreement]. + +Please read the [Developer Manuals][devmanual] to get useful info like how to create your first application or test the ownCloud code. + +[agreement]: http://owncloud.org/about/contributor-agreement/ +[devmanual]: http://owncloud.org/dev/ + +## Translations +Please submit translations via [Transifex][transifex]. + +[transifex]: https://www.transifex.com/projects/p/owncloud/ diff --git a/core/css/multiselect.css b/core/css/multiselect.css index 99f0e039334..31c8ef88eb9 100644 --- a/core/css/multiselect.css +++ b/core/css/multiselect.css @@ -5,15 +5,25 @@ ul.multiselectoptions { background-color:#fff; border:1px solid #ddd; - border-bottom-left-radius:.5em; - border-bottom-right-radius:.5em; border-top:none; box-shadow:0 1px 1px #ddd; padding-top:.5em; position:absolute; + max-height: 20em; + overflow-y: auto; z-index:49; } + ul.multiselectoptions.down { + border-bottom-left-radius:.5em; + border-bottom-right-radius:.5em; + } + + ul.multiselectoptions.up { + border-top-left-radius:.5em; + border-top-right-radius:.5em; + } + ul.multiselectoptions>li { overflow:hidden; white-space:nowrap; @@ -30,11 +40,20 @@ div.multiselect.active { background-color:#fff; + position:relative; + z-index:50; + } + + div.multiselect.up { + border-top:0 none; + border-top-left-radius:0; + border-top-right-radius:0; + } + + div.multiselect.down { border-bottom:none; border-bottom-left-radius:0; border-bottom-right-radius:0; - position:relative; - z-index:50; } div.multiselect>span:first-child { diff --git a/core/js/multiselect.js b/core/js/multiselect.js index c4fd74b0475..623c6e0f7e1 100644 --- a/core/js/multiselect.js +++ b/core/js/multiselect.js @@ -1,20 +1,44 @@ +/** + * @param 'createCallback' A function to be called when a new entry is created. Two arguments are supplied to this function: + * The select element used and the value of the option. If the function returns false addition will be cancelled. If it returns + * anything else it will be used as the value of the newly added option. + * @param 'createText' The placeholder text for the create action. + * @param 'title' The title to show if no options are selected. + * @param 'checked' An array containing values for options that should be checked. Any options which are already selected will be added to this array. + * @param 'labels' The corresponding labels to show for the checked items. + * @param 'oncheck' Callback function which will be called when a checkbox/radiobutton is selected. If the function returns false the input will be unchecked. + * @param 'onuncheck' @see 'oncheck'. + * @param 'singleSelect' If true radiobuttons will be used instead of checkboxes. + */ (function( $ ){ var multiSelectId=-1; - $.fn.multiSelect=function(options){ + $.fn.multiSelect=function(options) { multiSelectId++; var settings = { 'createCallback':false, 'createText':false, + 'singleSelect':false, + 'selectedFirst':false, + 'sort':true, 'title':this.attr('title'), 'checked':[], + 'labels':[], 'oncheck':false, 'onuncheck':false, 'minWidth': 'default;', }; + $(this).attr('data-msid', multiSelectId); $.extend(settings,options); - $.each(this.children(),function(i,option){ - if($(option).attr('selected') && settings.checked.indexOf($(option).val())==-1){ + $.each(this.children(),function(i,option) { + // If the option is selected, but not in the checked array, add it. + if($(option).attr('selected') && settings.checked.indexOf($(option).val()) === -1) { settings.checked.push($(option).val()); + settings.labels.push($(option).text().trim()); + } + // If the option is in the checked array but not selected, select it. + else if(settings.checked.indexOf($(option).val()) !== -1 && !$(option).attr('selected')) { + $(option).attr('selected', 'selected'); + settings.labels.push($(option).text().trim()); } }); var button=$('<div class="multiselect button"><span>'+settings.title+'</span><span>▾</span></div>'); @@ -24,24 +48,36 @@ button.selectedItems=[]; this.hide(); this.before(span); - if(settings.minWidth=='default'){ + if(settings.minWidth=='default') { settings.minWidth=button.width(); } button.css('min-width',settings.minWidth); settings.minOuterWidth=button.outerWidth()-2; button.data('settings',settings); - if(settings.checked.length>0){ - button.children('span').first().text(settings.checked.join(', ')); + + if(!settings.singleSelect && settings.checked.length>0) { + button.children('span').first().text(settings.labels.join(', ')); + } else if(settings.singleSelect) { + button.children('span').first().text(this.find(':selected').text()); } + var self = this; + self.menuDirection = 'down'; button.click(function(event){ var button=$(this); - if(button.parent().children('ul').length>0){ - button.parent().children('ul').slideUp(400,function(){ - button.parent().children('ul').remove(); - button.removeClass('active'); - }); + if(button.parent().children('ul').length>0) { + if(self.menuDirection === 'down') { + button.parent().children('ul').slideUp(400,function() { + button.parent().children('ul').remove(); + button.removeClass('active down'); + }); + } else { + button.parent().children('ul').fadeOut(400,function() { + button.parent().children('ul').remove(); + button.removeClass('active up'); + }); + } return; } var lists=$('ul.multiselectoptions'); @@ -54,49 +90,69 @@ event.stopPropagation(); var options=$(this).parent().next().children(); var list=$('<ul class="multiselectoptions"/>').hide().appendTo($(this).parent()); - function createItem(element,checked){ + var inputType = settings.singleSelect ? 'radio' : 'checkbox'; + function createItem(element, checked){ element=$(element); var item=element.val(); var id='ms'+multiSelectId+'-option-'+item; - var input=$('<input type="checkbox"/>'); + var input=$('<input type="' + inputType + '"/>'); input.attr('id',id); + if(settings.singleSelect) { + input.attr('name', 'ms'+multiSelectId+'-option'); + } var label=$('<label/>'); label.attr('for',id); - label.text(item); - if(settings.checked.indexOf(item)!=-1 || checked){ - input.attr('checked',true); + label.text(element.text() || item); + if(settings.checked.indexOf(item)!=-1 || checked) { + input.attr('checked', true); } if(checked){ - settings.checked.push(item); + if(settings.singleSelect) { + settings.checked = [item]; + settings.labels = [item]; + } else { + settings.checked.push(item); + settings.labels.push(item); + } } input.change(function(){ - var groupname=$(this).next().text(); - if($(this).is(':checked')){ + var value = $(this).attr('id').substring(String('ms'+multiSelectId+'-option').length+1); + var label = $(this).next().text().trim(); + if($(this).is(':checked')) { + if(settings.singleSelect) { + settings.checked = []; + settings.labels = []; + $.each(self.find('option'), function() { + $(this).removeAttr('selected'); + }); + } element.attr('selected','selected'); - if(settings.oncheck){ - if(settings.oncheck(groupname)===false){ + if(typeof settings.oncheck === 'function') { + if(settings.oncheck(value)===false) { $(this).attr('checked', false); return; } } - settings.checked.push(groupname); - }else{ - var index=settings.checked.indexOf(groupname); + settings.checked.push(value); + settings.labels.push(label); + $(this).parent().addClass('checked'); + } else { + var index=settings.checked.indexOf(value); element.attr('selected',null); - if(settings.onuncheck){ - if(settings.onuncheck(groupname)===false){ + if(typeof settings.onuncheck === 'function') { + if(settings.onuncheck(value)===false) { $(this).attr('checked',true); return; } } + $(this).parent().removeClass('checked'); settings.checked.splice(index,1); + settings.labels.splice(index,1); } var oldWidth=button.width(); - if(settings.checked.length>0){ - button.children('span').first().text(settings.checked.join(', ')); - }else{ - button.children('span').first().text(settings.title); - } + button.children('span').first().text(settings.labels.length > 0 + ? settings.labels.join(', ') + : settings.title); var newOuterWidth=Math.max((button.outerWidth()-2),settings.minOuterWidth)+'px'; var newWidth=Math.max(button.width(),settings.minWidth); var pos=button.position(); @@ -110,6 +166,9 @@ }); var li=$('<li></li>'); li.append(input).append(label); + if(input.is(':checked')) { + li.addClass('checked'); + } return li; } $.each(options,function(index,item){ @@ -117,13 +176,13 @@ }); button.parent().data('preventHide',false); if(settings.createText){ - var li=$('<li>+ <em>'+settings.createText+'<em></li>'); + var li=$('<li class="creator">+ <em>'+settings.createText+'<em></li>'); li.click(function(event){ li.empty(); var input=$('<input class="new">'); li.append(input); input.focus(); - input.css('width',button.width()); + input.css('width',button.innerWidth()); button.parent().data('preventHide',true); input.keypress(function(event) { if(event.keyCode == 13) { @@ -132,7 +191,7 @@ var value = $(this).val(); var exists = false; $.each(options,function(index, item) { - if ($(item).val() == value) { + if ($(item).val() == value || $(item).text() == value) { exists = true; return false; } @@ -141,22 +200,39 @@ return false; } var li=$(this).parent(); + var val = $(this).val() + var select=button.parent().next(); + if(typeof settings.createCallback === 'function') { + var response = settings.createCallback(select, val); + if(response === false) { + return false; + } else if(typeof response !== 'undefined') { + val = response; + } + } + if(settings.singleSelect) { + $.each(select.find('option:selected'), function() { + $(this).removeAttr('selected'); + }); + } $(this).remove(); li.text('+ '+settings.createText); li.before(createItem(this)); - var select=button.parent().next(); var option=$('<option selected="selected"/>'); - option.attr('value',value); - option.text($(this).val()); + option.text($(this).val()).val(val).attr('selected', 'selected'); select.append(option); - li.prev().children('input').trigger('click'); + li.prev().children('input').prop('checked', true).trigger('change'); button.parent().data('preventHide',false); - if(settings.createCallback){ - settings.createCallback($(this).val()); + button.children('span').first().text(settings.labels.length > 0 + ? settings.labels.join(', ') + : settings.title); + if(self.menuDirection === 'up') { + var list = li.parent(); + list.css('top', list.position().top-li.outerHeight()); } } }); - input.blur(function(){ + input.blur(function() { event.preventDefault(); event.stopPropagation(); $(this).remove(); @@ -168,21 +244,72 @@ }); list.append(li); } + + var doSort = function(list, selector) { + var rows = list.find('li'+selector).get(); + + if(settings.sort) { + rows.sort(function(a, b) { + return $(a).text().toUpperCase().localeCompare($(b).text().toUpperCase()); + }); + } + + $.each(rows, function(index, row) { + list.append(row); + }); + }; + if(settings.sort && settings.selectedFirst) { + doSort(list, '.checked'); + doSort(list, ':not(.checked)'); + } else if(settings.sort && !settings.selectedFirst) { + doSort(list, ''); + } + list.append(list.find('li.creator')); var pos=button.position(); - list.css('top',pos.top+button.outerHeight()-5); - list.css('left',pos.left+3); - list.css('width',(button.outerWidth()-2)+'px'); - list.slideDown(); - list.click(function(event){ + if($(document).height() > (button.offset().top+button.outerHeight() + list.children().length * button.height()) + || $(document).height()/2 > pos.top + ) { + list.css({ + top:pos.top+button.outerHeight()-5, + left:pos.left+3, + width:(button.outerWidth()-2)+'px', + 'max-height':($(document).height()-(button.offset().top+button.outerHeight()+10))+'px' + }); + list.addClass('down'); + button.addClass('down'); + list.slideDown(); + } else { + list.css('max-height', $(document).height()-($(document).height()-(pos.top)+50)+'px'); + list.css({ + top:pos.top - list.height(), + left:pos.left+3, + width:(button.outerWidth()-2)+'px' + + }); + list.detach().insertBefore($(this)); + list.addClass('up'); + button.addClass('up'); + list.fadeIn(); + self.menuDirection = 'up'; + } + list.click(function(event) { event.stopPropagation(); }); }); - $(window).click(function(){ - if(!button.parent().data('preventHide')){ - button.parent().children('ul').slideUp(400,function(){ - button.parent().children('ul').remove(); - button.removeClass('active'); - }); + $(window).click(function() { + if(!button.parent().data('preventHide')) { + // How can I save the effect in a var? + if(self.menuDirection === 'down') { + button.parent().children('ul').slideUp(400,function() { + button.parent().children('ul').remove(); + button.removeClass('active down'); + }); + } else { + button.parent().children('ul').fadeOut(400,function() { + button.parent().children('ul').remove(); + button.removeClass('active up'); + }); + } } }); diff --git a/core/templates/logout.php b/core/templates/logout.php deleted file mode 100644 index 2247ed8e70f..00000000000 --- a/core/templates/logout.php +++ /dev/null @@ -1 +0,0 @@ -<?php echo $l->t( 'You are logged out.' ); diff --git a/settings/admin.php b/settings/admin.php index 04905391138..4d9685ab920 100755 --- a/settings/admin.php +++ b/settings/admin.php @@ -33,6 +33,16 @@ $tmpl->assign('internetconnectionworking', OC_Util::isinternetconnectionworking( $tmpl->assign('islocaleworking', OC_Util::issetlocaleworking()); $tmpl->assign('backgroundjobs_mode', OC_Appconfig::getValue('core', 'backgroundjobs_mode', 'ajax')); $tmpl->assign('shareAPIEnabled', OC_Appconfig::getValue('core', 'shareapi_enabled', 'yes')); + +// Check if connected using HTTPS +if (OC_Request::serverProtocol() == 'https') { + $connectedHTTPS = true; +} else { + $connectedHTTPS = false; +} +$tmpl->assign('isConnectedViaHTTPS', $connectedHTTPS); +$tmpl->assign('enforceHTTPSEnabled', OC_Config::getValue( "forcessl", false)); + $tmpl->assign('allowLinks', OC_Appconfig::getValue('core', 'shareapi_allow_links', 'yes')); $tmpl->assign('allowResharing', OC_Appconfig::getValue('core', 'shareapi_allow_resharing', 'yes')); $tmpl->assign('sharePolicy', OC_Appconfig::getValue('core', 'shareapi_share_policy', 'global')); diff --git a/settings/ajax/disableapp.php b/settings/ajax/disableapp.php index a39b06b9c7d..e89de928eac 100644 --- a/settings/ajax/disableapp.php +++ b/settings/ajax/disableapp.php @@ -1,7 +1,6 @@ <?php OC_JSON::checkAdminUser(); OCP\JSON::callCheck(); -OC_JSON::setContentTypeHeader(); OC_App::disable($_POST['appid']); diff --git a/settings/ajax/enableapp.php b/settings/ajax/enableapp.php index f4d5c53adef..18202dc39e9 100644 --- a/settings/ajax/enableapp.php +++ b/settings/ajax/enableapp.php @@ -2,7 +2,6 @@ OC_JSON::checkAdminUser(); OCP\JSON::callCheck(); -OC_JSON::setContentTypeHeader(); $appid = OC_App::enable($_POST['appid']); if($appid !== false) { diff --git a/settings/ajax/setsecurity.php b/settings/ajax/setsecurity.php new file mode 100644 index 00000000000..16a85aade81 --- /dev/null +++ b/settings/ajax/setsecurity.php @@ -0,0 +1,13 @@ +<?php +/** + * Copyright (c) 2013, Lukas Reschke <lukas@statuscode.ch> + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + +OC_Util::checkAdminUser(); +OCP\JSON::callCheck(); + +OC_Config::setValue( 'forcessl', filter_var($_POST['enforceHTTPS'], FILTER_VALIDATE_BOOLEAN)); + +echo 'true';
\ No newline at end of file diff --git a/settings/js/admin.js b/settings/js/admin.js index 95b7a503c27..ab218377fb3 100644 --- a/settings/js/admin.js +++ b/settings/js/admin.js @@ -30,4 +30,8 @@ $(document).ready(function(){ } OC.AppConfig.setValue('core', $(this).attr('name'), value); }); + + $('#security').change(function(){ + $.post(OC.filePath('settings','ajax','setsecurity.php'), { enforceHTTPS: $('#enforceHTTPSEnabled').val() },function(){} ); + }); }); diff --git a/settings/js/users.js b/settings/js/users.js index b0e30feb80c..fa6f058d923 100644 --- a/settings/js/users.js +++ b/settings/js/users.js @@ -177,9 +177,9 @@ var UserList = { } else { checkHandeler = false; } - var addGroup = function (group) { + var addGroup = function (select, group) { $('select[multiple]').each(function (index, element) { - if ($(element).find('option[value="' + group + '"]').length == 0) { + if ($(element).find('option[value="' + group + '"]').length === 0 && select.data('msid') !== $(element).data('msid')) { $(element).append('<option value="' + group + '">' + group + '</option>'); } }) @@ -193,6 +193,7 @@ var UserList = { element.multiSelect({ createCallback:addGroup, createText:label, + selectedFirst:true, checked:checked, oncheck:checkHandeler, onuncheck:checkHandeler, diff --git a/settings/routes.php b/settings/routes.php index 60e01527105..9b5bf809230 100644 --- a/settings/routes.php +++ b/settings/routes.php @@ -57,4 +57,6 @@ $this->create('settings_ajax_navigationdetect', '/settings/ajax/navigationdetect $this->create('settings_ajax_getlog', '/settings/ajax/getlog.php') ->actionInclude('settings/ajax/getlog.php'); $this->create('settings_ajax_setloglevel', '/settings/ajax/setloglevel.php') - ->actionInclude('settings/ajax/setloglevel.php');
\ No newline at end of file + ->actionInclude('settings/ajax/setloglevel.php'); +$this->create('settings_ajax_setsecurity', '/settings/ajax/setsecurity.php') + ->actionInclude('settings/ajax/setsecurity.php'); diff --git a/settings/templates/admin.php b/settings/templates/admin.php index 26335063d4b..5ee0147fbcb 100644 --- a/settings/templates/admin.php +++ b/settings/templates/admin.php @@ -132,6 +132,33 @@ if (!$_['internetconnectionworking']) { </table> </fieldset> +<fieldset class="personalblock" id="security"> + <legend><strong><?php echo $l->t('Security');?></strong></legend> + <table class="nostyle"> + <tr> + <td id="enable"> + <input type="checkbox" name="forcessl" id="enforceHTTPSEnabled" + <?php if ($_['enforceHTTPSEnabled']) { + echo 'checked="checked" '; + echo 'value="false"'; + } else { + echo 'value="true"'; + } + ?> + <?php if (!$_['isConnectedViaHTTPS']) echo 'disabled'; ?> /> + <label for="forcessl"><?php echo $l->t('Enforce HTTPS');?></label><br/> + <em><?php echo $l->t('Enforces the clients to connect to ownCloud via an encrypted connection.'); ?></em> + <?php if (!$_['isConnectedViaHTTPS']) { + echo "<br/><em>"; + echo $l->t('Please connect to this ownCloud instance via HTTPS to enable or disable the SSL enforcement.'); + echo "</em>"; + } + ?> + </td> + </tr> + </table> +</fieldset> + <fieldset class="personalblock"> <legend><strong><?php echo $l->t('Log');?></strong></legend> <?php echo $l->t('Log level');?> <select name='loglevel' id='loglevel'> |