mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge branch 'stretch-unstable' into group_permission
This commit is contained in:
commit
24cfc15536
40 changed files with 1397 additions and 955 deletions
|
@ -195,7 +195,8 @@ if __name__ == '__main__':
|
|||
# Check that YunoHost is installed
|
||||
if not os.path.isfile('/etc/yunohost/installed') and \
|
||||
(len(args) < 2 or (args[0] +' '+ args[1] != 'tools postinstall' and \
|
||||
args[0] +' '+ args[1] != 'backup restore')):
|
||||
args[0] +' '+ args[1] != 'backup restore' and \
|
||||
args[0] +' '+ args[1] != 'log display')):
|
||||
|
||||
from moulinette import m18n
|
||||
# Init i18n
|
||||
|
|
|
@ -44,19 +44,7 @@ _global:
|
|||
uri: ldap://localhost:389
|
||||
base_dn: dc=yunohost,dc=org
|
||||
user_rdn: cn=admin,dc=yunohost,dc=org
|
||||
ldap-anonymous:
|
||||
vendor: ldap
|
||||
parameters:
|
||||
uri: ldap://localhost:389
|
||||
base_dn: dc=yunohost,dc=org
|
||||
as-root:
|
||||
vendor: ldap
|
||||
parameters:
|
||||
# We can get this uri by (urllib.quote_plus('/var/run/slapd/ldapi')
|
||||
uri: ldapi://%2Fvar%2Frun%2Fslapd%2Fldapi
|
||||
base_dn: dc=yunohost,dc=org
|
||||
user_rdn: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
|
||||
argument_auth: true
|
||||
argument_auth: false
|
||||
arguments:
|
||||
-v:
|
||||
full: --version
|
||||
|
@ -77,9 +65,6 @@ user:
|
|||
list:
|
||||
action_help: List users
|
||||
api: GET /users
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
--fields:
|
||||
help: fields to fetch
|
||||
|
@ -89,9 +74,6 @@ user:
|
|||
create:
|
||||
action_help: Create user
|
||||
api: POST /users
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
username:
|
||||
help: The unique username to create
|
||||
|
@ -148,9 +130,6 @@ user:
|
|||
delete:
|
||||
action_help: Delete user
|
||||
api: DELETE /users/<username>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
username:
|
||||
help: Username to delete
|
||||
|
@ -164,9 +143,6 @@ user:
|
|||
update:
|
||||
action_help: Update user informations
|
||||
api: PUT /users/<username>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
username:
|
||||
help: Username to update
|
||||
|
@ -219,9 +195,6 @@ user:
|
|||
info:
|
||||
action_help: Get user information
|
||||
api: GET /users/<username>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
username:
|
||||
help: Username or email to get information
|
||||
|
@ -234,9 +207,6 @@ user:
|
|||
list:
|
||||
action_help: List group
|
||||
api: GET /users/groups
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
--fields:
|
||||
help: fields to fetch
|
||||
|
@ -246,9 +216,6 @@ user:
|
|||
add:
|
||||
action_help: Create group
|
||||
api: POST /users/groups
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
groupname:
|
||||
help: The unique group name to add
|
||||
|
@ -261,9 +228,6 @@ user:
|
|||
delete:
|
||||
action_help: Delete group
|
||||
api: DELETE /users/groups/<groupname>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
groupname:
|
||||
help: Username to delete
|
||||
|
@ -274,9 +238,6 @@ user:
|
|||
update:
|
||||
action_help: Update group
|
||||
api: PUT /users/groups/<groupname>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
groupname:
|
||||
help: Username to update
|
||||
|
@ -301,9 +262,6 @@ user:
|
|||
info:
|
||||
action_help: Get group information
|
||||
api: GET /users/groups/<groupname>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
groupname:
|
||||
help: Groupname to get information
|
||||
|
@ -317,9 +275,6 @@ user:
|
|||
list:
|
||||
action_help: List access to user and group
|
||||
api: GET /users/permission/<app>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
-a:
|
||||
full: --app
|
||||
|
@ -346,9 +301,6 @@ user:
|
|||
add:
|
||||
action_help: Grant access right to users and group
|
||||
api: POST /users/permission/<app>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
app:
|
||||
help: Application to manage the permission
|
||||
|
@ -377,9 +329,6 @@ user:
|
|||
remove:
|
||||
action_help: Revoke access right to users and group
|
||||
api: PUT /users/permission/<app>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
app:
|
||||
help: Application to manage the permission
|
||||
|
@ -408,9 +357,6 @@ user:
|
|||
clear:
|
||||
action_help: Reset access rights for the app
|
||||
api: DELETE /users/permission/<app>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
app:
|
||||
help: Application to manage the permission
|
||||
|
@ -428,9 +374,6 @@ user:
|
|||
allow:
|
||||
action_help: Allow the user to uses ssh
|
||||
api: POST /users/ssh/enable
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
username:
|
||||
help: Username of the user
|
||||
|
@ -441,9 +384,6 @@ user:
|
|||
disallow:
|
||||
action_help: Disallow the user to uses ssh
|
||||
api: POST /users/ssh/disable
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
username:
|
||||
help: Username of the user
|
||||
|
@ -454,9 +394,6 @@ user:
|
|||
list-keys:
|
||||
action_help: Show user's authorized ssh keys
|
||||
api: GET /users/ssh/keys
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
username:
|
||||
help: Username of the user
|
||||
|
@ -467,9 +404,6 @@ user:
|
|||
add-key:
|
||||
action_help: Add a new authorized ssh key for this user
|
||||
api: POST /users/ssh/key
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
username:
|
||||
help: Username of the user
|
||||
|
@ -485,9 +419,6 @@ user:
|
|||
remove-key:
|
||||
action_help: Remove an authorized ssh key for this user
|
||||
api: DELETE /users/ssh/key
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
username:
|
||||
help: Username of the user
|
||||
|
@ -508,17 +439,11 @@ domain:
|
|||
list:
|
||||
action_help: List domains
|
||||
api: GET /domains
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
|
||||
### domain_add()
|
||||
add:
|
||||
action_help: Create a custom domain
|
||||
api: POST /domains
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
domain:
|
||||
help: Domain name to add
|
||||
|
@ -535,9 +460,6 @@ domain:
|
|||
remove:
|
||||
action_help: Delete domains
|
||||
api: DELETE /domains/<domain>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
domain:
|
||||
help: Domain to delete
|
||||
|
@ -548,9 +470,6 @@ domain:
|
|||
dns-conf:
|
||||
action_help: Generate DNS configuration for a domain
|
||||
api: GET /domains/<domain>/dns
|
||||
configuration:
|
||||
authenticate:
|
||||
- api
|
||||
arguments:
|
||||
domain:
|
||||
help: Target domain
|
||||
|
@ -566,9 +485,6 @@ domain:
|
|||
cert-status:
|
||||
action_help: List status of current certificates (all by default).
|
||||
api: GET /domains/cert-status/<domain_list>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
domain_list:
|
||||
help: Domains to check
|
||||
|
@ -581,9 +497,6 @@ domain:
|
|||
cert-install:
|
||||
action_help: Install Let's Encrypt certificates for given domains (all by default).
|
||||
api: POST /domains/cert-install/<domain_list>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
domain_list:
|
||||
help: Domains for which to install the certificates
|
||||
|
@ -605,9 +518,6 @@ domain:
|
|||
cert-renew:
|
||||
action_help: Renew the Let's Encrypt certificates for given domains (all by default).
|
||||
api: POST /domains/cert-renew/<domain_list>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
domain_list:
|
||||
help: Domains for which to renew the certificates
|
||||
|
@ -629,9 +539,6 @@ domain:
|
|||
url-available:
|
||||
action_help: Check availability of a web path
|
||||
api: GET /domain/urlavailable
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
domain:
|
||||
help: The domain for the web path (e.g. your.domain.tld)
|
||||
|
@ -734,9 +641,6 @@ app:
|
|||
map:
|
||||
action_help: List apps by domain
|
||||
api: GET /appsmap
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
-a:
|
||||
full: --app
|
||||
|
@ -755,9 +659,6 @@ app:
|
|||
install:
|
||||
action_help: Install apps
|
||||
api: POST /apps
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
app:
|
||||
help: Name, local path or git URL of the app to install
|
||||
|
@ -780,9 +681,6 @@ app:
|
|||
remove:
|
||||
action_help: Remove app
|
||||
api: DELETE /apps/<app>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
app:
|
||||
help: App(s) to delete
|
||||
|
@ -791,9 +689,6 @@ app:
|
|||
upgrade:
|
||||
action_help: Upgrade app
|
||||
api: PUT /upgrade/apps
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
app:
|
||||
help: App(s) to upgrade (default all)
|
||||
|
@ -809,9 +704,6 @@ app:
|
|||
change-url:
|
||||
action_help: Change app's URL
|
||||
api: PUT /apps/<app>/changeurl
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
app:
|
||||
help: Target app instance name
|
||||
|
@ -864,9 +756,6 @@ app:
|
|||
action_help: Check availability of a web path
|
||||
api: GET /tools/checkurl
|
||||
deprecated: True
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
url:
|
||||
help: Url to check
|
||||
|
@ -878,9 +767,6 @@ app:
|
|||
register-url:
|
||||
action_help: Book/register a web path for a given app
|
||||
api: PUT /tools/registerurl
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
app:
|
||||
help: App which will use the web path
|
||||
|
@ -920,9 +806,6 @@ app:
|
|||
makedefault:
|
||||
action_help: Redirect domain root to an app
|
||||
api: PUT /apps/<app>/default
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
app:
|
||||
help: App name to put on domain root
|
||||
|
@ -934,17 +817,11 @@ app:
|
|||
ssowatconf:
|
||||
action_help: Regenerate SSOwat configuration file
|
||||
api: PUT /ssowatconf
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
|
||||
### app_change_label()
|
||||
change-label:
|
||||
action_help: Change app label
|
||||
api: PUT /apps/<app>/label
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
app:
|
||||
help: App ID
|
||||
|
@ -955,9 +832,6 @@ app:
|
|||
addaccess:
|
||||
action_help: Grant access right to users (everyone by default)
|
||||
api: PUT /access
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
apps:
|
||||
nargs: "+"
|
||||
|
@ -969,9 +843,6 @@ app:
|
|||
removeaccess:
|
||||
action_help: Revoke access right to users (everyone by default)
|
||||
api: DELETE /access
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
apps:
|
||||
nargs: "+"
|
||||
|
@ -983,9 +854,6 @@ app:
|
|||
clearaccess:
|
||||
action_help: Reset access rights for the app
|
||||
api: POST /access
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
apps:
|
||||
nargs: "+"
|
||||
|
@ -1083,9 +951,6 @@ backup:
|
|||
restore:
|
||||
action_help: Restore from a local backup archive. If neither --apps or --system are given, this will restore all apps and all system parts in the archive. If only --apps if given, this will only restore apps and no system parts. Similarly, if only --system is given, this will only restore system parts and no apps.
|
||||
api: POST /backup/restore/<name>
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
name:
|
||||
help: Name of the local backup archive
|
||||
|
@ -1690,21 +1555,10 @@ tools:
|
|||
category_help: Specific tools
|
||||
actions:
|
||||
|
||||
### tools_ldapinit()
|
||||
ldapinit:
|
||||
action_help: YunoHost LDAP initialization
|
||||
api: POST /ldap
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
|
||||
### tools_adminpw()
|
||||
adminpw:
|
||||
action_help: Change password of admin and root users
|
||||
api: PUT /adminpw
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
-n:
|
||||
full: --new-password
|
||||
|
@ -1720,9 +1574,6 @@ tools:
|
|||
api:
|
||||
- GET /domains/main
|
||||
- PUT /domains/main
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
arguments:
|
||||
-n:
|
||||
full: --new-domain
|
||||
|
@ -1734,8 +1585,6 @@ tools:
|
|||
postinstall:
|
||||
action_help: YunoHost post-install
|
||||
api: POST /postinstall
|
||||
configuration:
|
||||
authenticate: false
|
||||
arguments:
|
||||
-d:
|
||||
full: --domain
|
||||
|
@ -1764,35 +1613,29 @@ tools:
|
|||
action_help: YunoHost update
|
||||
api: PUT /update
|
||||
arguments:
|
||||
--ignore-apps:
|
||||
help: Ignore apps cache update and changelog
|
||||
--apps:
|
||||
help: Fetch the application list to check which apps can be upgraded
|
||||
action: store_true
|
||||
--ignore-packages:
|
||||
help: Ignore APT cache update and changelog
|
||||
--system:
|
||||
help: Fetch available system packages upgrades (equivalent to apt update)
|
||||
action: store_true
|
||||
|
||||
### tools_upgrade()
|
||||
upgrade:
|
||||
action_help: YunoHost upgrade
|
||||
api: PUT /upgrade
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
--ignore-apps:
|
||||
help: Ignore apps upgrade
|
||||
action: store_true
|
||||
--ignore-packages:
|
||||
help: Ignore APT packages upgrade
|
||||
--apps:
|
||||
help: List of apps to upgrade (all by default)
|
||||
nargs: "*"
|
||||
--system:
|
||||
help: Upgrade only the system packages
|
||||
action: store_true
|
||||
|
||||
### tools_diagnosis()
|
||||
diagnosis:
|
||||
action_help: YunoHost diagnosis
|
||||
api: GET /diagnosis
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: ldap-anonymous
|
||||
arguments:
|
||||
-p:
|
||||
full: --private
|
||||
|
@ -1811,9 +1654,6 @@ tools:
|
|||
|
||||
### tools_shell()
|
||||
shell:
|
||||
configuration:
|
||||
authenticate: all
|
||||
authenticator: as-root
|
||||
action_help: Launch a development shell
|
||||
arguments:
|
||||
-c:
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
# To validate your regex you can test with this command:
|
||||
# fail2ban-regex /var/log/YOUR_LOG_FILE_PATH /etc/fail2ban/filter.d/YOUR_APP.conf
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_add_fail2ban_config () {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=lrmptv
|
||||
|
@ -143,7 +143,7 @@ EOF
|
|||
#
|
||||
# usage: ynh_remove_fail2ban_config
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_remove_fail2ban_config () {
|
||||
ynh_secure_remove "/etc/fail2ban/jail.d/$app.conf"
|
||||
ynh_secure_remove "/etc/fail2ban/filter.d/$app.conf"
|
||||
|
|
|
@ -195,9 +195,16 @@ ynh_print_ON () {
|
|||
# The execution time is given for the duration since the previous call. So the weight should be applied to this previous call.
|
||||
# | arg: -l, --last= - Use for the last call of the helper, to fill te progression bar.
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
increment_progression=0
|
||||
previous_weight=0
|
||||
max_progression=-1
|
||||
# Set the scale of the progression bar
|
||||
# progress_string(0,1,2) should have the size of the scale.
|
||||
progress_scale=20
|
||||
progress_string2="####################"
|
||||
progress_string1="++++++++++++++++++++"
|
||||
progress_string0="...................."
|
||||
# Define base_time when the file is sourced
|
||||
base_time=$(date +%s)
|
||||
ynh_script_progression () {
|
||||
|
@ -218,54 +225,51 @@ ynh_script_progression () {
|
|||
local exec_time=$(( $(date +%s) - $base_time ))
|
||||
base_time=$(date +%s)
|
||||
|
||||
# Get the number of occurrences of 'ynh_script_progression' in the script. Except those are commented.
|
||||
local helper_calls="$(grep --count "^[^#]*ynh_script_progression" $0)"
|
||||
# Get the number of call with a weight value
|
||||
local weight_calls=$(grep --perl-regexp --count "^[^#]*ynh_script_progression.*(--weight|-w )" $0)
|
||||
# Compute $max_progression (if we didn't already)
|
||||
if [ "$max_progression" = -1 ]
|
||||
then
|
||||
# Get the number of occurrences of 'ynh_script_progression' in the script. Except those are commented.
|
||||
local helper_calls="$(grep --count "^[^#]*ynh_script_progression" $0)"
|
||||
# Get the number of call with a weight value
|
||||
local weight_calls=$(grep --perl-regexp --count "^[^#]*ynh_script_progression.*(--weight|-w )" $0)
|
||||
|
||||
# Get the weight of each occurrences of 'ynh_script_progression' in the script using --weight
|
||||
local weight_valuesA="$(grep --perl-regexp "^[^#]*ynh_script_progression.*--weight" $0 | sed 's/.*--weight[= ]\([[:digit:]]*\).*/\1/g')"
|
||||
# Get the weight of each occurrences of 'ynh_script_progression' in the script using -w
|
||||
local weight_valuesB="$(grep --perl-regexp "^[^#]*ynh_script_progression.*-w " $0 | sed 's/.*-w[= ]\([[:digit:]]*\).*/\1/g')"
|
||||
# Each value will be on a different line.
|
||||
# Remove each 'end of line' and replace it by a '+' to sum the values.
|
||||
local weight_values=$(( $(echo "$weight_valuesA" | tr '\n' '+') + $(echo "$weight_valuesB" | tr '\n' '+') 0 ))
|
||||
# Get the weight of each occurrences of 'ynh_script_progression' in the script using --weight
|
||||
local weight_valuesA="$(grep --perl-regexp "^[^#]*ynh_script_progression.*--weight" $0 | sed 's/.*--weight[= ]\([[:digit:]]*\).*/\1/g')"
|
||||
# Get the weight of each occurrences of 'ynh_script_progression' in the script using -w
|
||||
local weight_valuesB="$(grep --perl-regexp "^[^#]*ynh_script_progression.*-w " $0 | sed 's/.*-w[= ]\([[:digit:]]*\).*/\1/g')"
|
||||
# Each value will be on a different line.
|
||||
# Remove each 'end of line' and replace it by a '+' to sum the values.
|
||||
local weight_values=$(( $(echo "$weight_valuesA" | tr '\n' '+') + $(echo "$weight_valuesB" | tr '\n' '+') 0 ))
|
||||
|
||||
# max_progression is a total number of calls to this helper.
|
||||
# Less the number of calls with a weight value.
|
||||
# Plus the total of weight values
|
||||
local max_progression=$(( $helper_calls - $weight_calls + $weight_values ))
|
||||
# max_progression is a total number of calls to this helper.
|
||||
# Less the number of calls with a weight value.
|
||||
# Plus the total of weight values
|
||||
max_progression=$(( $helper_calls - $weight_calls + $weight_values ))
|
||||
fi
|
||||
|
||||
# Increment each execution of ynh_script_progression in this script by the weight of the previous call.
|
||||
increment_progression=$(( $increment_progression + $previous_weight ))
|
||||
# Store the weight of the current call in $previous_weight for next call
|
||||
previous_weight=$weight
|
||||
|
||||
# Set the scale of the progression bar
|
||||
local scale=20
|
||||
# progress_string(0,1,2) should have the size of the scale.
|
||||
local progress_string2="####################"
|
||||
local progress_string1="++++++++++++++++++++"
|
||||
local progress_string0="...................."
|
||||
|
||||
# Reduce $increment_progression to the size of the scale
|
||||
if [ $last -eq 0 ]
|
||||
then
|
||||
local effective_progression=$(( $increment_progression * $scale / $max_progression ))
|
||||
local effective_progression=$(( $increment_progression * $progress_scale / $max_progression ))
|
||||
# If last is specified, fill immediately the progression_bar
|
||||
else
|
||||
local effective_progression=$scale
|
||||
local effective_progression=$progress_scale
|
||||
fi
|
||||
|
||||
# Build $progression_bar from progress_string(0,1,2) according to $effective_progression and the weight of the current task
|
||||
# expected_progression is the progression expected after the current task
|
||||
local expected_progression="$(( ( $increment_progression + $weight ) * $scale / $max_progression - $effective_progression ))"
|
||||
local expected_progression="$(( ( $increment_progression + $weight ) * $progress_scale / $max_progression - $effective_progression ))"
|
||||
if [ $last -eq 1 ]
|
||||
then
|
||||
expected_progression=0
|
||||
fi
|
||||
# left_progression is the progression not yet done
|
||||
local left_progression="$(( $scale - $effective_progression - $expected_progression ))"
|
||||
local left_progression="$(( $progress_scale - $effective_progression - $expected_progression ))"
|
||||
# Build the progression bar with $effective_progression, work done, $expected_progression, current work and $left_progression, work to be done.
|
||||
local progression_bar="${progress_string2:0:$effective_progression}${progress_string1:0:$expected_progression}${progress_string0:0:$left_progression}"
|
||||
|
||||
|
@ -284,7 +288,7 @@ ynh_script_progression () {
|
|||
# | arg: -m, --message= - The text to print
|
||||
# | arg: -t, --trace= - Turn on or off the trace of the script. Usefull to trace nonly a small part of a script.
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_debug () {
|
||||
# Disable set xtrace for the helper itself, to not pollute the debug log
|
||||
set +x
|
||||
|
@ -339,7 +343,7 @@ ynh_debug () {
|
|||
#
|
||||
# | arg: command - command to execute
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_debug_exec () {
|
||||
ynh_debug --message="$(eval $@)"
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ PSQL_ROOT_PWD_FILE=/etc/yunohost/psql
|
|||
# | arg: -p, --password - the user password
|
||||
# | arg: -d, --database - the database to connect to
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_psql_connect_as() {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=upd
|
||||
|
@ -33,7 +33,7 @@ ynh_psql_connect_as() {
|
|||
# | arg: -s, --sql - the SQL command to execute
|
||||
# | arg: -d, --database - the database to connect to
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_psql_execute_as_root() {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=sd
|
||||
|
@ -54,7 +54,7 @@ ynh_psql_execute_as_root() {
|
|||
# | arg: -f, --file - the file containing SQL commands
|
||||
# | arg: -d, --database - the database to connect to
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_psql_execute_file_as_root() {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=fd
|
||||
|
@ -77,7 +77,7 @@ ynh_psql_execute_file_as_root() {
|
|||
# | arg: db - the database name to create
|
||||
# | arg: user - the user to grant privilegies
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_psql_create_db() {
|
||||
local db=$1
|
||||
local user=${2:-}
|
||||
|
@ -102,7 +102,7 @@ ynh_psql_create_db() {
|
|||
# usage: ynh_psql_drop_db db
|
||||
# | arg: db - the database name to drop
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_psql_drop_db() {
|
||||
local db=$1
|
||||
# First, force disconnection of all clients connected to the database
|
||||
|
@ -120,7 +120,7 @@ ynh_psql_drop_db() {
|
|||
# | arg: -d, --database - the database name to dump
|
||||
# | ret: the psqldump output
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_psql_dump_db() {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=d
|
||||
|
@ -140,7 +140,7 @@ ynh_psql_dump_db() {
|
|||
# | arg: user - the user name to create
|
||||
# | arg: pwd - the password to identify user by
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_psql_create_user() {
|
||||
local user=$1
|
||||
local pwd=$2
|
||||
|
@ -192,7 +192,7 @@ ynh_psql_database_exists() {
|
|||
# usage: ynh_psql_drop_user user
|
||||
# | arg: user - the user name to drop
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_psql_drop_user() {
|
||||
ynh_psql_execute_as_root --sql="DROP USER ${1};"
|
||||
}
|
||||
|
|
|
@ -59,6 +59,98 @@ ynh_app_setting_delete() {
|
|||
ynh_app_setting "delete" "$app" "$key"
|
||||
}
|
||||
|
||||
# Add skipped_uris urls into the config
|
||||
#
|
||||
# usage: ynh_add_skipped_uris [--appid=app] --url=url1,url2 [--regex]
|
||||
# | arg: -a, --appid - the application id
|
||||
# | arg: -u, --url - the urls to add to the sso for this app
|
||||
# | arg: -r, --regex - Use the key 'skipped_regex' instead of 'skipped_uris'
|
||||
#
|
||||
# An URL set with 'skipped_uris' key will be totally ignored by the SSO,
|
||||
# which means that the access will be public and the logged-in user information will not be passed to the app.
|
||||
#
|
||||
# Requires YunoHost version 3.6.0 or higher.
|
||||
ynh_add_skipped_uris() {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=aur
|
||||
declare -Ar args_array=( [a]=appid= [u]=url= [r]=regex )
|
||||
local appid
|
||||
local url
|
||||
local regex
|
||||
# Manage arguments with getopts
|
||||
ynh_handle_getopts_args "$@"
|
||||
appid={appid:-$app}
|
||||
regex={regex:-0}
|
||||
|
||||
local key=skipped_uris
|
||||
if [ $regex -eq 1 ]; then
|
||||
key=skipped_regex
|
||||
fi
|
||||
|
||||
ynh_app_setting_set --app=$appid --key=$key --value="$url"
|
||||
}
|
||||
|
||||
# Add unprotected_uris urls into the config
|
||||
#
|
||||
# usage: ynh_add_unprotected_uris [--appid=app] --url=url1,url2 [--regex]
|
||||
# | arg: -a, --appid - the application id
|
||||
# | arg: -u, --url - the urls to add to the sso for this app
|
||||
# | arg: -r, --regex - Use the key 'unprotected_regex' instead of 'unprotected_uris'
|
||||
#
|
||||
# An URL set with unprotected_uris key will be accessible publicly, but if an user is logged in,
|
||||
# his information will be accessible (through HTTP headers) to the app.
|
||||
#
|
||||
# Requires YunoHost version 3.6.0 or higher.
|
||||
ynh_add_unprotected_uris() {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=aur
|
||||
declare -Ar args_array=( [a]=appid= [u]=url= [r]=regex )
|
||||
local appid
|
||||
local url
|
||||
local regex
|
||||
# Manage arguments with getopts
|
||||
ynh_handle_getopts_args "$@"
|
||||
appid={appid:-$app}
|
||||
regex={regex:-0}
|
||||
|
||||
local key=unprotected_uris
|
||||
if [ $regex -eq 1 ]; then
|
||||
key=unprotected_regex
|
||||
fi
|
||||
|
||||
ynh_app_setting_set --app=$appid --key=$key --value="$url"
|
||||
}
|
||||
|
||||
# Add protected_uris urls into the config
|
||||
#
|
||||
# usage: ynh_add_protected_uris [--appid=app] --url=url1,url2 [--regex]
|
||||
# | arg: -a, --appid - the application id
|
||||
# | arg: -u, --url - the urls to add to the sso for this app
|
||||
# | arg: -r, --regex - Use the key 'protected_regex' instead of 'protected_uris'
|
||||
#
|
||||
# An URL set with protected_uris will be blocked by the SSO and accessible only to authenticated and authorized users.
|
||||
#
|
||||
# Requires YunoHost version 3.6.0 or higher.
|
||||
ynh_add_protected_uris() {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=aur
|
||||
declare -Ar args_array=( [a]=appid= [u]=url= [r]=regex )
|
||||
local appid
|
||||
local url
|
||||
local regex
|
||||
# Manage arguments with getopts
|
||||
ynh_handle_getopts_args "$@"
|
||||
appid={appid:-$app}
|
||||
regex={regex:-0}
|
||||
|
||||
local key=protected_uris
|
||||
if [ $regex -eq 1 ]; then
|
||||
key=protected_regex
|
||||
fi
|
||||
|
||||
ynh_app_setting_set --app=$appid --key=$key --value="$url"
|
||||
}
|
||||
|
||||
# Small "hard-coded" interface to avoid calling "yunohost app" directly each
|
||||
# time dealing with a setting is needed (which may be so slow on ARM boards)
|
||||
#
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#
|
||||
# It prints a warning to inform that the script was failed, and execute the ynh_clean_setup function if used in the app script
|
||||
#
|
||||
# Requires YunoHost version 2.6.4 or higher.
|
||||
ynh_exit_properly () {
|
||||
local exit_code=$?
|
||||
if [ "$exit_code" -eq 0 ]; then
|
||||
|
@ -26,8 +25,46 @@ ynh_exit_properly () {
|
|||
trap '' EXIT # Ignore new exit signals
|
||||
set +eu # Do not exit anymore if a command fail or if a variable is empty
|
||||
|
||||
# Small tempo to avoid the next message being mixed up with other DEBUG messages
|
||||
sleep 0.5
|
||||
|
||||
ynh_print_err --message="!!\n $app's script has encountered an error. Its execution was cancelled.\n!!"
|
||||
|
||||
# If the script is executed from the CLI, dump the end of the log that precedes the crash.
|
||||
if [ "$YNH_INTERFACE" == "cli" ]
|
||||
then
|
||||
# Unset xtrace to not spoil the log
|
||||
set +x
|
||||
|
||||
local ynh_log="/var/log/yunohost/yunohost-cli.log"
|
||||
|
||||
# Wait for the log to be fill with the data until the crash.
|
||||
local timeout=0
|
||||
while ! tail --lines=20 "$ynh_log" | grep --quiet "+ ynh_exit_properly"
|
||||
do
|
||||
((timeout++))
|
||||
if [ $timeout -eq 500 ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
echo -e "\e[34m\e[1mPlease find here an extract of the log before the crash:\e[0m" >&2
|
||||
# Tail the last 30 lines of log of YunoHost
|
||||
# But remove all lines after "ynh_exit_properly"
|
||||
# Remove the timestamp at the beginning of the line
|
||||
# Remove "yunohost.hook..."
|
||||
# Add DEBUG and color it at the beginning of each log line.
|
||||
echo -e "$(tail --lines=30 "$ynh_log" \
|
||||
| sed '1,/+ ynh_exit_properly/!d' \
|
||||
| sed 's/^[[:digit:]: ,-]*//g' \
|
||||
| sed 's/ *yunohost.hook.*\]/ -/g' \
|
||||
| sed 's/^WARNING /&/g' \
|
||||
| sed 's/^DEBUG /& /g' \
|
||||
| sed 's/^INFO /& /g' \
|
||||
| sed 's/^/\\e[34m\\e[1m[DEBUG]\\e[0m: /g')" >&2
|
||||
set -x
|
||||
fi
|
||||
|
||||
if type -t ynh_clean_setup > /dev/null; then # Check if the function exist in the app script.
|
||||
ynh_clean_setup # Call the function to do specific cleaning for the app.
|
||||
fi
|
||||
|
@ -365,7 +402,7 @@ ynh_get_plain_key() {
|
|||
# | arg: -m, --manifest= - Path of the manifest to read
|
||||
# | arg: -k, --key= - Name of the key to find
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_read_manifest () {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=mk
|
||||
|
@ -392,7 +429,7 @@ ynh_read_manifest () {
|
|||
# usage: ynh_app_upstream_version [-m manifest]
|
||||
# | arg: -m, --manifest= - Path of the manifest to read
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_app_upstream_version () {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=m
|
||||
|
@ -415,7 +452,7 @@ ynh_app_upstream_version () {
|
|||
# usage: ynh_app_package_version [-m manifest]
|
||||
# | arg: -m, --manifest= - Path of the manifest to read
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_app_package_version () {
|
||||
# Declare an array to define the options of this helper.
|
||||
local legacy_args=m
|
||||
|
@ -444,7 +481,7 @@ ynh_app_package_version () {
|
|||
#
|
||||
# usage: ynh_check_app_version_changed
|
||||
#
|
||||
# Requires YunoHost version 3.?.? or higher.
|
||||
# Requires YunoHost version 3.5.0 or higher.
|
||||
ynh_check_app_version_changed () {
|
||||
local force_upgrade=${YNH_FORCE_UPGRADE:-0}
|
||||
local package_check=${PACKAGE_CHECK_EXEC:-0}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
set -e
|
||||
|
||||
. /usr/share/yunohost/helpers
|
||||
|
||||
do_pre_regen() {
|
||||
pending_dir=$1
|
||||
|
||||
|
@ -20,9 +22,12 @@ do_pre_regen() {
|
|||
main_domain=$(cat /etc/yunohost/current_host)
|
||||
domain_list=$(sudo yunohost domain list --output-as plain --quiet | tr '\n' ' ')
|
||||
|
||||
cat main.cf \
|
||||
| sed "s/{{ main_domain }}/${main_domain}/g" \
|
||||
> "${postfix_dir}/main.cf"
|
||||
# Support different strategy for security configurations
|
||||
export compatibility="$(yunohost settings get 'security.postfix.compatibility')"
|
||||
|
||||
export main_domain
|
||||
export domain_list
|
||||
ynh_render_template "main.cf" "${postfix_dir}/main.cf"
|
||||
|
||||
cat postsrsd \
|
||||
| sed "s/{{ main_domain }}/${main_domain}/g" \
|
||||
|
|
|
@ -42,4 +42,4 @@ nameserver 2001:1608:10:25::9249:d69b
|
|||
nameserver 91.239.100.100
|
||||
nameserver 2001:67c:28a4::
|
||||
nameserver 89.233.43.71
|
||||
nameserver 2002:d596:2a92:1:71:53::
|
||||
nameserver 2a01:3a0:53:53::
|
||||
|
|
|
@ -33,7 +33,11 @@ smtpd_tls_key_file = /etc/yunohost/certs/{{ main_domain }}/key.pem
|
|||
smtpd_tls_exclude_ciphers = aNULL, MD5, DES, ADH, RC4, 3DES
|
||||
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
|
||||
smtpd_tls_loglevel=1
|
||||
{% if compatibility == "intermediate" %}
|
||||
smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3
|
||||
{% else %}
|
||||
smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3,!TLSv1,!TLSv1.1
|
||||
{% endif %}
|
||||
smtpd_tls_mandatory_ciphers=high
|
||||
smtpd_tls_eecdh_grade = ultra
|
||||
|
||||
|
@ -58,7 +62,7 @@ alias_maps = hash:/etc/aliases
|
|||
alias_database = hash:/etc/aliases
|
||||
mydomain = {{ main_domain }}
|
||||
mydestination = localhost
|
||||
relayhost =
|
||||
relayhost =
|
||||
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
|
||||
mailbox_command = procmail -a "$EXTENSION"
|
||||
mailbox_size_limit = 0
|
||||
|
@ -68,71 +72,71 @@ inet_interfaces = all
|
|||
#### Fit to the maximum message size to 30mb, more than allowed by GMail or Yahoo ####
|
||||
message_size_limit = 31457280
|
||||
|
||||
# Virtual Domains Control
|
||||
virtual_mailbox_domains = ldap:/etc/postfix/ldap-domains.cf
|
||||
virtual_mailbox_maps = ldap:/etc/postfix/ldap-accounts.cf
|
||||
virtual_mailbox_base =
|
||||
virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf
|
||||
virtual_alias_domains =
|
||||
virtual_minimum_uid = 100
|
||||
virtual_uid_maps = static:vmail
|
||||
# Virtual Domains Control
|
||||
virtual_mailbox_domains = ldap:/etc/postfix/ldap-domains.cf
|
||||
virtual_mailbox_maps = ldap:/etc/postfix/ldap-accounts.cf
|
||||
virtual_mailbox_base =
|
||||
virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf
|
||||
virtual_alias_domains =
|
||||
virtual_minimum_uid = 100
|
||||
virtual_uid_maps = static:vmail
|
||||
virtual_gid_maps = static:mail
|
||||
smtpd_sender_login_maps= ldap:/etc/postfix/ldap-accounts.cf
|
||||
|
||||
# Dovecot LDA
|
||||
virtual_transport = dovecot
|
||||
# Dovecot LDA
|
||||
virtual_transport = dovecot
|
||||
dovecot_destination_recipient_limit = 1
|
||||
|
||||
# Enable SASL authentication for the smtpd daemon
|
||||
smtpd_sasl_auth_enable = yes
|
||||
smtpd_sasl_type = dovecot
|
||||
smtpd_sasl_path = private/auth
|
||||
# Fix some outlook's bugs
|
||||
broken_sasl_auth_clients = yes
|
||||
# Reject anonymous connections
|
||||
smtpd_sasl_security_options = noanonymous
|
||||
# Enable SASL authentication for the smtpd daemon
|
||||
smtpd_sasl_auth_enable = yes
|
||||
smtpd_sasl_type = dovecot
|
||||
smtpd_sasl_path = private/auth
|
||||
# Fix some outlook's bugs
|
||||
broken_sasl_auth_clients = yes
|
||||
# Reject anonymous connections
|
||||
smtpd_sasl_security_options = noanonymous
|
||||
smtpd_sasl_local_domain =
|
||||
|
||||
|
||||
# Wait until the RCPT TO command before evaluating restrictions
|
||||
smtpd_delay_reject = yes
|
||||
|
||||
# Basics Restrictions
|
||||
smtpd_helo_required = yes
|
||||
strict_rfc821_envelopes = yes
|
||||
|
||||
# Requirements for the connecting server
|
||||
smtpd_client_restrictions =
|
||||
permit_mynetworks,
|
||||
permit_sasl_authenticated,
|
||||
reject_rbl_client bl.spamcop.net,
|
||||
reject_rbl_client cbl.abuseat.org,
|
||||
reject_rbl_client zen.spamhaus.org,
|
||||
permit
|
||||
|
||||
# Requirements for the HELO statement
|
||||
smtpd_helo_restrictions =
|
||||
permit_mynetworks,
|
||||
permit_sasl_authenticated,
|
||||
reject_non_fqdn_hostname,
|
||||
reject_invalid_hostname,
|
||||
permit
|
||||
|
||||
# Requirements for the sender address
|
||||
# Wait until the RCPT TO command before evaluating restrictions
|
||||
smtpd_delay_reject = yes
|
||||
|
||||
# Basics Restrictions
|
||||
smtpd_helo_required = yes
|
||||
strict_rfc821_envelopes = yes
|
||||
|
||||
# Requirements for the connecting server
|
||||
smtpd_client_restrictions =
|
||||
permit_mynetworks,
|
||||
permit_sasl_authenticated,
|
||||
reject_rbl_client bl.spamcop.net,
|
||||
reject_rbl_client cbl.abuseat.org,
|
||||
reject_rbl_client zen.spamhaus.org,
|
||||
permit
|
||||
|
||||
# Requirements for the HELO statement
|
||||
smtpd_helo_restrictions =
|
||||
permit_mynetworks,
|
||||
permit_sasl_authenticated,
|
||||
reject_non_fqdn_hostname,
|
||||
reject_invalid_hostname,
|
||||
permit
|
||||
|
||||
# Requirements for the sender address
|
||||
smtpd_sender_restrictions =
|
||||
reject_sender_login_mismatch,
|
||||
permit_mynetworks,
|
||||
permit_sasl_authenticated,
|
||||
reject_non_fqdn_sender,
|
||||
reject_sender_login_mismatch,
|
||||
permit_mynetworks,
|
||||
permit_sasl_authenticated,
|
||||
reject_non_fqdn_sender,
|
||||
reject_unknown_sender_domain,
|
||||
permit
|
||||
|
||||
# Requirement for the recipient address
|
||||
smtpd_recipient_restrictions =
|
||||
permit_mynetworks,
|
||||
permit_sasl_authenticated,
|
||||
reject_non_fqdn_recipient,
|
||||
reject_unknown_recipient_domain,
|
||||
permit
|
||||
|
||||
# Requirement for the recipient address
|
||||
smtpd_recipient_restrictions =
|
||||
permit_mynetworks,
|
||||
permit_sasl_authenticated,
|
||||
reject_non_fqdn_recipient,
|
||||
reject_unknown_recipient_domain,
|
||||
reject_unauth_destination,
|
||||
permit
|
||||
|
||||
|
@ -154,3 +158,13 @@ smtpd_milters = inet:localhost:11332
|
|||
|
||||
# Skip email without checking if milter has died
|
||||
milter_default_action = accept
|
||||
|
||||
# Avoid to send simultaneously too many emails
|
||||
smtp_destination_concurrency_limit = 1
|
||||
default_destination_rate_delay = 5s
|
||||
|
||||
# Avoid email adress scanning
|
||||
# By default it's possible to detect if the email adress exist
|
||||
# So it's easly possible to scan a server to know which email adress is valid
|
||||
# and after to send spam
|
||||
disable_vrfy_command = yes
|
|
@ -64,9 +64,13 @@ suffix "dc=yunohost,dc=org"
|
|||
directory "/var/lib/ldap"
|
||||
|
||||
# Indexing options for database #1
|
||||
index objectClass eq
|
||||
index uid eq,sub
|
||||
index entryCSN,entryUUID eq
|
||||
index objectClass eq
|
||||
index uid,sudoUser eq,sub
|
||||
index entryCSN,entryUUID eq
|
||||
index cn,mail eq
|
||||
index gidNumber,uidNumber eq
|
||||
index member,memberUid,uniqueMember eq
|
||||
index virtualdomain eq
|
||||
|
||||
# Save the time that the entry gets modified, for database #1
|
||||
lastmod on
|
||||
|
|
47
debian/changelog
vendored
47
debian/changelog
vendored
|
@ -1,3 +1,48 @@
|
|||
yunohost (3.6.0) testing; urgency=low
|
||||
|
||||
## Major changes
|
||||
|
||||
- [enh] Simplify the whole LDAP interface thing (#721)
|
||||
- [enh] Rework how system upgrade is handled (#692)
|
||||
- [enh] Properly reimplement bash completion for yunohost cli (#678)
|
||||
- [enh] Migrate to apps.json / use it as default list (#666, #665)
|
||||
- [enh] Decouple the regen-conf mechanism from services (#653)
|
||||
- [i18n] Update translations for Catalan, Occitan, French, Italian, Spanish, Arabic
|
||||
|
||||
## App helpers
|
||||
|
||||
- [mod] Set min version to 3.5.0 for helpers (#725)
|
||||
- [enh] Add helpers for sso config (#720)
|
||||
- [enh] Reorganize helpers (#717)
|
||||
- [enh] Add the ongoing part to the progression bar when using ynh_script_progression (#715)
|
||||
- [fix] postgresql helpers : force disconnection of all clients connected to the database (#713)
|
||||
- [enh] Use printers in helpers (#712)
|
||||
- [enh] Use ynh_systemd_action in helpers (#711)
|
||||
- [fix] Fix extraction of weight value for ynh_script_progression (#710)
|
||||
- [enh] Add support for ynh_setup_source in restore script (#703)
|
||||
|
||||
# Other changes
|
||||
|
||||
- [fix] Update censurfridns ipv6 (#727)
|
||||
- [enh] Optimize ynh_script_progression (#723)
|
||||
- [enh] Disable VRFY command in Postfix command (#722)
|
||||
- [enh] Add a --with-details option for log list (#716)
|
||||
- [enh] Specify -a parameter on dovecot lda for Sieve (#709)
|
||||
- [fix] Fix an issue with config panels following changes in hook_exec (#707)
|
||||
- [enh] Don't expose LDAP server to the outside world (#706)
|
||||
- [fix] Remove backup hook warning about cron file (#704)
|
||||
- [enh] Update nginx conf to handle WebSocket proxying (#701)
|
||||
- [enh] Add size of apps in backup_info result (#699)
|
||||
- [enh] Add a setting to remove support for TLSv1 and TLSv1.1 in Postfix (#696)
|
||||
- [enh] Mark YunoHost as essential to avoid removing it inadvertenly (#694)
|
||||
- [enh] Avoid to send simultaneously too many emails (#691)
|
||||
- [enh] Dump log when an app script fails in CLI to help with debugging (#687)
|
||||
- [fix] Many small technical fixes (ec48edf,251a338,d11d31d,3668bf7,c7eb5bb,9b08afc,cecaee4,95fdfb3,2bc0deb)
|
||||
|
||||
Thanks to all contributors : Aleks, Benoît, Bram, ButterflyOfFire, C. Vuillot, Josue, J. Maulny, Kayou, L. Noferini, Maniack, M. Thiel, Quentí, R. du Song, Sylkevicious, ljf, xaloc33, yalh76 ! <3
|
||||
|
||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Wed, 22 May 2019 19:10:00 +0000
|
||||
|
||||
yunohost (3.5.2.2) stable; urgency=low
|
||||
|
||||
- Hotfix for ynh_psql_remove_db (from ljf)
|
||||
|
@ -17,7 +62,7 @@ yunohost (3.5.2) stable; urgency=low
|
|||
- [i18n] Update translations for Catalan, Arabic, Italian
|
||||
|
||||
Thanks to all contributors: Aleks, xaloc, BoF, silkevicious ! <3
|
||||
|
||||
|
||||
-- Alexandre Aubin <alex.aubin@mailoo.org> Wed, 10 Apr 2019 01:53:00 +0000
|
||||
|
||||
yunohost (3.5.1.1) testing; urgency=low
|
||||
|
|
2
debian/control
vendored
2
debian/control
vendored
|
@ -2,7 +2,7 @@ Source: yunohost
|
|||
Section: utils
|
||||
Priority: extra
|
||||
Maintainer: YunoHost Contributors <contrib@yunohost.org>
|
||||
Build-Depends: debhelper (>=9), dh-systemd, dh-python, python-all (>= 2.7)
|
||||
Build-Depends: debhelper (>=9), dh-systemd, dh-python, python-all (>= 2.7), python-yaml
|
||||
Standards-Version: 3.9.6
|
||||
X-Python-Version: >= 2.7
|
||||
Homepage: https://yunohost.org/
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
"appslist_corrupted_json": "Could not load the application lists. It looks like {filename:s} is corrupted.",
|
||||
"appslist_could_not_migrate": "Could not migrate app list {appslist:s} ! Unable to parse the url... The old cron job has been kept in {bkp_file:s}.",
|
||||
"appslist_fetched": "تم جلب قائمة تطبيقات {appslist:s}",
|
||||
"appslist_migrating": "Migrating application list {appslist:s} ...",
|
||||
"appslist_migrating": "Migrating application list {appslist:s} …",
|
||||
"appslist_name_already_tracked": "There is already a registered application list with name {name:s}.",
|
||||
"appslist_removed": "تم حذف قائمة البرمجيات {appslist:s}",
|
||||
"appslist_retrieve_bad_format": "Retrieved file for application list {appslist:s} is not valid",
|
||||
|
@ -61,10 +61,10 @@
|
|||
"backup_abstract_method": "This backup method hasn't yet been implemented",
|
||||
"backup_action_required": "You must specify something to save",
|
||||
"backup_app_failed": "Unable to back up the app '{app:s}'",
|
||||
"backup_applying_method_borg": "Sending all files to backup into borg-backup repository...",
|
||||
"backup_applying_method_borg": "Sending all files to backup into borg-backup repository…",
|
||||
"backup_applying_method_copy": "جارٍ نسخ كافة الملفات إلى النسخة الإحتياطية …",
|
||||
"backup_applying_method_custom": "Calling the custom backup method '{method:s}'...",
|
||||
"backup_applying_method_tar": "Creating the backup tar archive...",
|
||||
"backup_applying_method_custom": "Calling the custom backup method '{method:s}'…",
|
||||
"backup_applying_method_tar": "جارٍ إنشاء ملف tar للنسخة الاحتياطية…",
|
||||
"backup_archive_app_not_found": "App '{app:s}' not found in the backup archive",
|
||||
"backup_archive_broken_link": "Unable to access backup archive (broken link to {path:s})",
|
||||
"backup_archive_mount_failed": "Mounting the backup archive failed",
|
||||
|
@ -80,7 +80,7 @@
|
|||
"backup_copying_to_organize_the_archive": "Copying {size:s}MB to organize the archive",
|
||||
"backup_couldnt_bind": "Couldn't bind {src:s} to {dest:s}.",
|
||||
"backup_created": "تم إنشاء النسخة الإحتياطية",
|
||||
"backup_creating_archive": "Creating the backup archive...",
|
||||
"backup_creating_archive": "جارٍ إنشاء ملف النسخة الاحتياطية…",
|
||||
"backup_creation_failed": "Backup creation failed",
|
||||
"backup_csv_addition_failed": "Unable to add files to backup into the CSV file",
|
||||
"backup_csv_creation_failed": "Unable to create the CSV file needed for future restore operations",
|
||||
|
@ -89,7 +89,7 @@
|
|||
"backup_custom_need_mount_error": "Custom backup method failure on 'need_mount' step",
|
||||
"backup_delete_error": "Unable to delete '{path:s}'",
|
||||
"backup_deleted": "The backup has been deleted",
|
||||
"backup_extracting_archive": "Extracting the backup archive...",
|
||||
"backup_extracting_archive": "Extracting the backup archive…",
|
||||
"backup_hook_unknown": "Backup hook '{hook:s}' unknown",
|
||||
"backup_invalid_archive": "نسخة إحتياطية غير صالحة",
|
||||
"backup_method_borg_finished": "Backup into borg finished",
|
||||
|
@ -103,7 +103,7 @@
|
|||
"backup_output_directory_required": "يتوجب عليك تحديد مجلد لتلقي النسخ الإحتياطية",
|
||||
"backup_output_symlink_dir_broken": "You have a broken symlink instead of your archives directory '{path:s}'. You may have a specific setup to backup your data on an other filesystem, in this case you probably forgot to remount or plug your hard dirve or usb key.",
|
||||
"backup_running_app_script": "Running backup script of app '{app:s}'...",
|
||||
"backup_running_hooks": "Running backup hooks...",
|
||||
"backup_running_hooks": "Running backup hooks…",
|
||||
"backup_system_part_failed": "Unable to backup the '{part:s}' system part",
|
||||
"backup_unable_to_organize_files": "Unable to organize files in the archive with the quick method",
|
||||
"backup_with_no_backup_script_for_app": "App {app:s} has no backup script. Ignoring.",
|
||||
|
@ -117,7 +117,7 @@
|
|||
"certmanager_cert_install_success_selfsigned": "Successfully installed a self-signed certificate for domain {domain:s}!",
|
||||
"certmanager_cert_renew_success": "نجحت عملية تجديد شهادة Let's Encrypt الخاصة باسم النطاق {domain:s} !",
|
||||
"certmanager_cert_signing_failed": "فشل إجراء توقيع الشهادة الجديدة",
|
||||
"certmanager_certificate_fetching_or_enabling_failed": "Sounds like enabling the new certificate for {domain:s} failed somehow...",
|
||||
"certmanager_certificate_fetching_or_enabling_failed": "Sounds like enabling the new certificate for {domain:s} failed somehow…",
|
||||
"certmanager_conflicting_nginx_file": "Unable to prepare domain for ACME challenge: the nginx configuration file {filepath:s} is conflicting and should be removed first",
|
||||
"certmanager_couldnt_fetch_intermediate_cert": "Timed out when trying to fetch intermediate certificate from Let's Encrypt. Certificate installation/renewal aborted - please try again later.",
|
||||
"certmanager_domain_cert_not_selfsigned": "The certificate for domain {domain:s} is not self-signed. Are you sure you want to replace it? (Use --force)",
|
||||
|
@ -174,8 +174,8 @@
|
|||
"dyndns_registration_failed": "Unable to register DynDNS domain: {error:s}",
|
||||
"dyndns_domain_not_provided": "Dyndns provider {provider:s} cannot provide domain {domain:s}.",
|
||||
"dyndns_unavailable": "Domain {domain:s} is not available.",
|
||||
"executing_command": "Executing command '{command:s}'...",
|
||||
"executing_script": "Executing script '{script:s}'...",
|
||||
"executing_command": "Executing command '{command:s}'…",
|
||||
"executing_script": "Executing script '{script:s}'…",
|
||||
"extracting": "عملية فك الضغط جارية …",
|
||||
"field_invalid": "Invalid field '{:s}'",
|
||||
"firewall_reload_failed": "Unable to reload the firewall",
|
||||
|
@ -216,7 +216,7 @@
|
|||
"migrate_tsig_end": "Migration to hmac-sha512 finished",
|
||||
"migrate_tsig_failed": "Migrating the dyndns domain {domain} to hmac-sha512 failed, rolling back. Error: {error_code} - {error}",
|
||||
"migrate_tsig_start": "Not secure enough key algorithm detected for TSIG signature of domain '{domain}', initiating migration to the more secure one hmac-sha512",
|
||||
"migrate_tsig_wait": "Let's wait 3min for the dyndns server to take the new key into account...",
|
||||
"migrate_tsig_wait": "لننتظر الآن 3 دقائق ريثما يأخذ خادم أسماء النطاقات الديناميكية بعين الاعتبار المفتاح الجديد…",
|
||||
"migrate_tsig_wait_2": "دقيقتين …",
|
||||
"migrate_tsig_wait_3": "دقيقة واحدة …",
|
||||
"migrate_tsig_wait_4": "30 ثانية …",
|
||||
|
@ -227,12 +227,12 @@
|
|||
"migrations_current_target": "Migration target is {}",
|
||||
"migrations_error_failed_to_load_migration": "ERROR: failed to load migration {number} {name}",
|
||||
"migrations_forward": "Migrating forward",
|
||||
"migrations_loading_migration": "Loading migration {number} {name}...",
|
||||
"migrations_loading_migration": "Loading migration {number} {name}…",
|
||||
"migrations_migration_has_failed": "Migration {number} {name} has failed with exception {exception}, aborting",
|
||||
"migrations_no_migrations_to_run": "No migrations to run",
|
||||
"migrations_show_currently_running_migration": "Running migration {number} {name}...",
|
||||
"migrations_show_currently_running_migration": "Running migration {number} {name}…",
|
||||
"migrations_show_last_migration": "Last ran migration is {}",
|
||||
"migrations_skip_migration": "Skipping migration {number} {name}...",
|
||||
"migrations_skip_migration": "جارٍ تجاهل التهجير {number} {name}…",
|
||||
"monitor_disabled": "The server monitoring has been disabled",
|
||||
"monitor_enabled": "The server monitoring has been enabled",
|
||||
"monitor_glances_con_failed": "Unable to connect to Glances server",
|
||||
|
@ -283,7 +283,7 @@
|
|||
"restore_cleaning_failed": "Unable to clean-up the temporary restoration directory",
|
||||
"restore_complete": "Restore complete",
|
||||
"restore_confirm_yunohost_installed": "Do you really want to restore an already installed system? [{answers:s}]",
|
||||
"restore_extracting": "فك الضغط عن الملفات التي نحتاجها من النسخة الإحتياطية ...",
|
||||
"restore_extracting": "جارٍ فك الضغط عن الملفات التي نحتاجها من النسخة الاحتياطية…",
|
||||
"restore_failed": "Unable to restore the system",
|
||||
"restore_hook_unavailable": "Restoration script for '{part:s}' not available on your system and not in the archive either",
|
||||
"restore_may_be_not_enough_disk_space": "Your system seems not to have enough disk space (freespace: {free_space:d} B, needed space: {needed_space:d} B, security margin: {margin:d} B)",
|
||||
|
@ -291,8 +291,8 @@
|
|||
"restore_not_enough_disk_space": "Not enough disk space (freespace: {free_space:d} B, needed space: {needed_space:d} B, security margin: {margin:d} B)",
|
||||
"restore_nothings_done": "Nothing has been restored",
|
||||
"restore_removing_tmp_dir_failed": "Unable to remove an old temporary directory",
|
||||
"restore_running_app_script": "Running restore script of app '{app:s}'...",
|
||||
"restore_running_hooks": "Running restoration hooks...",
|
||||
"restore_running_app_script": "Running restore script of app '{app:s}'…",
|
||||
"restore_running_hooks": "Running restoration hooks…",
|
||||
"restore_system_part_failed": "Unable to restore the '{part:s}' system part",
|
||||
"server_shutdown": "سوف ينطفئ الخادوم",
|
||||
"server_shutdown_confirm": "سوف ينطفئ الخادوم حالا. متأكد ؟ [{answers:s}]",
|
||||
|
@ -366,9 +366,9 @@
|
|||
"yunohost_installing": "عملية تنصيب يونوهوست جارية …",
|
||||
"yunohost_not_installed": "إنَّ واي يونوهوست ليس مُنَصَّب أو هو مثبت حاليا بشكل خاطئ. قم بتنفيذ الأمر 'yunohost tools postinstall'",
|
||||
"migration_description_0003_migrate_to_stretch": "تحديث النظام إلى ديبيان ستريتش و واي يونوهوست 3.0",
|
||||
"migration_0003_patching_sources_list": "عملية تعديل ملف المصادر sources.lists جارية ...",
|
||||
"migration_0003_main_upgrade": "بداية عملية التحديث الأساسية ...",
|
||||
"migration_0003_fail2ban_upgrade": "بداية عملية تحديث fail2ban ...",
|
||||
"migration_0003_patching_sources_list": "عملية تصحيح ملف المصادر sources.lists جارية…",
|
||||
"migration_0003_main_upgrade": "بداية عملية التحديث الأساسية…",
|
||||
"migration_0003_fail2ban_upgrade": "بداية عملية تحديث fail2ban…",
|
||||
"migration_0003_not_jessie": "إن توزيعة ديبيان الحالية تختلف عن جيسي !",
|
||||
"migration_description_0002_migrate_to_tsig_sha256": "يقوم بتحسين أمان TSIG لنظام أسماء النطاقات الديناميكة باستخدام SHA512 بدلًا مِن MD5",
|
||||
"migration_0003_backward_impossible": "لا يُمكن إلغاء عملية الإنتقال إلى ستريتش.",
|
||||
|
|
|
@ -209,5 +209,73 @@
|
|||
"format_datetime_short": "%d/%m/%Y %H:%M",
|
||||
"global_settings_bad_choice_for_enum": "Opció pel paràmetre {setting:s} incorrecta, s'ha rebut «{choice:s}» però les opcions disponibles són: {available_choices:s}",
|
||||
"global_settings_bad_type_for_setting": "El tipus del paràmetre {setting:s} és incorrecte. S'ha rebut {received_type:s}, però s'esperava {expected_type:s}",
|
||||
"global_settings_cant_open_settings": "No s'ha pogut obrir el fitxer de configuració, raó: {reason:s}"
|
||||
"global_settings_cant_open_settings": "No s'ha pogut obrir el fitxer de configuració, raó: {reason:s}",
|
||||
"global_settings_cant_serialize_settings": "No s'ha pogut serialitzar les dades de configuració, raó: {reason:s}",
|
||||
"global_settings_cant_write_settings": "No s'ha pogut escriure el fitxer de configuració, raó: {reason:s}",
|
||||
"global_settings_key_doesnt_exists": "La clau « {settings_key:s} » no existeix en la configuració global, podeu veure totes les claus disponibles executant « yunohost settings list »",
|
||||
"global_settings_reset_success": "Èxit. S'ha fet una còpia de seguretat de la configuració anterior a {path:s}",
|
||||
"global_settings_setting_example_bool": "Exemple d'opció booleana",
|
||||
"global_settings_setting_example_enum": "Exemple d'opció de tipus enumeració",
|
||||
"global_settings_setting_example_int": "Exemple d'opció de tipus enter",
|
||||
"global_settings_setting_example_string": "Exemple d'opció de tipus cadena",
|
||||
"global_settings_setting_security_nginx_compatibility": "Solució de compromís entre compatibilitat i seguretat pel servidor web nginx. Afecta els criptògrafs (i altres aspectes relacionats amb la seguretat)",
|
||||
"global_settings_setting_security_password_admin_strength": "Robustesa de la contrasenya d'administrador",
|
||||
"global_settings_setting_security_password_user_strength": "Robustesa de la contrasenya de l'usuari",
|
||||
"global_settings_setting_security_ssh_compatibility": "Solució de compromís entre compatibilitat i seguretat pel servidor SSH. Afecta els criptògrafs (i altres aspectes relacionats amb la seguretat)",
|
||||
"global_settings_unknown_setting_from_settings_file": "Clau de configuració desconeguda: «{setting_key:s}», refusant-la i guardant-la a /etc/yunohost/settings-unknown.json",
|
||||
"global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Permetre la clau d'hoste DSA (obsolet) per la configuració del servei SSH",
|
||||
"global_settings_unknown_type": "Situació inesperada, la configuració {setting:s} sembla tenir el tipus {unknown_type:s} però no és un tipus reconegut pel sistema.",
|
||||
"good_practices_about_admin_password": "Esteu a punt de definir una nova contrasenya d'administrador. La contrasenya ha de tenir un mínim de 8 caràcters ; tot i que és de bona pràctica utilitzar una contrasenya més llarga (és a dir una frase de contrasenya) i/o utilitzar diferents tipus de caràcters (majúscules, minúscules, dígits i caràcters especials).",
|
||||
"hook_exec_failed": "No s'ha pogut executar l'script: {path:s}",
|
||||
"hook_exec_not_terminated": "L'execució de l'script « {path:s} » no s'ha acabat correctament",
|
||||
"hook_json_return_error": "No s'ha pogut llegir el retorn de l'script {path:s}. Error: {msg:s}. Contingut en brut: {raw_content}",
|
||||
"hook_list_by_invalid": "Propietat per llistar les accions invàlida",
|
||||
"hook_name_unknown": "Nom de script « {name:s} » desconegut",
|
||||
"installation_complete": "Instal·lació completada",
|
||||
"installation_failed": "Ha fallat la instal·lació",
|
||||
"invalid_url_format": "Format d'URL invàlid",
|
||||
"ip6tables_unavailable": "No podeu modificar les ip6tables aquí. O bé sou en un contenidor o bé el vostre nucli no és compatible amb aquesta opció",
|
||||
"iptables_unavailable": "No podeu modificar les iptables aquí. O bé sou en un contenidor o bé el vostre nucli no és compatible amb aquesta opció",
|
||||
"log_corrupted_md_file": "El fitxer de metadades yaml associat amb els registres està malmès: « {md_file} »",
|
||||
"log_category_404": "La categoria de registres « {category} » no existeix",
|
||||
"log_link_to_log": "El registre complet d'aquesta operació: «<a href=\"#/tools/logs/{name}\" style=\"text-decoration:underline\">{desc}</a>»",
|
||||
"log_help_to_get_log": "Per veure el registre de l'operació « {desc} », utilitzeu l'ordre « yunohost log display {name} »",
|
||||
"log_link_to_failed_log": "L'operació « {dec} » ha fallat! Per obtenir ajuda, <a href=\"#/tools/logs/{name}\">proveïu el registre complete de l'operació clicant aquí</a>",
|
||||
"log_help_to_get_failed_log": "L'operació « {dec} » ha fallat! Per obtenir ajuda, compartiu el registre complete de l'operació utilitzant l'ordre « yunohost log display {name} --share »",
|
||||
"log_does_exists": "No hi ha cap registre per l'operació amb el nom« {log} », utilitzeu « yunohost log list » per veure tots els registre d'operació disponibles",
|
||||
"log_operation_unit_unclosed_properly": "L'operació no s'ha tancat de forma correcta",
|
||||
"log_app_addaccess": "Afegir accés a « {} »",
|
||||
"log_app_removeaccess": "Suprimeix accés a « {} »",
|
||||
"log_app_clearaccess": "Suprimeix tots els accessos a « {} »",
|
||||
"log_app_fetchlist": "Afegeix una llista d'aplicacions",
|
||||
"log_app_removelist": "Elimina una llista d'aplicacions",
|
||||
"log_app_change_url": "Canvia l'URL de l'aplicació « {} »",
|
||||
"log_app_install": "Instal·la l'aplicació « {} »",
|
||||
"log_app_remove": "Elimina l'aplicació « {} »",
|
||||
"log_app_upgrade": "Actualitza l'aplicació « {} »",
|
||||
"log_app_makedefault": "Fes « {} » l'aplicació per defecte",
|
||||
"log_available_on_yunopaste": "Aquest registre està disponible via {url}",
|
||||
"log_backup_restore_system": "Restaura el sistema a partir d'una còpia de seguretat",
|
||||
"log_backup_restore_app": "Restaura « {} » a partir d'una còpia de seguretat",
|
||||
"log_remove_on_failed_restore": "Elimina « {} » després de que la restauració a partir de la còpia de seguretat hagi fallat",
|
||||
"log_remove_on_failed_install": "Elimina « {} » després de que la instal·lació hagi fallat",
|
||||
"log_domain_add": "Afegir el domini « {} » a la configuració del sistema",
|
||||
"log_domain_remove": "Elimina el domini « {} » de la configuració del sistema",
|
||||
"log_dyndns_subscribe": "Subscriure's a un subdomini YunoHost « {} »",
|
||||
"log_dyndns_update": "Actualitza la IP associada al subdomini YunoHost « {} »",
|
||||
"log_letsencrypt_cert_install": "Instal·la el certificat Let's Encrypt al domini « {} »",
|
||||
"log_selfsigned_cert_install": "Instal·la el certificat autosignat al domini « {} »",
|
||||
"log_letsencrypt_cert_renew": "Renova el certificat Let's Encrypt de « {} »",
|
||||
"log_service_enable": "Activa el servei « {} »",
|
||||
"log_regen_conf": "Regenera la configuració del sistema « {} »",
|
||||
"log_user_create": "Afegeix l'usuari « {} »",
|
||||
"log_user_delete": "Elimina l'usuari « {} »",
|
||||
"log_user_update": "Actualitza la informació de l'usuari « {} »",
|
||||
"log_tools_maindomain": "Fes de « {} » el domini principal",
|
||||
"log_tools_migrations_migrate_forward": "Migrar",
|
||||
"log_tools_migrations_migrate_backward": "Migrar endarrera",
|
||||
"log_tools_postinstall": "Fer la post instal·lació del servidor YunoHost",
|
||||
"log_tools_upgrade": "Actualitza els paquets Debian",
|
||||
"log_tools_shutdown": "Apaga el servidor",
|
||||
"log_tools_reboot": "Reinicia el servidor"
|
||||
}
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
"admin_password": "Administration password",
|
||||
"admin_password_change_failed": "Unable to change password",
|
||||
"admin_password_changed": "The administration password has been changed",
|
||||
"app_action_cannot_be_ran_because_required_services_down": "This app requires some services which are currently down. Before continuing, you should try to restart the following services (and possibly investigate why they are down) : {services}",
|
||||
"admin_password_too_long": "Please choose a password shorter than 127 characters",
|
||||
"already_up_to_date": "Nothing to do! Everything is already up to date!",
|
||||
"app_action_cannot_be_ran_because_required_services_down": "This app requires some services which are currently down. Before continuing, you should try to restart the following services (and possibly investigate why they are down) : {services}",
|
||||
"app_already_installed": "{app:s} is already installed",
|
||||
"app_already_installed_cant_change_url": "This app is already installed. The url cannot be changed just by this function. Look into `app changeurl` if it's available.",
|
||||
"app_already_up_to_date": "{app:s} is already up to date",
|
||||
|
@ -36,7 +37,7 @@
|
|||
"app_requirements_checking": "Checking required packages for {app}…",
|
||||
"app_requirements_failed": "Unable to meet requirements for {app}: {error}",
|
||||
"app_requirements_unmeet": "Requirements are not met for {app}, the package {pkgname} ({version}) must be {spec}",
|
||||
"app_sources_fetch_failed": "Unable to fetch sources files",
|
||||
"app_sources_fetch_failed": "Unable to fetch sources files, is the url correct?",
|
||||
"app_start_install": "Installing application {app}…",
|
||||
"app_start_remove": "Removing application {app}…",
|
||||
"app_start_backup": "Collecting files to be backuped for {app}…",
|
||||
|
@ -159,6 +160,7 @@
|
|||
"diagnosis_monitor_system_error": "Can't monitor system: {error}",
|
||||
"diagnosis_no_apps": "No installed application",
|
||||
"dpkg_is_broken": "You cannot do this right now because dpkg/apt (the system package managers) seems to be in a broken state... You can try to solve this issue by connecting through SSH and running `sudo dpkg --configure -a`.",
|
||||
"dpkg_lock_not_available": "This command can't be ran right now because another program seems to be using the lock of dpkg (the system package manager)",
|
||||
"dnsmasq_isnt_installed": "dnsmasq does not seem to be installed, please run 'apt-get remove bind9 && apt-get install dnsmasq'",
|
||||
"domain_cannot_remove_main": "Cannot remove main domain. Set a new main domain first",
|
||||
"domain_cert_gen_failed": "Unable to generate certificate",
|
||||
|
@ -222,6 +224,7 @@
|
|||
"global_settings_setting_security_password_admin_strength": "Admin password strength",
|
||||
"global_settings_setting_security_password_user_strength": "User password strength",
|
||||
"global_settings_setting_security_ssh_compatibility": "Compatibility vs. security tradeoff for the SSH server. Affects the ciphers (and other security-related aspects)",
|
||||
"global_settings_setting_security_postfix_compatibility": "Compatibility vs. security tradeoff for the Postfix server. Affects the ciphers (and other security-related aspects)",
|
||||
"global_settings_unknown_setting_from_settings_file": "Unknown key in settings: '{setting_key:s}', discarding it and save it in /etc/yunohost/settings-unknown.json",
|
||||
"global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Allow the use of (deprecated) DSA hostkey for the SSH daemon configuration",
|
||||
"global_settings_unknown_type": "Unexpected situation, the setting {setting:s} appears to have the type {unknown_type:s} but it's not a type supported by the system.",
|
||||
|
@ -296,7 +299,7 @@
|
|||
"log_tools_migrations_migrate_forward": "Migrate forward",
|
||||
"log_tools_migrations_migrate_backward": "Migrate backward",
|
||||
"log_tools_postinstall": "Postinstall your YunoHost server",
|
||||
"log_tools_upgrade": "Upgrade debian packages",
|
||||
"log_tools_upgrade": "Upgrade system packages",
|
||||
"log_tools_shutdown": "Shutdown your server",
|
||||
"log_tools_reboot": "Reboot your server",
|
||||
"ldap_init_failed_to_create_admin": "LDAP initialization failed to create admin user",
|
||||
|
@ -407,7 +410,6 @@
|
|||
"package_not_installed": "Package '{pkgname}' is not installed",
|
||||
"package_unexpected_error": "An unexpected error occurred processing the package '{pkgname}'",
|
||||
"package_unknown": "Unknown package '{pkgname}'",
|
||||
"packages_no_upgrade": "There is no package to upgrade",
|
||||
"packages_upgrade_critical_later": "Critical packages ({packages:s}) will be upgraded later",
|
||||
"packages_upgrade_failed": "Unable to upgrade all of the packages",
|
||||
"password_listed": "This password is among the most used password in the world. Please choose something a bit more unique.",
|
||||
|
@ -537,6 +539,15 @@
|
|||
"system_upgraded": "The system has been upgraded",
|
||||
"system_username_exists": "Username already exists in the system users",
|
||||
"this_action_broke_dpkg": "This action broke dpkg/apt (the system package managers)... You can try to solve this issue by connecting through SSH and running `sudo dpkg --configure -a`.",
|
||||
"tools_upgrade_at_least_one": "Please specify --apps OR --system",
|
||||
"tools_upgrade_cant_both": "Cannot upgrade both system and apps at the same time",
|
||||
"tools_upgrade_cant_hold_critical_packages": "Unable to hold critical packages ...",
|
||||
"tools_upgrade_cant_unhold_critical_packages": "Unable to unhold critical packages ...",
|
||||
"tools_upgrade_regular_packages": "Now upgrading 'regular' (non-yunohost-related) packages ...",
|
||||
"tools_upgrade_regular_packages_failed": "Unable to upgrade packages: {packages_list}",
|
||||
"tools_upgrade_special_packages": "Now upgrading 'special' (yunohost-related) packages ...",
|
||||
"tools_upgrade_special_packages_explanation": "This action will end but the actual special upgrade will continue in background. Please don't start any other action on your server in the next ~10 minutes (depending on your hardware speed). Once it's done, you may have to re-log on the webadmin. The upgrade log will be available in Tools > Log (in the webadmin) or through 'yunohost log list' (in command line).",
|
||||
"tools_upgrade_special_packages_completed": "YunoHost package upgrade completed !\nPress [Enter] to get the command line back",
|
||||
"unbackup_app": "App '{app:s}' will not be saved",
|
||||
"unexpected_error": "An unexpected error occured: {error}",
|
||||
"unit_unknown": "Unknown unit '{unit:s}'",
|
||||
|
@ -545,6 +556,7 @@
|
|||
"update_apt_cache_failed": "Unable to update the cache of APT (Debian's package manager). Here is a dump of the sources.list lines which might help to identify problematic lines : \n{sourceslist}",
|
||||
"update_apt_cache_warning": "Some errors happened while updating the cache of APT (Debian's package manager). Here is a dump of the sources.list lines which might help to identify problematic lines : \n{sourceslist}",
|
||||
"updating_apt_cache": "Fetching available upgrades for system packages…",
|
||||
"updating_app_lists": "Fetching available upgrades for applications…",
|
||||
"upgrade_complete": "Upgrade complete",
|
||||
"upgrading_packages": "Upgrading packages…",
|
||||
"upnp_dev_not_found": "No UPnP device found",
|
||||
|
|
|
@ -317,5 +317,11 @@
|
|||
"backup_with_no_restore_script_for_app": "La aplicación {app:s} no tiene script de restauración, no podrá restaurar automáticamente la copia de seguridad de esta aplicación.",
|
||||
"dyndns_could_not_check_provide": "No se pudo verificar si {provider:s} puede ofrecer {domain:s}.",
|
||||
"dyndns_domain_not_provided": "El proveedor Dyndns {provider:s} no puede proporcionar el dominio {domain:s}.",
|
||||
"experimental_feature": "Cuidado : esta funcionalidad es experimental y no es considerada estable, no debería usarla excepto si sabe lo que hace."
|
||||
"experimental_feature": "Cuidado : esta funcionalidad es experimental y no es considerada estable, no debería usarla excepto si sabe lo que hace.",
|
||||
"good_practices_about_user_password": "Está a punto de establecer una nueva contraseña de usuario. La contraseña debería de ser de al menos 8 caracteres, aunque es una buena práctica usar una contraseña más larga (es decir, una frase de paso) y/o usar varias clases de caracteres (mayúsculas, minúsculas, dígitos y caracteres especiales).",
|
||||
"password_listed": "Esta contraseña es una de las más usadas en el mundo. Elija algo un poco más único.",
|
||||
"password_too_simple_1": "La contraseña debe tener al menos 8 caracteres de longitud",
|
||||
"password_too_simple_2": "La contraseña debe tener al menos 8 caracteres de longitud y contiene dígitos, mayúsculas y minúsculas",
|
||||
"password_too_simple_3": "La contraseña debe tener al menos 8 caracteres de longitud y contiene dígitos, mayúsculas, minúsculas y caracteres especiales",
|
||||
"password_too_simple_4": "La contraseña debe tener al menos 12 caracteres de longitud y contiene dígitos, mayúsculas, minúsculas y caracteres especiales"
|
||||
}
|
||||
|
|
|
@ -458,7 +458,7 @@
|
|||
"log_tools_migrations_migrate_forward": "Migrer vers",
|
||||
"log_tools_migrations_migrate_backward": "Revenir en arrière",
|
||||
"log_tools_postinstall": "Faire la post-installation de votre serveur YunoHost",
|
||||
"log_tools_upgrade": "Mise à jour des paquets Debian",
|
||||
"log_tools_upgrade": "Mettre à jour les paquets système",
|
||||
"log_tools_shutdown": "Éteindre votre serveur",
|
||||
"log_tools_reboot": "Redémarrer votre serveur",
|
||||
"mail_unavailable": "Cette adresse de courriel est réservée et doit être automatiquement attribuée au tout premier utilisateur",
|
||||
|
@ -522,5 +522,34 @@
|
|||
"service_restarted": "Le service '{service:s}' a été redémarré",
|
||||
"service_reload_or_restart_failed": "Impossible de recharger ou de redémarrer le service '{service:s}'\n\nJournaux historisés récents de ce service : {logs:s}",
|
||||
"service_reloaded_or_restarted": "Le service '{service:s}' a été rechargé ou redémarré",
|
||||
"this_action_broke_dpkg": "Cette action a laissé des paquets non configurés par dpkg/apt (les gestionnaires de paquets système). Vous pouvez essayer de résoudre ce problème en vous connectant via SSH et en exécutant `sudo dpkg --configure -a`."
|
||||
"this_action_broke_dpkg": "Cette action a laissé des paquets non configurés par dpkg/apt (les gestionnaires de paquets système). Vous pouvez essayer de résoudre ce problème en vous connectant via SSH et en exécutant `sudo dpkg --configure -a`.",
|
||||
"app_action_cannot_be_ran_because_required_services_down": "Cette application requiert certains services qui sont actuellement en pannes. Avant de continuer, vous devriez essayer de redémarrer les services suivant (et éventuellement rechercher pourquoi ils sont en panne) : {services}",
|
||||
"admin_password_too_long": "Choisissez un mot de passe de 127 caractères maximum.",
|
||||
"log_regen_conf": "Régénérer les configurations du système '{}'",
|
||||
"migration_0009_not_needed": "Cette migration semble avoir déjà été jouée ? On l'ignore.",
|
||||
"regenconf_file_backed_up": "Le fichier de configuration '{conf}' a été sauvegardé sous '{backup}'",
|
||||
"regenconf_file_copy_failed": "Impossible de copier le nouveau fichier de configuration '{new}' vers '{conf}'",
|
||||
"regenconf_file_manually_modified": "Le fichier de configuration '{conf}' a été modifié manuellement et ne sera pas mis à jour",
|
||||
"regenconf_file_manually_removed": "Le fichier de configuration '{conf}' a été supprimé manuellement et ne sera pas créé",
|
||||
"regenconf_file_remove_failed": "Impossible de supprimer le fichier de configuration '{conf}'",
|
||||
"regenconf_file_removed": "Le fichier de configuration '{conf}' a été supprimé",
|
||||
"regenconf_file_updated": "Le fichier de configuration '{conf}' a été mis à jour",
|
||||
"regenconf_now_managed_by_yunohost": "Le fichier de configuration '{conf}' est maintenant géré par YunoHost (catégorie {category}).",
|
||||
"regenconf_up_to_date": "La configuration est déjà à jour pour la catégorie « {catégorie} ».",
|
||||
"already_up_to_date": "Il n'y a rien à faire ! Tout est déjà à jour !",
|
||||
"global_settings_setting_security_nginx_compatibility": "Compatibilité vs. compromis sécuritaire pour le serveur web nginx. Affecte les cryptogrammes (et d'autres aspects liés à la sécurité)",
|
||||
"global_settings_setting_security_ssh_compatibility": "Compatibilité vs. compromis sécuritaire pour le serveur SSH. Affecte les cryptogrammes (et d'autres aspects liés à la sécurité)",
|
||||
"global_settings_setting_security_postfix_compatibility": "Compatibilité vs. compromis sécuritaire pour le serveur Postfix. Affecte les cryptogrammes (et d'autres aspects liés à la sécurité)",
|
||||
"migration_description_0009_decouple_regenconf_from_services": "Dissocier le mécanisme « regen-conf » des services",
|
||||
"migration_description_0010_migrate_to_apps_json": "Supprimer les listes d'applications obsolètes et utiliser la nouvelle liste unifiée « apps.json » à la place",
|
||||
"regenconf_file_kept_back": "Le fichier de configuration « {conf} » s'attendait à être supprimé par « regen-conf » (catégorie {catégorie}) mais a été conservé.",
|
||||
"regenconf_updated": "La configuration a été mise à jour pour la catégorie « {category} ».",
|
||||
"regenconf_would_be_updated": "La configuration aurait dû être mise à jour pour la catégorie « {category} ».",
|
||||
"regenconf_dry_pending_applying": "Vérification de la configuration en attente qui aurait été appliquée pour la catégorie « {category} ».",
|
||||
"regenconf_failed": "Impossible de régénérer la configuration pour la ou les catégorie(s) : « {categories} ».",
|
||||
"regenconf_pending_applying": "Appliquer la configuration en attente pour la catégorie « {catégorie} »…",
|
||||
"service_regen_conf_is_deprecated": "« yunohost service regen-conf » est obsolète ! Veuillez plutôt utiliser « yunohost tools regen-conf ».",
|
||||
"tools_upgrade_at_least_one": "Veuillez spécifier --apps OU --system",
|
||||
"tools_upgrade_cant_both": "Impossible de mettre à niveau le système et les applications en même temps",
|
||||
"tools_upgrade_cant_hold_critical_packages": "Impossibilité de maintenir les paquets critiques..."
|
||||
}
|
||||
|
|
118
locales/it.json
118
locales/it.json
|
@ -225,7 +225,7 @@
|
|||
"unit_unknown": "Unità '{unit:s}' sconosciuta",
|
||||
"unlimit": "Nessuna quota",
|
||||
"update_cache_failed": "Impossibile aggiornare la cache APT",
|
||||
"updating_apt_cache": "Recupero degli aggiornamenti disponibili per i pacchietti di sistema…",
|
||||
"updating_apt_cache": "Recupero degli aggiornamenti disponibili per i pacchetti di sistema…",
|
||||
"upgrade_complete": "Aggiornamento completo",
|
||||
"upnp_dev_not_found": "Nessuno supporto UPnP trovato",
|
||||
"upnp_disabled": "UPnP è stato disattivato",
|
||||
|
@ -321,5 +321,119 @@
|
|||
"password_too_simple_3": "La password deve essere lunga almeno 8 caratteri e contenere numeri, maiuscole e minuscole e simboli",
|
||||
"password_too_simple_4": "La password deve essere lunga almeno 12 caratteri e contenere numeri, maiuscole e minuscole",
|
||||
"users_available": "Utenti disponibili:",
|
||||
"yunohost_ca_creation_success": "L'autorità di certificazione locale è stata creata."
|
||||
"yunohost_ca_creation_success": "L'autorità di certificazione locale è stata creata.",
|
||||
"app_action_cannot_be_ran_because_required_services_down": "Questa app richiede alcuni servizi che attualmente non sono attivi. Prima di continuare, dovresti provare a riavviare i seguenti servizi (e possibilmente capire perchè questi non siano attivi) : {services}",
|
||||
"backup_output_symlink_dir_broken": "Hai un collegamento errato alla tua cartella di archiviazione '{path:s}'. Potresti avere delle impostazioni particolari per salvare i tuoi dati su un altro spazio, in questo caso probabilmente ti sei scordato di rimontare o collegare il tuo hard disk o la chiavetta usb.",
|
||||
"certmanager_conflicting_nginx_file": "Impossibile preparare il dominio per il controllo ACME: il file di configurazione nginx {filepath:s} è in conflitto e dovrebbe essere prima rimosso",
|
||||
"certmanager_couldnt_fetch_intermediate_cert": "Tempo scaduto durante il tentativo di recupero di un certificato intermedio da Let's Encrypt. Installazione/rinnovo non riuscito - per favore riprova più tardi.",
|
||||
"certmanager_domain_dns_ip_differs_from_public_ip": "Il valore DNS 'A' per il dominio {domain:s} è diverso dall'IP di questo server. Se hai modificato recentemente il tuo valore A, attendi che si propaghi (esistono online alcuni siti per il controllo della propagazione DNS). (Se sai cosa stai facendo, usa --no-checks per disabilitare quei controlli.)",
|
||||
"certmanager_domain_not_resolved_locally": "Il dominio {domain:s} non può essere risolto in locale dal server Yunohost. Questo può accadere se hai modificato recentemente il tuo valore DNS. Se così fosse, per favore aspetta qualche ora per far si che si propaghi. Se il problema persiste, prova ad aggiungere {domain:s} in /etc/hosts. (Se sai cosa stai facendo, usa --no-checks per disabilitare quei controlli.)",
|
||||
"certmanager_error_no_A_record": "Nessun valore DNS 'A' trovato per {domain:s}. Devi far puntare il tuo nome di dominio verso la tua macchina per essere in grado di installare un certificato Let's Encrypt! (Se sai cosa stai facendo, usa --no-checks per disabilitare quei controlli.)",
|
||||
"certmanager_hit_rate_limit": "Troppi certificati già rilasciati per l'esatta serie di dominii {domain:s} recentemente. Per favore riprova più tardi. Guarda https://letsencrypt.org/docs/rate-limits/ per maggiori dettagli",
|
||||
"certmanager_http_check_timeout": "Tempo scaduto durante il tentativo di contatto del tuo server a se stesso attraverso HTTP utilizzando l'indirizzo IP pubblico (dominio {domain:s} con ip {ip:s}). Potresti avere un problema di hairpinning o il firewall/router davanti al tuo server non è correttamente configurato.",
|
||||
"certmanager_no_cert_file": "Impossibile leggere il file di certificato per il dominio {domain:s} (file: {file:s})",
|
||||
"certmanager_self_ca_conf_file_not_found": "File di configurazione non trovato per l'autorità di autofirma (file: {file:s})",
|
||||
"certmanager_unable_to_parse_self_CA_name": "Impossibile analizzare il nome dell'autorità di autofirma (file: {file:s})",
|
||||
"confirm_app_install_warning": "Attenzione: questa applicazione potrebbe funzionare ma non è ben integrata in YunoHost. Alcune funzionalità come l'accesso unico e il backup/ripristino potrebbero non essere disponibili. Installare comunque? [{answers:s}] ",
|
||||
"confirm_app_install_danger": "ATTENZIONE! Questa applicazione è ancora sperimentale (se non esplicitamente non funzionante) e probabilmente potrebbe danneggiare il tuo sistema! Probabilmente NON dovresti installarla a meno che tu non sappia cosa stai facendo. Sicuro di volerti prendere questo rischio? [{answers:s}] ",
|
||||
"confirm_app_install_thirdparty": "ATTENZIONE! Installando applicazioni di terze parti potresti compromettere l'integrita e la sicurezza del tuo sistema. Probabilmente NON dovresti installarle a meno che tu non sappia cosa stai facendo. Sicuro di volerti prendere questo rischio? [{answers:s}] ",
|
||||
"dpkg_is_broken": "Non puoi eseguire questo ora perchè dpkg/apt (i gestori di pacchetti del sistema) sembrano essere in stato danneggiato... Puoi provare a risolvere il problema connettendoti via SSH ed eseguire `sudo dpkg --configure -a`.",
|
||||
"domain_cannot_remove_main": "Non è possibile rimuovere il dominio principale ora. Prima imposta un nuovo dominio principale",
|
||||
"domain_dns_conf_is_just_a_recommendation": "Questo comando ti mostra qual è la configurazione *raccomandata*. Non ti imposta la configurazione DNS al tuo posto. È tua responsabilità configurare la tua zona DNS nel tuo registrar in accordo con queste raccomandazioni.",
|
||||
"domain_dyndns_dynette_is_unreachable": "Impossibile raggiungere la dynette YunoHost, o il tuo YunHost non è correttamente connesso a internet o il server dynette non è attivo. Errore: {error}",
|
||||
"dyndns_could_not_check_provide": "Impossibile controllare se {provider:s} possano fornire {domain:s}.",
|
||||
"dyndns_could_not_check_available": "Impossibile controllare se {domain:s} è disponibile su {provider:s}.",
|
||||
"dyndns_domain_not_provided": "Il fornitore Dyndns {provider:s} non può fornire il dominio {domain:s}.",
|
||||
"experimental_feature": "Attenzione: questa funzionalità è sperimentale e non è considerata stabile, non dovresti utilizzarla a meno che tu non sappia cosa stai facendo.",
|
||||
"file_does_not_exist": "Il file {path:s} non esiste.",
|
||||
"global_settings_bad_choice_for_enum": "Scelta sbagliata per l'impostazione {setting:s}, ricevuta '{choice:s}' ma le scelte disponibili sono : {available_choices:s}",
|
||||
"global_settings_bad_type_for_setting": "Tipo errato per l'impostazione {setting:s}, ricevuto {received_type:s}, atteso {expected_type:s}",
|
||||
"global_settings_cant_open_settings": "Apertura del file delle impostazioni non riuscita, motivo: {reason:s}",
|
||||
"global_settings_cant_serialize_settings": "Serializzazione dei dati delle impostazioni non riuscita, motivo: {reason:s}",
|
||||
"global_settings_cant_write_settings": "Scrittura del file delle impostazioni non riuscita, motivo: {reason:s}",
|
||||
"global_settings_key_doesnt_exists": "La chiave '{settings_key:s}' non esiste nelle impostazioni globali, puoi vedere tutte le chiavi disponibili eseguendo 'yunohost settings list'",
|
||||
"global_settings_reset_success": "Successo. Le tue impostazioni precedenti sono state salvate in {path:s}",
|
||||
"global_settings_setting_example_bool": "Esempio di opzione booleana",
|
||||
"global_settings_setting_example_enum": "Esempio di opzione enum",
|
||||
"already_up_to_date": "Niente da fare! Tutto è già aggiornato!",
|
||||
"global_settings_setting_example_int": "Esempio di opzione int",
|
||||
"global_settings_setting_example_string": "Esempio di opzione string",
|
||||
"global_settings_setting_security_nginx_compatibility": "Bilanciamento tra compatibilità e sicurezza per il server web nginx. Riguarda gli algoritmi di cifratura (e altri aspetti legati alla sicurezza)",
|
||||
"global_settings_setting_security_password_admin_strength": "Complessità della password di amministratore",
|
||||
"global_settings_setting_security_password_user_strength": "Complessità della password utente",
|
||||
"global_settings_setting_security_ssh_compatibility": "Bilanciamento tra compatibilità e sicurezza per il server SSH. Riguarda gli algoritmi di cifratura (e altri aspetti legati alla sicurezza)",
|
||||
"global_settings_unknown_setting_from_settings_file": "Chiave sconosciuta nelle impostazioni: '{setting_key:s}', scartata e salvata in /etc/yunohost/settings-unknown.json",
|
||||
"global_settings_setting_service_ssh_allow_deprecated_dsa_hostkey": "Consenti l'uso del (deprecato) hostkey DSA per la configurazione del demone SSH",
|
||||
"global_settings_unknown_type": "Situazione inaspettata, l'impostazione {setting:s} sembra essere di tipo {unknown_type:s} ma non è un tipo supportato dal sistema.",
|
||||
"good_practices_about_admin_password": "Stai per definire una nuova password di amministratore. La password deve essere almeno di 8 caratteri - anche se è buona pratica utilizzare password più lunghe (es. una frase, una serie di parole) e/o utilizzare vari tipi di caratteri (maiuscole, minuscole, numeri e simboli).",
|
||||
"invalid_url_format": "Formato URL non valido",
|
||||
"log_corrupted_md_file": "Il file dei metadati yaml associato con i registri è corrotto: '{md_file}'",
|
||||
"log_category_404": "La categoria di registrazione '{category}' non esiste",
|
||||
"log_link_to_log": "Registro completo di questa operazione: '<a href=\"#/tools/logs/{name}\" style=\"text-decoration:underline\">{desc}</a>'",
|
||||
"log_help_to_get_log": "Per vedere il registro dell'operazione '{desc}', usa il comando 'yunohost log display {name}'",
|
||||
"global_settings_setting_security_postfix_compatibility": "Bilanciamento tra compatibilità e sicurezza per il server Postfix. Riguarda gli algoritmi di cifratura (e altri aspetti legati alla sicurezza)",
|
||||
"log_link_to_failed_log": "L'operazione '{desc}' è fallita! Per ottenere aiuto, per favore <a href=\"#/tools/logs/{name}\">fornisci il registro completo dell'operazione cliccando qui</a>",
|
||||
"log_help_to_get_failed_log": "L'operazione '{desc}' è fallita! Per ottenere aiuto, per favore condividi il registro completo dell'operazione utilizzando il comando 'yunohost log display {name} --share'",
|
||||
"log_does_exists": "Non esiste nessun registro delle operazioni chiamato '{log}', usa 'yunohost log list' per vedere tutti i registri delle operazioni disponibili",
|
||||
"log_app_addaccess": "Aggiungi accesso a '{}'",
|
||||
"log_app_removeaccess": "Rimuovi accesso a '{}'",
|
||||
"log_app_clearaccess": "Rimuovi tutti gli accessi a '{}'",
|
||||
"log_app_fetchlist": "Aggiungi un elenco di applicazioni",
|
||||
"log_app_removelist": "Rimuovi un elenco di applicazioni",
|
||||
"log_app_change_url": "Cambia l'url dell'applicazione '{}'",
|
||||
"log_app_install": "Installa l'applicazione '{}'",
|
||||
"log_app_remove": "Rimuovi l'applicazione '{}'",
|
||||
"log_app_upgrade": "Aggiorna l'applicazione '{}'",
|
||||
"log_app_makedefault": "Rendi predefinita l'applicazione '{}'",
|
||||
"log_available_on_yunopaste": "Questo registro è ora disponibile via {url}",
|
||||
"log_backup_restore_system": "Ripristina sistema da un archivio di backup",
|
||||
"log_backup_restore_app": "Ripristina '{}' da un archivio di backup",
|
||||
"log_remove_on_failed_restore": "Rimuovi '{}' dopo un ripristino fallito da un archivio di backup",
|
||||
"log_remove_on_failed_install": "Rimuovi '{}' dopo un'installazione fallita",
|
||||
"log_domain_add": "Aggiungi il dominio '{}' nella configurazione di sistema",
|
||||
"log_domain_remove": "Rimuovi il dominio '{}' dalla configurazione di sistema",
|
||||
"log_dyndns_subscribe": "Sottoscrivi un sottodominio YunoHost '{}'",
|
||||
"log_dyndns_update": "Aggiorna l'ip associato con il tuo sottodominio YunoHost '{}'",
|
||||
"log_letsencrypt_cert_install": "Installa un certificato Let's encrypt sul dominio '{}'",
|
||||
"log_selfsigned_cert_install": "Installa un certificato autofirmato sul dominio '{}'",
|
||||
"log_letsencrypt_cert_renew": "Rinnova il certificato Let's encrypt sul dominio '{}'",
|
||||
"log_service_enable": "Abilita il servizio '{}'",
|
||||
"log_regen_conf": "Rigenera configurazioni di sistema '{}'",
|
||||
"log_user_create": "Aggiungi l'utente '{}'",
|
||||
"log_user_delete": "Elimina l'utente '{}'",
|
||||
"log_user_update": "Aggiornate le informazioni dell'utente '{}'",
|
||||
"log_tools_maindomain": "Rendi '{}' dominio principale",
|
||||
"log_tools_migrations_migrate_forward": "Migra avanti",
|
||||
"log_tools_migrations_migrate_backward": "Migra indietro",
|
||||
"log_tools_postinstall": "Postinstallazione del tuo server YunoHost",
|
||||
"log_tools_upgrade": "Aggiornamento dei pacchetti di sistema",
|
||||
"log_tools_shutdown": "Spegni il tuo server",
|
||||
"log_tools_reboot": "Riavvia il tuo server",
|
||||
"mail_unavailable": "Questo indirizzo email è riservato e dovrebbe essere automaticamente assegnato al primo utente",
|
||||
"migrate_tsig_end": "Migrazione a hmac-sha512 terminata",
|
||||
"migrate_tsig_failed": "Migrazione del dominio dyndns {domain} verso hmac-sha512 fallita, torno indetro. Errore: {error_code} - {error}",
|
||||
"migrate_tsig_start": "Trovato un algoritmo di chiave non abbastanza sicuro per la firma TSIG del dominio '{domain}', inizio della migrazione verso la più sicura hmac-sha512",
|
||||
"migrate_tsig_wait": "Aspetta 3 minuti che il server dyndns prenda la nuova chiave in gestione…",
|
||||
"migrate_tsig_wait_2": "2 minuti…",
|
||||
"migrate_tsig_wait_3": "1 minuto…",
|
||||
"migrate_tsig_wait_4": "30 secondi…",
|
||||
"migrate_tsig_not_needed": "Non sembra tu stia utilizzando un dominio dyndns, quindi non è necessaria nessuna migrazione!",
|
||||
"migration_description_0001_change_cert_group_to_sslcert": "Cambia permessi del gruppo di certificati da 'metronome' a 'ssl-cert'",
|
||||
"migration_description_0002_migrate_to_tsig_sha256": "Migliora la sicurezza del TSIG dyndns utilizzando SHA512 invece di MD5",
|
||||
"migration_description_0003_migrate_to_stretch": "Aggiorna il sistema a Debian Stretch e YunoHost 3.0",
|
||||
"migration_description_0004_php5_to_php7_pools": "Riconfigura le PHP pools ad utilizzare PHP 7 invece di 5",
|
||||
"migration_description_0005_postgresql_9p4_to_9p6": "Migra i database da postgresql 9.4 a 9.6",
|
||||
"migration_description_0006_sync_admin_and_root_passwords": "Sincronizza password di amministratore e root",
|
||||
"migration_description_0010_migrate_to_apps_json": "Rimuovi gli elenchi di app deprecati ed usa invece il nuovo elenco unificato 'apps.json'",
|
||||
"migration_0003_backward_impossible": "La migrazione a Stretch non può essere annullata.",
|
||||
"migration_0003_start": "Migrazione a Stretch iniziata. I registri saranno disponibili in {logfile}.",
|
||||
"migration_0003_patching_sources_list": "Sistemando il file sources.lists…",
|
||||
"migration_0003_main_upgrade": "Iniziando l'aggiornamento principale…",
|
||||
"migration_0003_fail2ban_upgrade": "Iniziando l'aggiornamento di fail2ban…",
|
||||
"migration_0003_restoring_origin_nginx_conf": "Il tuo file /etc/nginx/nginx.conf è stato modificato in qualche modo. La migrazione lo riporterà al suo stato originale… Il file precedente sarà disponibile come {backup_dest}.",
|
||||
"migration_0003_yunohost_upgrade": "Iniziando l'aggiornamento dei pacchetti yunohost… La migrazione terminerà, ma l'aggiornamento attuale avverrà subito dopo. Dopo che l'operazione sarà completata, probabilmente dovrai riaccedere all'interfaccia di amministrazione.",
|
||||
"migration_0003_not_jessie": "La distribuzione attuale non è Jessie!",
|
||||
"migration_0003_system_not_fully_up_to_date": "Il tuo sistema non è completamente aggiornato. Per favore prima esegui un aggiornamento normale prima di migrare a stretch.",
|
||||
"this_action_broke_dpkg": "Questa azione ha danneggiato dpkg/apt (i gestori di pacchetti del sistema)… Puoi provare a risolvere questo problema connettendoti via SSH ed eseguendo `sudo dpkg --configure -a`.",
|
||||
"updating_app_lists": "Recupero degli aggiornamenti disponibili per le applicazioni…"
|
||||
}
|
||||
|
|
|
@ -247,7 +247,7 @@
|
|||
"firewall_reload_failed": "Impossible de recargar lo parafuòc",
|
||||
"firewall_reloaded": "Lo parafuòc es estat recargat",
|
||||
"firewall_rules_cmd_failed": "Unas règlas del parafuòc an fracassat. Per mai informacions, consultatz lo jornal.",
|
||||
"global_settings_bad_choice_for_enum": "La valor del paramètre {setting:s} es incorrècta. Recebut : {received_type:s}, esperat {expected_type:s}",
|
||||
"global_settings_bad_choice_for_enum": "La valor del paramètre {setting:s} es incorrècta. Recebut : {received_type:s}, mas las opcions esperadas son : {expected_type:s}",
|
||||
"global_settings_bad_type_for_setting": "Lo tipe del paramètre {setting:s} es incorrècte. Recebut : {received_type:s}, esperat {expected_type:s}",
|
||||
"global_settings_cant_write_settings": "Fracàs de l’escritura del fichièr de configuracion, rason : {reason:s}",
|
||||
"global_settings_setting_example_enum": "Exemple d’opcion de tipe enumeracion",
|
||||
|
@ -486,5 +486,10 @@
|
|||
"migration_description_0008_ssh_conf_managed_by_yunohost_step2": "Daissar YunoHost gerir la configuracion SSH (etapa 2, manuala)",
|
||||
"migration_0007_cancelled": "YunoHost a pas reüssit a melhorar lo biais de gerir la configuracion SSH.",
|
||||
"root_password_replaced_by_admin_password": "Lo senhal root es estat remplaçat pel senhal administrator.",
|
||||
"service_restarted": "Lo servici '{service:s}' es estat reaviat"
|
||||
"service_restarted": "Lo servici '{service:s}' es estat reaviat",
|
||||
"admin_password_too_long": "Causissètz un senhal d’almens 127 caractèrs",
|
||||
"migration_0007_cannot_restart": "SSH pòt pas èsser reavit aprèp aver ensajat d’anullar la migracion numèro 6.",
|
||||
"migrations_success": "Migracion {number} {name} reüssida !",
|
||||
"service_conf_now_managed_by_yunohost": "Lo fichièr de configuracion « {conf} » es ara gerit per YunoHost.",
|
||||
"service_reloaded": "Lo servici « {servici:s} » es estat tornat cargar"
|
||||
}
|
||||
|
|
|
@ -38,12 +38,12 @@ from collections import OrderedDict
|
|||
from datetime import datetime
|
||||
|
||||
from moulinette import msignals, m18n, msettings
|
||||
from yunohost.utils.error import YunohostError
|
||||
from moulinette.utils.log import getActionLogger
|
||||
from moulinette.utils.filesystem import read_json
|
||||
|
||||
from yunohost.service import service_log, service_status, _run_service_command
|
||||
from yunohost.utils import packages
|
||||
from yunohost.utils.error import YunohostError
|
||||
from yunohost.log import is_unit_operation, OperationLogger
|
||||
|
||||
logger = getActionLogger('yunohost.app')
|
||||
|
@ -384,7 +384,7 @@ def app_info(app, show_status=False, raw=False):
|
|||
return info
|
||||
|
||||
|
||||
def app_map(auth, app=None, raw=False, user=None):
|
||||
def app_map(app=None, raw=False, user=None):
|
||||
"""
|
||||
List apps by domain
|
||||
|
||||
|
@ -395,6 +395,7 @@ def app_map(auth, app=None, raw=False, user=None):
|
|||
|
||||
"""
|
||||
from yunohost.permission import user_permission_list
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
|
||||
apps = []
|
||||
result = {}
|
||||
|
@ -415,7 +416,8 @@ def app_map(auth, app=None, raw=False, user=None):
|
|||
if 'no_sso' in app_settings: # I don't think we need to check for the value here
|
||||
continue
|
||||
if user is not None:
|
||||
if not auth.search(base='ou=permission,dc=yunohost,dc=org',
|
||||
ldap = _get_ldap_interface()
|
||||
if not ldap.search(base='ou=permission,dc=yunohost,dc=org',
|
||||
filter='(&(objectclass=permissionYnh)(cn=main.%s)(inheritPermission=uid=%s,ou=users,dc=yunohost,dc=org))' % (app_id, user),
|
||||
attrs=['cn']):
|
||||
continue
|
||||
|
@ -437,7 +439,7 @@ def app_map(auth, app=None, raw=False, user=None):
|
|||
|
||||
|
||||
@is_unit_operation()
|
||||
def app_change_url(operation_logger, auth, app, domain, path):
|
||||
def app_change_url(operation_logger, app, domain, path):
|
||||
"""
|
||||
Modify the URL at which an application is installed.
|
||||
|
||||
|
@ -469,7 +471,7 @@ def app_change_url(operation_logger, auth, app, domain, path):
|
|||
raise YunohostError("app_change_url_identical_domains", domain=domain, path=path)
|
||||
|
||||
# Check the url is available
|
||||
conflicts = _get_conflicting_apps(auth, domain, path, ignore_app=app)
|
||||
conflicts = _get_conflicting_apps(domain, path, ignore_app=app)
|
||||
if conflicts:
|
||||
apps = []
|
||||
for path, app_id, app_label in conflicts:
|
||||
|
@ -485,7 +487,7 @@ def app_change_url(operation_logger, auth, app, domain, path):
|
|||
|
||||
# Retrieve arguments list for change_url script
|
||||
# TODO: Allow to specify arguments
|
||||
args_odict = _parse_args_from_manifest(manifest, 'change_url', auth=auth)
|
||||
args_odict = _parse_args_from_manifest(manifest, 'change_url')
|
||||
args_list = args_odict.values()
|
||||
args_list.append(app)
|
||||
|
||||
|
@ -539,10 +541,10 @@ def app_change_url(operation_logger, auth, app, domain, path):
|
|||
app_setting(app, 'domain', value=domain)
|
||||
app_setting(app, 'path', value=path)
|
||||
|
||||
permission_update(auth, app, permission="main", add_url=[domain+path], remove_url=[old_domain+old_path], sync_perm=True)
|
||||
permission_update(app, permission="main", add_url=[domain+path], remove_url=[old_domain+old_path], sync_perm=True)
|
||||
|
||||
# avoid common mistakes
|
||||
if _run_service_command("reload", "nginx") == False:
|
||||
if _run_service_command("reload", "nginx") is False:
|
||||
# grab nginx errors
|
||||
# the "exit 0" is here to avoid check_output to fail because 'nginx -t'
|
||||
# will return != 0 since we are in a failed state
|
||||
|
@ -558,7 +560,7 @@ def app_change_url(operation_logger, auth, app, domain, path):
|
|||
hook_callback('post_app_change_url', args=args_list, env=env_dict)
|
||||
|
||||
|
||||
def app_upgrade(auth, app=[], url=None, file=None):
|
||||
def app_upgrade(app=[], url=None, file=None):
|
||||
"""
|
||||
Upgrade app
|
||||
|
||||
|
@ -635,7 +637,7 @@ def app_upgrade(auth, app=[], url=None, file=None):
|
|||
|
||||
# Retrieve arguments list for upgrade script
|
||||
# TODO: Allow to specify arguments
|
||||
args_odict = _parse_args_from_manifest(manifest, 'upgrade', auth=auth)
|
||||
args_odict = _parse_args_from_manifest(manifest, 'upgrade')
|
||||
args_list = args_odict.values()
|
||||
args_list.append(app_instance_name)
|
||||
|
||||
|
@ -695,17 +697,13 @@ def app_upgrade(auth, app=[], url=None, file=None):
|
|||
if not_upgraded_apps:
|
||||
raise YunohostError('app_not_upgraded', apps=', '.join(not_upgraded_apps))
|
||||
|
||||
permission_sync_to_user(auth)
|
||||
permission_sync_to_user()
|
||||
|
||||
logger.success(m18n.n('upgrade_complete'))
|
||||
|
||||
# Return API logs if it is an API call
|
||||
if is_api:
|
||||
return {"log": service_log('yunohost-api', number="100").values()[0]}
|
||||
|
||||
|
||||
@is_unit_operation()
|
||||
def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on_failure=False, force=False):
|
||||
def app_install(operation_logger, app, label=None, args=None, no_remove_on_failure=False, force=False):
|
||||
"""
|
||||
Install apps
|
||||
|
||||
|
@ -719,9 +717,11 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
|
|||
if packages.dpkg_is_broken():
|
||||
raise YunohostError("dpkg_is_broken")
|
||||
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
from yunohost.hook import hook_add, hook_remove, hook_exec, hook_callback
|
||||
from yunohost.log import OperationLogger
|
||||
from yunohost.permission import permission_add, permission_update, permission_remove, permission_sync_to_user
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
# Fetch or extract sources
|
||||
try:
|
||||
|
@ -785,7 +785,7 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
|
|||
_check_services_status_for_app(manifest.get("services", []))
|
||||
|
||||
# Check if app can be forked
|
||||
instance_number = _installed_instance_number(auth, app_id, last=True) + 1
|
||||
instance_number = _installed_instance_number(app_id, last=True) + 1
|
||||
if instance_number > 1:
|
||||
if 'multi_instance' not in manifest or not is_true(manifest['multi_instance']):
|
||||
raise YunohostError('app_already_installed', app=app_id)
|
||||
|
@ -798,7 +798,7 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
|
|||
# Retrieve arguments list for install script
|
||||
args_dict = {} if not args else \
|
||||
dict(urlparse.parse_qsl(args, keep_blank_values=True))
|
||||
args_odict = _parse_args_from_manifest(manifest, 'install', args=args_dict, auth=auth)
|
||||
args_odict = _parse_args_from_manifest(manifest, 'install', args=args_dict)
|
||||
args_list = args_odict.values()
|
||||
args_list.append(app_instance_name)
|
||||
|
||||
|
@ -849,7 +849,7 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
|
|||
# Create permission before the install (useful if the install script redefine the permission)
|
||||
# Note that sync_perm is disabled to avoid triggering a whole bunch of code and messages
|
||||
# can't be sure that we don't have one case when it's needed
|
||||
permission_add(auth, app=app_instance_name, permission="main", sync_perm=False)
|
||||
permission_add(app=app_instance_name, permission="main", sync_perm=False)
|
||||
|
||||
# Execute the app install script
|
||||
install_retcode = 1
|
||||
|
@ -884,11 +884,11 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
|
|||
args=[app_instance_name], env=env_dict_remove
|
||||
)[0]
|
||||
# Remove all permission in LDAP
|
||||
result = auth.search(base='ou=permission,dc=yunohost,dc=org',
|
||||
result = ldap.search(base='ou=permission,dc=yunohost,dc=org',
|
||||
filter='(&(objectclass=permissionYnh)(cn=*.%s))' % app_instance_name, attrs=['cn'])
|
||||
permission_list = [p['cn'][0] for p in result]
|
||||
for l in permission_list:
|
||||
permission_remove(auth, app_instance_name, l.split('.')[0], force=True)
|
||||
permission_remove(app_instance_name, l.split('.')[0], force=True)
|
||||
|
||||
if remove_retcode != 0:
|
||||
msg = m18n.n('app_not_properly_removed',
|
||||
|
@ -902,7 +902,7 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
|
|||
shutil.rmtree(app_setting_path)
|
||||
shutil.rmtree(extracted_app_folder)
|
||||
|
||||
app_ssowatconf(auth)
|
||||
app_ssowatconf()
|
||||
|
||||
if packages.dpkg_is_broken():
|
||||
logger.error(m18n.n("this_action_broke_dpkg"))
|
||||
|
@ -934,9 +934,9 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
|
|||
domain = app_settings.get('domain', None)
|
||||
path = app_settings.get('path', None)
|
||||
if domain and path:
|
||||
permission_update(auth, app_instance_name, permission="main", add_url=[domain+path], sync_perm=False)
|
||||
permission_update(app_instance_name, permission="main", add_url=[domain+path], sync_perm=False)
|
||||
|
||||
permission_sync_to_user(auth)
|
||||
permission_sync_to_user()
|
||||
|
||||
logger.success(m18n.n('installation_complete'))
|
||||
|
||||
|
@ -944,7 +944,7 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on
|
|||
|
||||
|
||||
@is_unit_operation()
|
||||
def app_remove(operation_logger, auth, app):
|
||||
def app_remove(operation_logger, app):
|
||||
"""
|
||||
Remove app
|
||||
|
||||
|
@ -952,6 +952,7 @@ def app_remove(operation_logger, auth, app):
|
|||
app -- App(s) to delete
|
||||
|
||||
"""
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
from yunohost.hook import hook_exec, hook_remove, hook_callback
|
||||
from yunohost.permission import permission_remove, permission_sync_to_user
|
||||
if not _is_installed(app):
|
||||
|
@ -999,20 +1000,21 @@ def app_remove(operation_logger, auth, app):
|
|||
hook_remove(app)
|
||||
|
||||
# Remove all permission in LDAP
|
||||
result = auth.search(base='ou=permission,dc=yunohost,dc=org',
|
||||
ldap = _get_ldap_interface()
|
||||
result = ldap.search(base='ou=permission,dc=yunohost,dc=org',
|
||||
filter='(&(objectclass=permissionYnh)(cn=*.%s))' % app, attrs=['cn'])
|
||||
permission_list = [p['cn'][0] for p in result]
|
||||
for l in permission_list:
|
||||
permission_remove(auth, app, l.split('.')[0], force=True, sync_perm=False)
|
||||
permission_remove(app, l.split('.')[0], force=True, sync_perm=False)
|
||||
|
||||
permission_sync_to_user(auth)
|
||||
permission_sync_to_user()
|
||||
|
||||
if packages.dpkg_is_broken():
|
||||
raise YunohostError("this_action_broke_dpkg")
|
||||
|
||||
|
||||
@is_unit_operation(['permission','app'])
|
||||
def app_addaccess(operation_logger, auth, apps, users=[]):
|
||||
def app_addaccess(operation_logger, apps, users=[]):
|
||||
"""
|
||||
Grant access right to users (everyone by default)
|
||||
|
||||
|
@ -1023,7 +1025,7 @@ def app_addaccess(operation_logger, auth, apps, users=[]):
|
|||
"""
|
||||
from yunohost.permission import user_permission_update
|
||||
|
||||
permission = user_permission_update(operation_logger, auth, app=apps, permission="main", add_username=users)
|
||||
permission = user_permission_update(operation_logger, app=apps, permission="main", add_username=users)
|
||||
|
||||
result = {p : v['main']['allowed_users'] for p, v in permission['permissions'].items()}
|
||||
|
||||
|
@ -1031,7 +1033,7 @@ def app_addaccess(operation_logger, auth, apps, users=[]):
|
|||
|
||||
|
||||
@is_unit_operation(['permission','app'])
|
||||
def app_removeaccess(operation_logger, auth, apps, users=[]):
|
||||
def app_removeaccess(operation_logger, apps, users=[]):
|
||||
"""
|
||||
Revoke access right to users (everyone by default)
|
||||
|
||||
|
@ -1042,7 +1044,7 @@ def app_removeaccess(operation_logger, auth, apps, users=[]):
|
|||
"""
|
||||
from yunohost.permission import user_permission_update
|
||||
|
||||
permission = user_permission_update(operation_logger, auth, app=apps, permission="main", del_username=users)
|
||||
permission = user_permission_update(operation_logger, app=apps, permission="main", del_username=users)
|
||||
|
||||
result = {p : v['main']['allowed_users'] for p, v in permission['permissions'].items()}
|
||||
|
||||
|
@ -1050,7 +1052,7 @@ def app_removeaccess(operation_logger, auth, apps, users=[]):
|
|||
|
||||
|
||||
@is_unit_operation(['permission','app'])
|
||||
def app_clearaccess(operation_logger, auth, apps):
|
||||
def app_clearaccess(operation_logger, apps):
|
||||
"""
|
||||
Reset access rights for the app
|
||||
|
||||
|
@ -1060,7 +1062,7 @@ def app_clearaccess(operation_logger, auth, apps):
|
|||
"""
|
||||
from yunohost.permission import user_permission_clear
|
||||
|
||||
permission = user_permission_clear(operation_logger, auth, app=apps, permission="main")
|
||||
permission = user_permission_clear(operation_logger, app=apps, permission="main")
|
||||
|
||||
result = {p : v['main']['allowed_users'] for p, v in permission['permissions'].items()}
|
||||
|
||||
|
@ -1090,7 +1092,7 @@ def app_debug(app):
|
|||
|
||||
|
||||
@is_unit_operation()
|
||||
def app_makedefault(operation_logger, auth, app, domain=None):
|
||||
def app_makedefault(operation_logger, app, domain=None):
|
||||
"""
|
||||
Redirect domain root to an app
|
||||
|
||||
|
@ -1108,13 +1110,13 @@ def app_makedefault(operation_logger, auth, app, domain=None):
|
|||
if domain is None:
|
||||
domain = app_domain
|
||||
operation_logger.related_to.append(('domain', domain))
|
||||
elif domain not in domain_list(auth)['domains']:
|
||||
elif domain not in domain_list()['domains']:
|
||||
raise YunohostError('domain_unknown')
|
||||
|
||||
operation_logger.start()
|
||||
if '/' in app_map(auth, raw=True)[domain]:
|
||||
if '/' in app_map(raw=True)[domain]:
|
||||
raise YunohostError('app_make_default_location_already_used', app=app, domain=app_domain,
|
||||
other_app=app_map(auth, raw=True)[domain]["/"]["id"])
|
||||
other_app=app_map(raw=True)[domain]["/"]["id"])
|
||||
|
||||
try:
|
||||
with open('/etc/ssowat/conf.json.persistent') as json_conf:
|
||||
|
@ -1188,7 +1190,7 @@ def app_checkport(port):
|
|||
raise YunohostError('port_unavailable', port=int(port))
|
||||
|
||||
|
||||
def app_register_url(auth, app, domain, path):
|
||||
def app_register_url(app, domain, path):
|
||||
"""
|
||||
Book/register a web path for a given app
|
||||
|
||||
|
@ -1214,7 +1216,7 @@ def app_register_url(auth, app, domain, path):
|
|||
raise YunohostError('app_already_installed_cant_change_url')
|
||||
|
||||
# Check the url is available
|
||||
conflicts = _get_conflicting_apps(auth, domain, path)
|
||||
conflicts = _get_conflicting_apps(domain, path)
|
||||
if conflicts:
|
||||
apps = []
|
||||
for path, app_id, app_label in conflicts:
|
||||
|
@ -1231,7 +1233,7 @@ def app_register_url(auth, app, domain, path):
|
|||
app_setting(app, 'path', value=path)
|
||||
|
||||
|
||||
def app_checkurl(auth, url, app=None):
|
||||
def app_checkurl(url, app=None):
|
||||
"""
|
||||
Check availability of a web path
|
||||
|
||||
|
@ -1259,9 +1261,9 @@ def app_checkurl(auth, url, app=None):
|
|||
|
||||
domain, path = _normalize_domain_path(domain, path)
|
||||
|
||||
apps_map = app_map(auth, raw=True)
|
||||
apps_map = app_map(raw=True)
|
||||
|
||||
if domain not in domain_list(auth)['domains']:
|
||||
if domain not in domain_list()['domains']:
|
||||
raise YunohostError('domain_unknown')
|
||||
|
||||
if domain in apps_map:
|
||||
|
@ -1318,7 +1320,7 @@ def app_initdb(user, password=None, db=None, sql=None):
|
|||
logger.success(m18n.n('mysql_db_initialized'))
|
||||
|
||||
|
||||
def app_ssowatconf(auth):
|
||||
def app_ssowatconf():
|
||||
"""
|
||||
Regenerate SSOwat configuration file
|
||||
|
||||
|
@ -1329,7 +1331,7 @@ def app_ssowatconf(auth):
|
|||
from yunohost.permission import user_permission_list
|
||||
|
||||
main_domain = _get_maindomain()
|
||||
domains = domain_list(auth)['domains']
|
||||
domains = domain_list()['domains']
|
||||
|
||||
skipped_urls = []
|
||||
skipped_regex = []
|
||||
|
@ -1388,7 +1390,7 @@ def app_ssowatconf(auth):
|
|||
skipped_regex.append("^[^/]*/%.well%-known/autoconfig/mail/config%-v1%.1%.xml.*$")
|
||||
|
||||
permission = {}
|
||||
for a in user_permission_list(auth)['permissions'].values():
|
||||
for a in user_permission_list()['permissions'].values():
|
||||
for p in a.values():
|
||||
if 'URL' in p:
|
||||
for u in p['URL']:
|
||||
|
@ -1412,8 +1414,8 @@ def app_ssowatconf(auth):
|
|||
'protected_regex': protected_regex,
|
||||
'redirected_urls': redirected_urls,
|
||||
'redirected_regex': redirected_regex,
|
||||
'users': {username: app_map(auth, user=username)
|
||||
for username in user_list(auth)['users'].keys()},
|
||||
'users': {username: app_map(user=username)
|
||||
for username in user_list()['users'].keys()},
|
||||
'permission': permission,
|
||||
}
|
||||
|
||||
|
@ -1423,14 +1425,14 @@ def app_ssowatconf(auth):
|
|||
logger.success(m18n.n('ssowat_conf_generated'))
|
||||
|
||||
|
||||
def app_change_label(auth, app, new_label):
|
||||
def app_change_label(app, new_label):
|
||||
installed = _is_installed(app)
|
||||
if not installed:
|
||||
raise YunohostError('app_not_installed', app=app)
|
||||
|
||||
app_setting(app, "label", value=new_label)
|
||||
|
||||
app_ssowatconf(auth)
|
||||
app_ssowatconf()
|
||||
|
||||
|
||||
# actions todo list:
|
||||
|
@ -1948,7 +1950,7 @@ def _fetch_app_from_git(app):
|
|||
return manifest, extracted_app_folder
|
||||
|
||||
|
||||
def _installed_instance_number(auth, app, last=False):
|
||||
def _installed_instance_number(app, last=False):
|
||||
"""
|
||||
Check if application is installed and return instance number
|
||||
|
||||
|
@ -1980,7 +1982,7 @@ def _installed_instance_number(auth, app, last=False):
|
|||
|
||||
else:
|
||||
instance_number_list = []
|
||||
instances_dict = app_map(auth, app=app, raw=True)
|
||||
instances_dict = app_map(app=app, raw=True)
|
||||
for key, domain in instances_dict.items():
|
||||
for key, path in domain.items():
|
||||
instance_number_list.append(path['instance'])
|
||||
|
@ -2076,7 +2078,7 @@ def _check_manifest_requirements(manifest, app_instance_name):
|
|||
spec=spec, app=app_instance_name)
|
||||
|
||||
|
||||
def _parse_args_from_manifest(manifest, action, args={}, auth=None):
|
||||
def _parse_args_from_manifest(manifest, action, args={}):
|
||||
"""Parse arguments needed for an action from the manifest
|
||||
|
||||
Retrieve specified arguments for the action from the manifest, and parse
|
||||
|
@ -2095,10 +2097,10 @@ def _parse_args_from_manifest(manifest, action, args={}, auth=None):
|
|||
return OrderedDict()
|
||||
|
||||
action_args = manifest['arguments'][action]
|
||||
return _parse_action_args_in_yunohost_format(args, action_args, auth)
|
||||
return _parse_action_args_in_yunohost_format(args, action_args)
|
||||
|
||||
|
||||
def _parse_args_for_action(action, args={}, auth=None):
|
||||
def _parse_args_for_action(action, args={}):
|
||||
"""Parse arguments needed for an action from the actions list
|
||||
|
||||
Retrieve specified arguments for the action from the manifest, and parse
|
||||
|
@ -2119,10 +2121,10 @@ def _parse_args_for_action(action, args={}, auth=None):
|
|||
|
||||
action_args = action['arguments']
|
||||
|
||||
return _parse_action_args_in_yunohost_format(args, action_args, auth)
|
||||
return _parse_action_args_in_yunohost_format(args, action_args)
|
||||
|
||||
|
||||
def _parse_action_args_in_yunohost_format(args, action_args, auth=None):
|
||||
def _parse_action_args_in_yunohost_format(args, action_args):
|
||||
"""Parse arguments store in either manifest.json or actions.json
|
||||
"""
|
||||
from yunohost.domain import (domain_list, _get_maindomain,
|
||||
|
@ -2175,12 +2177,12 @@ def _parse_action_args_in_yunohost_format(args, action_args, auth=None):
|
|||
arg_default = _get_maindomain()
|
||||
ask_string += ' (default: {0})'.format(arg_default)
|
||||
msignals.display(m18n.n('domains_available'))
|
||||
for domain in domain_list(auth)['domains']:
|
||||
for domain in domain_list()['domains']:
|
||||
msignals.display("- {}".format(domain))
|
||||
|
||||
elif arg_type == 'user':
|
||||
msignals.display(m18n.n('users_available'))
|
||||
for user in user_list(auth)['users'].keys():
|
||||
for user in user_list()['users'].keys():
|
||||
msignals.display("- {}".format(user))
|
||||
|
||||
elif arg_type == 'password':
|
||||
|
@ -2216,11 +2218,11 @@ def _parse_action_args_in_yunohost_format(args, action_args, auth=None):
|
|||
|
||||
# Validate argument type
|
||||
if arg_type == 'domain':
|
||||
if arg_value not in domain_list(auth)['domains']:
|
||||
if arg_value not in domain_list()['domains']:
|
||||
raise YunohostError('app_argument_invalid', name=arg_name, error=m18n.n('domain_unknown'))
|
||||
elif arg_type == 'user':
|
||||
try:
|
||||
user_info(auth, arg_value)
|
||||
user_info(arg_value)
|
||||
except YunohostError as e:
|
||||
raise YunohostError('app_argument_invalid', name=arg_name, error=e)
|
||||
elif arg_type == 'app':
|
||||
|
@ -2261,7 +2263,7 @@ def _parse_action_args_in_yunohost_format(args, action_args, auth=None):
|
|||
domain, path = _normalize_domain_path(domain, path)
|
||||
|
||||
# Check the url is available
|
||||
conflicts = _get_conflicting_apps(auth, domain, path)
|
||||
conflicts = _get_conflicting_apps(domain, path)
|
||||
if conflicts:
|
||||
apps = []
|
||||
for path, app_id, app_label in conflicts:
|
||||
|
|
|
@ -816,14 +816,14 @@ class RestoreManager():
|
|||
|
||||
Public methods:
|
||||
set_targets(self, system_parts=[], apps=[])
|
||||
restore(self, auth)
|
||||
restore(self)
|
||||
|
||||
Usage:
|
||||
restore_manager = RestoreManager(name)
|
||||
|
||||
restore_manager.set_targets(None, ['wordpress__3'])
|
||||
|
||||
restore_manager.restore(auth)
|
||||
restore_manager.restore()
|
||||
|
||||
if restore_manager.success:
|
||||
logger.success(m18n.n('restore_complete'))
|
||||
|
@ -910,7 +910,7 @@ class RestoreManager():
|
|||
tools_postinstall(domain, 'Yunohost', True)
|
||||
|
||||
|
||||
def clean(self, auth):
|
||||
def clean(self):
|
||||
"""
|
||||
End a restore operations by cleaning the working directory and
|
||||
regenerate ssowat conf (if some apps were restored)
|
||||
|
@ -919,7 +919,7 @@ class RestoreManager():
|
|||
|
||||
successfull_apps = self.targets.list("apps", include=["Success", "Warning"])
|
||||
|
||||
permission_sync_to_user(auth, force=False)
|
||||
permission_sync_to_user(force=False)
|
||||
|
||||
if os.path.ismount(self.work_dir):
|
||||
ret = subprocess.call(["umount", self.work_dir])
|
||||
|
@ -1115,7 +1115,7 @@ class RestoreManager():
|
|||
# "Actual restore" (reverse step of the backup collect part) #
|
||||
#
|
||||
|
||||
def restore(self, auth):
|
||||
def restore(self):
|
||||
"""
|
||||
Restore the archive
|
||||
|
||||
|
@ -1129,10 +1129,10 @@ class RestoreManager():
|
|||
# Apply dirty patch to redirect php5 file on php7
|
||||
self._patch_backup_csv_file()
|
||||
|
||||
self._restore_system(auth)
|
||||
self._restore_apps(auth)
|
||||
self._restore_system()
|
||||
self._restore_apps()
|
||||
finally:
|
||||
self.clean(auth)
|
||||
self.clean()
|
||||
|
||||
def _patch_backup_csv_file(self):
|
||||
"""
|
||||
|
@ -1174,7 +1174,7 @@ class RestoreManager():
|
|||
logger.warning(m18n.n('backup_php5_to_php7_migration_may_fail',
|
||||
error=str(e)))
|
||||
|
||||
def _restore_system(self, auth):
|
||||
def _restore_system(self):
|
||||
""" Restore user and system parts """
|
||||
|
||||
system_targets = self.targets.list("system", exclude=["Skipped"])
|
||||
|
@ -1183,11 +1183,14 @@ class RestoreManager():
|
|||
if system_targets == []:
|
||||
return
|
||||
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
# Backup old permission for apps
|
||||
# We need to do that because in case of an app is installed we can't remove the permission for this app
|
||||
old_apps_permission = []
|
||||
try:
|
||||
old_apps_permission = auth.search('ou=permission,dc=yunohost,dc=org',
|
||||
old_apps_permission = ldap.search('ou=permission,dc=yunohost,dc=org',
|
||||
'(&(objectClass=permissionYnh)(!(cn=main.mail))(!(cn=main.metronome))(!(cn=main.sftp)))',
|
||||
['cn', 'objectClass', 'groupPermission', 'URL', 'gidNumber'])
|
||||
except:
|
||||
|
@ -1231,7 +1234,7 @@ class RestoreManager():
|
|||
|
||||
# Check if we need to do the migration 0009 : setup group and permission
|
||||
# Legacy code
|
||||
result = auth.search('ou=groups,dc=yunohost,dc=org',
|
||||
result = ldap.search('ou=groups,dc=yunohost,dc=org',
|
||||
'(&(objectclass=groupOfNamesYnh)(cn=all_users))',
|
||||
['cn'])
|
||||
if not result:
|
||||
|
@ -1240,13 +1243,13 @@ class RestoreManager():
|
|||
# Update LDAP schema restart slapd
|
||||
logger.info(m18n.n("migration_0011_update_LDAP_schema"))
|
||||
regen_conf(names=['slapd'], force=True)
|
||||
setup_group_permission.migrate_LDAP_db(auth)
|
||||
setup_group_permission.migrate_LDAP_db()
|
||||
|
||||
# Remove all permission for all app which sill in the LDAP
|
||||
for per in auth.search('ou=permission,dc=yunohost,dc=org',
|
||||
for per in ldap.search('ou=permission,dc=yunohost,dc=org',
|
||||
'(&(objectClass=permissionYnh)(!(cn=main.mail))(!(cn=main.metronome))(!(cn=main.sftp)))',
|
||||
['cn']):
|
||||
if not auth.remove('cn=%s,ou=permission' % per['cn'][0]):
|
||||
if not ldap.remove('cn=%s,ou=permission' % per['cn'][0]):
|
||||
raise YunohostError('permission_deletion_failed', permission=permission, app=app)
|
||||
|
||||
# Restore permission for the app which is installed
|
||||
|
@ -1256,20 +1259,20 @@ class RestoreManager():
|
|||
except:
|
||||
logger.warning(m18n.n('permission_name_not_valid', permission=per['cn'][0]))
|
||||
if _is_installed(app_name):
|
||||
if not auth.add('cn=%s,ou=permission' % per['cn'][0], per):
|
||||
if not ldap.add('cn=%s,ou=permission' % per['cn'][0], per):
|
||||
raise YunohostError('apps_permission_restoration_failed', permission=permission_name, app=app_name)
|
||||
|
||||
|
||||
def _restore_apps(self, auth):
|
||||
def _restore_apps(self):
|
||||
"""Restore all apps targeted"""
|
||||
|
||||
apps_targets = self.targets.list("apps", exclude=["Skipped"])
|
||||
|
||||
for app in apps_targets:
|
||||
print(app)
|
||||
self._restore_app(auth, app)
|
||||
self._restore_app(app)
|
||||
|
||||
def _restore_app(self, auth, app_instance_name):
|
||||
def _restore_app(self, app_instance_name):
|
||||
"""
|
||||
Restore an app
|
||||
|
||||
|
@ -1299,6 +1302,8 @@ class RestoreManager():
|
|||
from moulinette.utils.filesystem import read_ldif
|
||||
from yunohost.user import user_group_list
|
||||
from yunohost.permission import permission_remove
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
def copytree(src, dst, symlinks=False, ignore=None):
|
||||
for item in os.listdir(src):
|
||||
|
@ -1367,7 +1372,7 @@ class RestoreManager():
|
|||
filtred_entries = ['entryUUID', 'creatorsName', 'createTimestamp', 'entryCSN', 'structuralObjectClass',
|
||||
'modifiersName', 'modifyTimestamp', 'inheritPermission', 'memberUid']
|
||||
entries = read_ldif('%s/permission.ldif' % app_settings_in_archive, filtred_entries)
|
||||
group_list = user_group_list(auth, ['cn'])['groups']
|
||||
group_list = user_group_list(['cn'])['groups']
|
||||
for dn, entry in entries:
|
||||
# Remove the group which has been removed
|
||||
for group in entry['groupPermission']:
|
||||
|
@ -1375,12 +1380,12 @@ class RestoreManager():
|
|||
if group_name not in group_list:
|
||||
entry['groupPermission'].remove(group)
|
||||
print(entry)
|
||||
if not auth.add('cn=%s,ou=permission' % entry['cn'][0], entry):
|
||||
if not ldap.add('cn=%s,ou=permission' % entry['cn'][0], entry):
|
||||
raise YunohostError('apps_permission_restoration_failed', permission=permission_name, app=app_name)
|
||||
else:
|
||||
from yunohost.tools import _get_migration_by_name
|
||||
setup_group_permission = _get_migration_by_name("setup_group_permission")
|
||||
setup_group_permission.migrate_app_permission(auth, app=app_instance_name)
|
||||
setup_group_permission.migrate_app_permission(app=app_instance_name)
|
||||
|
||||
# Prepare env. var. to pass to script
|
||||
env_dict = self._get_env_var(app_instance_name)
|
||||
|
@ -1429,11 +1434,11 @@ class RestoreManager():
|
|||
shutil.rmtree(app_settings_new_path, ignore_errors=True)
|
||||
|
||||
# Remove all permission in LDAP
|
||||
result = auth.search(base='ou=permission,dc=yunohost,dc=org',
|
||||
result = ldap.search(base='ou=permission,dc=yunohost,dc=org',
|
||||
filter='(&(objectclass=permissionYnh)(cn=*.%s))' % app_instance_name, attrs=['cn'])
|
||||
permission_list = [p['cn'][0] for p in result]
|
||||
for l in permission_list:
|
||||
permission_remove(auth, app_instance_name, l.split('.')[0], force=True)
|
||||
permission_remove(app_instance_name, l.split('.')[0], force=True)
|
||||
|
||||
# TODO Cleaning app hooks
|
||||
else:
|
||||
|
@ -2168,7 +2173,7 @@ def backup_create(name=None, description=None, methods=[],
|
|||
}
|
||||
|
||||
|
||||
def backup_restore(auth, name, system=[], apps=[], force=False):
|
||||
def backup_restore(name, system=[], apps=[], force=False):
|
||||
"""
|
||||
Restore from a local backup archive
|
||||
|
||||
|
@ -2227,7 +2232,7 @@ def backup_restore(auth, name, system=[], apps=[], force=False):
|
|||
|
||||
logger.info(m18n.n("backup_mount_archive_for_restore"))
|
||||
restore_manager.mount()
|
||||
restore_manager.restore(auth)
|
||||
restore_manager.restore()
|
||||
|
||||
# Check if something has been restored
|
||||
if restore_manager.success:
|
||||
|
|
|
@ -86,7 +86,7 @@ DNS_RESOLVERS = [
|
|||
#
|
||||
|
||||
|
||||
def certificate_status(auth, domain_list, full=False):
|
||||
def certificate_status(domain_list, full=False):
|
||||
"""
|
||||
Print the status of certificate for given domains (all by default)
|
||||
|
||||
|
@ -99,10 +99,10 @@ def certificate_status(auth, domain_list, full=False):
|
|||
|
||||
# If no domains given, consider all yunohost domains
|
||||
if domain_list == []:
|
||||
domain_list = yunohost.domain.domain_list(auth)['domains']
|
||||
domain_list = yunohost.domain.domain_list()['domains']
|
||||
# Else, validate that yunohost knows the domains given
|
||||
else:
|
||||
yunohost_domains_list = yunohost.domain.domain_list(auth)['domains']
|
||||
yunohost_domains_list = yunohost.domain.domain_list()['domains']
|
||||
for domain in domain_list:
|
||||
# Is it in Yunohost domain list?
|
||||
if domain not in yunohost_domains_list:
|
||||
|
@ -126,7 +126,7 @@ def certificate_status(auth, domain_list, full=False):
|
|||
return {"certificates": certificates}
|
||||
|
||||
|
||||
def certificate_install(auth, domain_list, force=False, no_checks=False, self_signed=False, staging=False):
|
||||
def certificate_install(domain_list, force=False, no_checks=False, self_signed=False, staging=False):
|
||||
"""
|
||||
Install a Let's Encrypt certificate for given domains (all by default)
|
||||
|
||||
|
@ -142,7 +142,7 @@ def certificate_install(auth, domain_list, force=False, no_checks=False, self_si
|
|||
_certificate_install_selfsigned(domain_list, force)
|
||||
else:
|
||||
_certificate_install_letsencrypt(
|
||||
auth, domain_list, force, no_checks, staging)
|
||||
domain_list, force, no_checks, staging)
|
||||
|
||||
|
||||
def _certificate_install_selfsigned(domain_list, force=False):
|
||||
|
@ -237,7 +237,7 @@ def _certificate_install_selfsigned(domain_list, force=False):
|
|||
operation_logger.error(msg)
|
||||
|
||||
|
||||
def _certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=False, staging=False):
|
||||
def _certificate_install_letsencrypt(domain_list, force=False, no_checks=False, staging=False):
|
||||
import yunohost.domain
|
||||
|
||||
if not os.path.exists(ACCOUNT_KEY_FILE):
|
||||
|
@ -246,7 +246,7 @@ def _certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=F
|
|||
# If no domains given, consider all yunohost domains with self-signed
|
||||
# certificates
|
||||
if domain_list == []:
|
||||
for domain in yunohost.domain.domain_list(auth)['domains']:
|
||||
for domain in yunohost.domain.domain_list()['domains']:
|
||||
|
||||
status = _get_status(domain)
|
||||
if status["CA_type"]["code"] != "self-signed":
|
||||
|
@ -257,7 +257,7 @@ def _certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=F
|
|||
# Else, validate that yunohost knows the domains given
|
||||
else:
|
||||
for domain in domain_list:
|
||||
yunohost_domains_list = yunohost.domain.domain_list(auth)['domains']
|
||||
yunohost_domains_list = yunohost.domain.domain_list()['domains']
|
||||
if domain not in yunohost_domains_list:
|
||||
raise YunohostError('certmanager_domain_unknown', domain=domain)
|
||||
|
||||
|
@ -285,7 +285,7 @@ def _certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=F
|
|||
|
||||
operation_logger.start()
|
||||
|
||||
_configure_for_acme_challenge(auth, domain)
|
||||
_configure_for_acme_challenge(domain)
|
||||
_fetch_and_enable_new_certificate(domain, staging, no_checks=no_checks)
|
||||
_install_cron(no_checks=no_checks)
|
||||
|
||||
|
@ -300,7 +300,7 @@ def _certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=F
|
|||
operation_logger.error(msg)
|
||||
|
||||
|
||||
def certificate_renew(auth, domain_list, force=False, no_checks=False, email=False, staging=False):
|
||||
def certificate_renew(domain_list, force=False, no_checks=False, email=False, staging=False):
|
||||
"""
|
||||
Renew Let's Encrypt certificate for given domains (all by default)
|
||||
|
||||
|
@ -317,7 +317,7 @@ def certificate_renew(auth, domain_list, force=False, no_checks=False, email=Fal
|
|||
# If no domains given, consider all yunohost domains with Let's Encrypt
|
||||
# certificates
|
||||
if domain_list == []:
|
||||
for domain in yunohost.domain.domain_list(auth)['domains']:
|
||||
for domain in yunohost.domain.domain_list()['domains']:
|
||||
|
||||
# Does it have a Let's Encrypt cert?
|
||||
status = _get_status(domain)
|
||||
|
@ -344,7 +344,7 @@ def certificate_renew(auth, domain_list, force=False, no_checks=False, email=Fal
|
|||
for domain in domain_list:
|
||||
|
||||
# Is it in Yunohost dmomain list?
|
||||
if domain not in yunohost.domain.domain_list(auth)['domains']:
|
||||
if domain not in yunohost.domain.domain_list()['domains']:
|
||||
raise YunohostError('certmanager_domain_unknown', domain=domain)
|
||||
|
||||
status = _get_status(domain)
|
||||
|
@ -468,7 +468,7 @@ Subject: %s
|
|||
smtp.quit()
|
||||
|
||||
|
||||
def _configure_for_acme_challenge(auth, domain):
|
||||
def _configure_for_acme_challenge(domain):
|
||||
|
||||
nginx_conf_folder = "/etc/nginx/conf.d/%s.d" % domain
|
||||
nginx_conf_file = "%s/000-acmechallenge.conf" % nginx_conf_folder
|
||||
|
@ -511,7 +511,7 @@ location ^~ '/.well-known/acme-challenge/'
|
|||
# any clean function already implemented in yunohost to do this though)
|
||||
_run_service_command("reload", "nginx")
|
||||
|
||||
app_ssowatconf(auth)
|
||||
app_ssowatconf()
|
||||
|
||||
|
||||
def _check_acme_challenge_configuration(domain):
|
||||
|
|
|
@ -22,14 +22,15 @@ class MyMigration(Migration):
|
|||
|
||||
# Remove all the deprecated lists
|
||||
lists_to_remove = [
|
||||
"https://app.yunohost.org/official.json",
|
||||
"https://app.yunohost.org/community.json",
|
||||
"https://labriqueinter.net/apps/labriqueinternet.json"
|
||||
"app.yunohost.org/list.json", # Old list on old installs, alias to official.json
|
||||
"app.yunohost.org/official.json",
|
||||
"app.yunohost.org/community.json",
|
||||
"labriqueinter.net/apps/labriqueinternet.json"
|
||||
]
|
||||
|
||||
appslists = _read_appslist_list()
|
||||
for appslist, infos in appslists.items():
|
||||
if infos["url"] in lists_to_remove:
|
||||
if infos["url"].split("//")[-1] in lists_to_remove:
|
||||
app_removelist(name=appslist)
|
||||
|
||||
# Replace by apps.json list
|
||||
|
|
|
@ -3,7 +3,6 @@ import time
|
|||
import os
|
||||
|
||||
from moulinette import m18n
|
||||
from moulinette.core import init_authenticator
|
||||
from yunohost.utils.error import YunohostError
|
||||
from moulinette.utils.log import getActionLogger
|
||||
|
||||
|
@ -29,11 +28,15 @@ class MyMigration(Migration):
|
|||
|
||||
required = True
|
||||
|
||||
def migrate_LDAP_db(self, auth):
|
||||
print("asdfadsf")
|
||||
def migrate_LDAP_db(self):
|
||||
|
||||
logger.info(m18n.n("migration_0011_update_LDAP_database"))
|
||||
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
try:
|
||||
auth.remove('cn=sftpusers,ou=groups')
|
||||
ldap.remove('cn=sftpusers,ou=groups')
|
||||
except:
|
||||
logger.warn(m18n.n("error_when_removing_sftpuser_group"))
|
||||
|
||||
|
@ -42,32 +45,32 @@ class MyMigration(Migration):
|
|||
|
||||
try:
|
||||
attr_dict = ldap_map['parents']['ou=permission']
|
||||
auth.add('ou=permission', attr_dict)
|
||||
ldap.add('ou=permission', attr_dict)
|
||||
|
||||
attr_dict = ldap_map['children']['cn=all_users,ou=groups']
|
||||
auth.add('cn=all_users,ou=groups', attr_dict)
|
||||
ldap.add('cn=all_users,ou=groups', attr_dict)
|
||||
|
||||
for rdn, attr_dict in ldap_map['depends_children'].items():
|
||||
auth.add(rdn, attr_dict)
|
||||
ldap.add(rdn, attr_dict)
|
||||
except Exception as e:
|
||||
raise YunohostError("migration_0011_LDAP_update_failed", error=e)
|
||||
|
||||
logger.info(m18n.n("migration_0011_create_group"))
|
||||
|
||||
# Create a group for each yunohost user
|
||||
user_list = auth.search('ou=users,dc=yunohost,dc=org',
|
||||
user_list = ldap.search('ou=users,dc=yunohost,dc=org',
|
||||
'(&(objectclass=person)(!(uid=root))(!(uid=nobody)))',
|
||||
['uid', 'uidNumber'])
|
||||
for user_info in user_list:
|
||||
username = user_info['uid'][0]
|
||||
auth.update('uid=%s,ou=users' % username,
|
||||
ldap.update('uid=%s,ou=users' % username,
|
||||
{'objectClass': ['mailAccount', 'inetOrgPerson', 'posixAccount', 'userPermissionYnh']})
|
||||
user_group_add(auth, username, gid=user_info['uidNumber'][0], sync_perm=False)
|
||||
user_group_update(auth, groupname=username, add_user=username, force=True, sync_perm=False)
|
||||
user_group_update(auth, groupname='all_users', add_user=username, force=True, sync_perm=False)
|
||||
user_group_add(username, gid=user_info['uidNumber'][0], sync_perm=False)
|
||||
user_group_update(groupname=username, add_user=username, force=True, sync_perm=False)
|
||||
user_group_update(groupname='all_users', add_user=username, force=True, sync_perm=False)
|
||||
|
||||
|
||||
def migrate_app_permission(self, auth, app=None):
|
||||
def migrate_app_permission(self, app=None):
|
||||
logger.info(m18n.n("migration_0011_migrate_permission"))
|
||||
|
||||
if app:
|
||||
|
@ -82,10 +85,10 @@ class MyMigration(Migration):
|
|||
domain = app_setting(app, 'domain')
|
||||
|
||||
urls = [domain + path] if domain and path else None
|
||||
permission_add(auth, app, permission='main', urls=urls, default_allow=True, sync_perm=False)
|
||||
permission_add(app, permission='main', urls=urls, default_allow=True, sync_perm=False)
|
||||
if permission:
|
||||
allowed_group = permission.split(',')
|
||||
user_permission_add(auth, [app], permission='main', group=allowed_group, sync_perm=False)
|
||||
user_permission_add([app], permission='main', group=allowed_group, sync_perm=False)
|
||||
app_setting(app, 'allowed_users', delete=True)
|
||||
|
||||
|
||||
|
@ -115,20 +118,13 @@ class MyMigration(Migration):
|
|||
logger.info(m18n.n("migration_0011_update_LDAP_schema"))
|
||||
regen_conf(names=['slapd'], force=True)
|
||||
|
||||
# Do the authentication to LDAP after LDAP as been updated
|
||||
AUTH_IDENTIFIER = ('ldap', 'as-root')
|
||||
AUTH_PARAMETERS = {'uri': 'ldapi://%2Fvar%2Frun%2Fslapd%2Fldapi',
|
||||
'base_dn': 'dc=yunohost,dc=org',
|
||||
'user_rdn': 'gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth'}
|
||||
auth = init_authenticator(AUTH_IDENTIFIER, AUTH_PARAMETERS)
|
||||
|
||||
# Update LDAP database
|
||||
self.migrate_LDAP_db(auth)
|
||||
self.migrate_LDAP_db()
|
||||
|
||||
# Migrate permission
|
||||
self.migrate_app_permission(auth)
|
||||
self.migrate_app_permission()
|
||||
|
||||
permission_sync_to_user(auth)
|
||||
permission_sync_to_user()
|
||||
except Exception as e:
|
||||
logger.warn(m18n.n("migration_0011_migration_failed_trying_to_rollback"))
|
||||
os.system("systemctl stop slapd")
|
||||
|
|
|
@ -42,7 +42,7 @@ from yunohost.hook import hook_callback
|
|||
logger = getActionLogger('yunohost.domain')
|
||||
|
||||
|
||||
def domain_list(auth):
|
||||
def domain_list():
|
||||
"""
|
||||
List domains
|
||||
|
||||
|
@ -52,10 +52,12 @@ def domain_list(auth):
|
|||
limit -- Maximum number of domain fetched
|
||||
|
||||
"""
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
|
||||
ldap = _get_ldap_interface()
|
||||
result = ldap.search('ou=domains,dc=yunohost,dc=org', 'virtualdomain=*', ['virtualdomain'])
|
||||
|
||||
result_list = []
|
||||
|
||||
result = auth.search('ou=domains,dc=yunohost,dc=org', 'virtualdomain=*', ['virtualdomain'])
|
||||
|
||||
for domain in result:
|
||||
result_list.append(domain['virtualdomain'][0])
|
||||
|
||||
|
@ -63,7 +65,7 @@ def domain_list(auth):
|
|||
|
||||
|
||||
@is_unit_operation()
|
||||
def domain_add(operation_logger, auth, domain, dyndns=False):
|
||||
def domain_add(operation_logger, domain, dyndns=False):
|
||||
"""
|
||||
Create a custom domain
|
||||
|
||||
|
@ -74,9 +76,12 @@ def domain_add(operation_logger, auth, domain, dyndns=False):
|
|||
"""
|
||||
from yunohost.hook import hook_callback
|
||||
from yunohost.app import app_ssowatconf
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
try:
|
||||
auth.validate_uniqueness({'virtualdomain': domain})
|
||||
ldap.validate_uniqueness({'virtualdomain': domain})
|
||||
except MoulinetteError:
|
||||
raise YunohostError('domain_exists')
|
||||
|
||||
|
@ -107,18 +112,18 @@ def domain_add(operation_logger, auth, domain, dyndns=False):
|
|||
'virtualdomain': domain,
|
||||
}
|
||||
|
||||
if not auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict):
|
||||
if not ldap.add('virtualdomain=%s,ou=domains' % domain, attr_dict):
|
||||
raise YunohostError('domain_creation_failed')
|
||||
|
||||
# Don't regen these conf if we're still in postinstall
|
||||
if os.path.exists('/etc/yunohost/installed'):
|
||||
regen_conf(names=['nginx', 'metronome', 'dnsmasq', 'postfix', 'rspamd'])
|
||||
app_ssowatconf(auth)
|
||||
app_ssowatconf()
|
||||
|
||||
except Exception:
|
||||
# Force domain removal silently
|
||||
try:
|
||||
domain_remove(auth, domain, True)
|
||||
domain_remove(domain, True)
|
||||
except:
|
||||
pass
|
||||
raise
|
||||
|
@ -129,7 +134,7 @@ def domain_add(operation_logger, auth, domain, dyndns=False):
|
|||
|
||||
|
||||
@is_unit_operation()
|
||||
def domain_remove(operation_logger, auth, domain, force=False):
|
||||
def domain_remove(operation_logger, domain, force=False):
|
||||
"""
|
||||
Delete domains
|
||||
|
||||
|
@ -140,8 +145,9 @@ def domain_remove(operation_logger, auth, domain, force=False):
|
|||
"""
|
||||
from yunohost.hook import hook_callback
|
||||
from yunohost.app import app_ssowatconf
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
|
||||
if not force and domain not in domain_list(auth)['domains']:
|
||||
if not force and domain not in domain_list()['domains']:
|
||||
raise YunohostError('domain_unknown')
|
||||
|
||||
# Check domain is not the main domain
|
||||
|
@ -160,13 +166,14 @@ def domain_remove(operation_logger, auth, domain, force=False):
|
|||
raise YunohostError('domain_uninstall_app_first')
|
||||
|
||||
operation_logger.start()
|
||||
if auth.remove('virtualdomain=' + domain + ',ou=domains') or force:
|
||||
ldap = _get_ldap_interface()
|
||||
if ldap.remove('virtualdomain=' + domain + ',ou=domains') or force:
|
||||
os.system('rm -rf /etc/yunohost/certs/%s' % domain)
|
||||
else:
|
||||
raise YunohostError('domain_deletion_failed')
|
||||
|
||||
regen_conf(names=['nginx', 'metronome', 'dnsmasq', 'postfix'])
|
||||
app_ssowatconf(auth)
|
||||
app_ssowatconf()
|
||||
|
||||
hook_callback('post_domain_remove', args=[domain])
|
||||
|
||||
|
@ -222,19 +229,19 @@ def domain_dns_conf(domain, ttl=None):
|
|||
return result
|
||||
|
||||
|
||||
def domain_cert_status(auth, domain_list, full=False):
|
||||
return yunohost.certificate.certificate_status(auth, domain_list, full)
|
||||
def domain_cert_status(domain_list, full=False):
|
||||
return yunohost.certificate.certificate_status(domain_list, full)
|
||||
|
||||
|
||||
def domain_cert_install(auth, domain_list, force=False, no_checks=False, self_signed=False, staging=False):
|
||||
return yunohost.certificate.certificate_install(auth, domain_list, force, no_checks, self_signed, staging)
|
||||
def domain_cert_install(domain_list, force=False, no_checks=False, self_signed=False, staging=False):
|
||||
return yunohost.certificate.certificate_install(domain_list, force, no_checks, self_signed, staging)
|
||||
|
||||
|
||||
def domain_cert_renew(auth, domain_list, force=False, no_checks=False, email=False, staging=False):
|
||||
return yunohost.certificate.certificate_renew(auth, domain_list, force, no_checks, email, staging)
|
||||
def domain_cert_renew(domain_list, force=False, no_checks=False, email=False, staging=False):
|
||||
return yunohost.certificate.certificate_renew(domain_list, force, no_checks, email, staging)
|
||||
|
||||
|
||||
def _get_conflicting_apps(auth, domain, path, ignore_app=None):
|
||||
def _get_conflicting_apps(domain, path, ignore_app=None):
|
||||
"""
|
||||
Return a list of all conflicting apps with a domain/path (it can be empty)
|
||||
|
||||
|
@ -247,7 +254,7 @@ def _get_conflicting_apps(auth, domain, path, ignore_app=None):
|
|||
domain, path = _normalize_domain_path(domain, path)
|
||||
|
||||
# Abort if domain is unknown
|
||||
if domain not in domain_list(auth)['domains']:
|
||||
if domain not in domain_list()['domains']:
|
||||
raise YunohostError('domain_unknown')
|
||||
|
||||
# This import cannot be put on top of file because it would create a
|
||||
|
@ -255,7 +262,7 @@ def _get_conflicting_apps(auth, domain, path, ignore_app=None):
|
|||
from yunohost.app import app_map
|
||||
|
||||
# Fetch apps map
|
||||
apps_map = app_map(auth, raw=True)
|
||||
apps_map = app_map(raw=True)
|
||||
|
||||
# Loop through all apps to check if path is taken by one of them
|
||||
conflicts = []
|
||||
|
@ -274,7 +281,7 @@ def _get_conflicting_apps(auth, domain, path, ignore_app=None):
|
|||
return conflicts
|
||||
|
||||
|
||||
def domain_url_available(auth, domain, path):
|
||||
def domain_url_available(domain, path):
|
||||
"""
|
||||
Check availability of a web path
|
||||
|
||||
|
@ -283,7 +290,7 @@ def domain_url_available(auth, domain, path):
|
|||
path -- The path to check (e.g. /coffee)
|
||||
"""
|
||||
|
||||
return len(_get_conflicting_apps(auth, domain, path)) == 0
|
||||
return len(_get_conflicting_apps(domain, path)) == 0
|
||||
|
||||
|
||||
def _get_maindomain():
|
||||
|
|
|
@ -28,7 +28,7 @@ import re
|
|||
import tempfile
|
||||
from glob import iglob
|
||||
|
||||
from moulinette import m18n
|
||||
from moulinette import m18n, msettings
|
||||
from yunohost.utils.error import YunohostError
|
||||
from moulinette.utils import log
|
||||
from moulinette.utils.filesystem import read_json
|
||||
|
@ -337,6 +337,8 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False,
|
|||
env = {}
|
||||
env['YNH_CWD'] = chdir
|
||||
|
||||
env['YNH_INTERFACE'] = msettings.get('interface')
|
||||
|
||||
stdinfo = os.path.join(tempfile.mkdtemp(), "stdinfo")
|
||||
env['YNH_STDINFO'] = stdinfo
|
||||
|
||||
|
|
|
@ -208,7 +208,7 @@ def log_display(path, number=50, share=False):
|
|||
|
||||
|
||||
def is_unit_operation(entities=['app', 'domain', 'service', 'user'],
|
||||
exclude=['auth', 'password'], operation_key=None):
|
||||
exclude=['password'], operation_key=None):
|
||||
"""
|
||||
Configure quickly a unit operation
|
||||
|
||||
|
@ -222,9 +222,8 @@ def is_unit_operation(entities=['app', 'domain', 'service', 'user'],
|
|||
(argname, entity_type) instead of just put the entity type.
|
||||
|
||||
exclude Remove some arguments from the context. By default, arguments
|
||||
called 'password' and 'auth' are removed. If an argument is an object, you
|
||||
need to exclude it or create manually the unit operation without this
|
||||
decorator.
|
||||
called 'password' are removed. If an argument is an object, you need to
|
||||
exclude it or create manually the unit operation without this decorator.
|
||||
|
||||
operation_key A key to describe the unit operation log used to create the
|
||||
filename and search a translation. Please ensure that this key prefixed by
|
||||
|
@ -347,8 +346,7 @@ class OperationLogger(object):
|
|||
"""
|
||||
|
||||
# TODO add a way to not save password on app installation
|
||||
filename = os.path.join(self.path, self.name + LOG_FILE_EXT)
|
||||
self.file_handler = FileHandler(filename)
|
||||
self.file_handler = FileHandler(self.log_path)
|
||||
self.file_handler.formatter = Formatter('%(asctime)s: %(levelname)s - %(message)s')
|
||||
|
||||
# Listen to the root logger
|
||||
|
@ -360,8 +358,7 @@ class OperationLogger(object):
|
|||
Write or rewrite the metadata file with all metadata known
|
||||
"""
|
||||
|
||||
filename = os.path.join(self.path, self.name + METADATA_FILE_EXT)
|
||||
with open(filename, 'w') as outfile:
|
||||
with open(self.md_path, 'w') as outfile:
|
||||
yaml.safe_dump(self.metadata, outfile, default_flow_style=False)
|
||||
|
||||
@property
|
||||
|
|
|
@ -36,7 +36,7 @@ from yunohost.log import is_unit_operation
|
|||
logger = getActionLogger('yunohost.user')
|
||||
|
||||
|
||||
def user_permission_list(auth, app=None, permission=None, username=None, group=None):
|
||||
def user_permission_list(app=None, permission=None, username=None, group=None):
|
||||
"""
|
||||
List permission for specific application
|
||||
|
||||
|
@ -48,6 +48,9 @@ def user_permission_list(auth, app=None, permission=None, username=None, group=N
|
|||
|
||||
"""
|
||||
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
permission_attrs = [
|
||||
'cn',
|
||||
'groupPermission',
|
||||
|
@ -67,7 +70,7 @@ def user_permission_list(auth, app=None, permission=None, username=None, group=N
|
|||
|
||||
permissions = {}
|
||||
|
||||
result = auth.search('ou=permission,dc=yunohost,dc=org',
|
||||
result = ldap.search('ou=permission,dc=yunohost,dc=org',
|
||||
'(objectclass=permissionYnh)', permission_attrs)
|
||||
|
||||
for res in result:
|
||||
|
@ -110,7 +113,7 @@ def user_permission_list(auth, app=None, permission=None, username=None, group=N
|
|||
return {'permissions': permissions}
|
||||
|
||||
|
||||
def user_permission_update(operation_logger, auth, app=[], permission=None, add_username=None, add_group=None, del_username=None, del_group=None, sync_perm=True):
|
||||
def user_permission_update(operation_logger, app=[], permission=None, add_username=None, add_group=None, del_username=None, del_group=None, sync_perm=True):
|
||||
"""
|
||||
Allow or Disallow a user or group to a permission for a specific application
|
||||
|
||||
|
@ -125,6 +128,8 @@ def user_permission_update(operation_logger, auth, app=[], permission=None, add_
|
|||
"""
|
||||
from yunohost.hook import hook_callback
|
||||
from yunohost.user import user_group_list
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
if permission:
|
||||
if not isinstance(permission, list):
|
||||
|
@ -158,16 +163,16 @@ def user_permission_update(operation_logger, auth, app=[], permission=None, add_
|
|||
|
||||
# Validate that the group exist
|
||||
for g in add_group:
|
||||
if g not in user_group_list(auth, ['cn'])['groups']:
|
||||
if g not in user_group_list(['cn'])['groups']:
|
||||
raise YunohostError('group_unknown', group=g)
|
||||
for u in add_username:
|
||||
if u not in user_list(auth, ['uid'])['users']:
|
||||
if u not in user_list(['uid'])['users']:
|
||||
raise YunohostError('user_unknown', user=u)
|
||||
for g in del_group:
|
||||
if g not in user_group_list(auth, ['cn'])['groups']:
|
||||
if g not in user_group_list(['cn'])['groups']:
|
||||
raise YunohostError('group_unknown', group=g)
|
||||
for u in del_username:
|
||||
if u not in user_list(auth, ['uid'])['users']:
|
||||
if u not in user_list(['uid'])['users']:
|
||||
raise YunohostError('user_unknown', user=u)
|
||||
|
||||
# Merge user and group (note that we consider all user as a group)
|
||||
|
@ -182,7 +187,7 @@ def user_permission_update(operation_logger, auth, app=[], permission=None, add_
|
|||
'cn',
|
||||
'groupPermission',
|
||||
]
|
||||
result = auth.search('ou=permission,dc=yunohost,dc=org',
|
||||
result = ldap.search('ou=permission,dc=yunohost,dc=org',
|
||||
'(objectclass=permissionYnh)', permission_attrs)
|
||||
result = {p['cn'][0]: p for p in result}
|
||||
|
||||
|
@ -221,19 +226,19 @@ def user_permission_update(operation_logger, auth, app=[], permission=None, add_
|
|||
# Don't update LDAP if we update exactly the same values
|
||||
if val == set(result[per]['groupPermission'] if 'groupPermission' in result[per] else []):
|
||||
continue
|
||||
if auth.update('cn=%s,ou=permission' % per, {'groupPermission': val}):
|
||||
if ldap.update('cn=%s,ou=permission' % per, {'groupPermission': val}):
|
||||
p = per.split('.')
|
||||
logger.success(m18n.n('permission_updated', permission=p[0], app=p[1]))
|
||||
else:
|
||||
raise YunohostError('permission_update_failed')
|
||||
|
||||
if sync_perm:
|
||||
permission_sync_to_user(auth)
|
||||
permission_sync_to_user()
|
||||
|
||||
for a in app:
|
||||
allowed_users = set()
|
||||
disallowed_users = set()
|
||||
group_list = user_group_list(auth, ['member'])['groups']
|
||||
group_list = user_group_list(['member'])['groups']
|
||||
|
||||
for g in add_group:
|
||||
if 'members' in group_list[g]:
|
||||
|
@ -249,10 +254,10 @@ def user_permission_update(operation_logger, auth, app=[], permission=None, add_
|
|||
if del_group:
|
||||
hook_callback('post_app_removeaccess', args=[app, disallowed_users])
|
||||
|
||||
return user_permission_list(auth, app, permission)
|
||||
return user_permission_list(app, permission)
|
||||
|
||||
|
||||
def user_permission_clear(operation_logger, auth, app=[], permission=None, sync_perm=True):
|
||||
def user_permission_clear(operation_logger, app=[], permission=None, sync_perm=True):
|
||||
"""
|
||||
Reset the permission for a specific application
|
||||
|
||||
|
@ -264,6 +269,8 @@ def user_permission_clear(operation_logger, auth, app=[], permission=None, sync_
|
|||
|
||||
"""
|
||||
from yunohost.hook import hook_callback
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
if permission:
|
||||
if not isinstance(permission, list):
|
||||
|
@ -278,7 +285,7 @@ def user_permission_clear(operation_logger, auth, app=[], permission=None, sync_
|
|||
'cn',
|
||||
'groupPermission',
|
||||
]
|
||||
result = auth.search('ou=permission,dc=yunohost,dc=org',
|
||||
result = ldap.search('ou=permission,dc=yunohost,dc=org',
|
||||
'(objectclass=permissionYnh)', permission_attrs)
|
||||
result = {p['cn'][0]: p for p in result}
|
||||
|
||||
|
@ -290,27 +297,27 @@ def user_permission_clear(operation_logger, auth, app=[], permission=None, sync_
|
|||
if 'groupPermission' in result[permission_name] and 'cn=all_users,ou=groups,dc=yunohost,dc=org' in result[permission_name]['groupPermission']:
|
||||
logger.warning(m18n.n('permission_already_clear', permission=per, app=a))
|
||||
continue
|
||||
if auth.update('cn=%s,ou=permission' % permission_name, default_permission):
|
||||
if ldap.update('cn=%s,ou=permission' % permission_name, default_permission):
|
||||
logger.success(m18n.n('permission_updated', permission=per, app=a))
|
||||
else:
|
||||
raise YunohostError('permission_update_failed')
|
||||
|
||||
permission_sync_to_user(auth)
|
||||
permission_sync_to_user()
|
||||
|
||||
for a in app:
|
||||
permission_name = 'main.' + a
|
||||
result = auth.search('ou=permission,dc=yunohost,dc=org',
|
||||
result = ldap.search('ou=permission,dc=yunohost,dc=org',
|
||||
filter='cn=' + permission_name, attrs=['inheritPermission'])
|
||||
if result:
|
||||
allowed_users = result[0]['inheritPermission']
|
||||
new_user_list = ','.join(allowed_users)
|
||||
hook_callback('post_app_removeaccess', args=[app, new_user_list])
|
||||
|
||||
return user_permission_list(auth, app, permission)
|
||||
return user_permission_list(app, permission)
|
||||
|
||||
|
||||
@is_unit_operation(['permission', 'app'])
|
||||
def permission_add(operation_logger, auth, app, permission, urls=None, default_allow=True, sync_perm=True):
|
||||
def permission_add(operation_logger, app, permission, urls=None, default_allow=True, sync_perm=True):
|
||||
"""
|
||||
Create a new permission for a specific application
|
||||
|
||||
|
@ -321,10 +328,12 @@ def permission_add(operation_logger, auth, app, permission, urls=None, default_a
|
|||
|
||||
"""
|
||||
from yunohost.domain import _normalize_domain_path
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
# Validate uniqueness of permission in LDAP
|
||||
permission_name = str(permission + '.' + app) # str(...) Fix encoding issue
|
||||
conflict = auth.get_conflict({
|
||||
conflict = ldap.get_conflict({
|
||||
'cn': permission_name
|
||||
}, base_dn='ou=permission,dc=yunohost,dc=org')
|
||||
if conflict:
|
||||
|
@ -355,17 +364,17 @@ def permission_add(operation_logger, auth, app, permission, urls=None, default_a
|
|||
attr_dict['URL'].append(domain + path)
|
||||
|
||||
operation_logger.start()
|
||||
if auth.add('cn=%s,ou=permission' % permission_name, attr_dict):
|
||||
if ldap.add('cn=%s,ou=permission' % permission_name, attr_dict):
|
||||
if sync_perm:
|
||||
permission_sync_to_user(auth)
|
||||
permission_sync_to_user()
|
||||
logger.success(m18n.n('permission_created', permission=permission, app=app))
|
||||
return user_permission_list(auth, app, permission)
|
||||
return user_permission_list(app, permission)
|
||||
|
||||
raise YunohostError('permission_creation_failed')
|
||||
|
||||
|
||||
@is_unit_operation(['permission', 'app'])
|
||||
def permission_update(operation_logger, auth, app, permission, add_url=None, remove_url=None, sync_perm=True):
|
||||
def permission_update(operation_logger, app, permission, add_url=None, remove_url=None, sync_perm=True):
|
||||
"""
|
||||
Update a permission for a specific application
|
||||
|
||||
|
@ -377,11 +386,13 @@ def permission_update(operation_logger, auth, app, permission, add_url=None, rem
|
|||
|
||||
"""
|
||||
from yunohost.domain import _normalize_domain_path
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
permission_name = str(permission + '.' + app) # str(...) Fix encoding issue
|
||||
|
||||
# Populate permission informations
|
||||
result = auth.search(base='ou=permission,dc=yunohost,dc=org',
|
||||
result = ldap.search(base='ou=permission,dc=yunohost,dc=org',
|
||||
filter='cn=' + permission_name, attrs=['URL'])
|
||||
if not result:
|
||||
raise YunohostError('permission_not_found', permission=permission, app=app)
|
||||
|
@ -407,20 +418,20 @@ def permission_update(operation_logger, auth, app, permission, add_url=None, rem
|
|||
|
||||
if url == set(permission_obj['URL']):
|
||||
logger.warning(m18n.n('permission_update_nothing_to_do'))
|
||||
return user_permission_list(auth, app, permission)
|
||||
return user_permission_list(app, permission)
|
||||
|
||||
operation_logger.start()
|
||||
if auth.update('cn=%s,ou=permission' % permission_name, {'cn': permission_name, 'URL': url}):
|
||||
if ldap.update('cn=%s,ou=permission' % permission_name, {'cn': permission_name, 'URL': url}):
|
||||
if sync_perm:
|
||||
permission_sync_to_user(auth)
|
||||
permission_sync_to_user()
|
||||
logger.success(m18n.n('permission_updated', permission=permission, app=app))
|
||||
return user_permission_list(auth, app, permission)
|
||||
return user_permission_list(app, permission)
|
||||
|
||||
raise YunohostError('premission_update_failed')
|
||||
|
||||
|
||||
@is_unit_operation(['permission', 'app'])
|
||||
def permission_remove(operation_logger, auth, app, permission, force=False, sync_perm=True):
|
||||
def permission_remove(operation_logger, app, permission, force=False, sync_perm=True):
|
||||
"""
|
||||
Remove a permission for a specific application
|
||||
|
||||
|
@ -433,15 +444,18 @@ def permission_remove(operation_logger, auth, app, permission, force=False, sync
|
|||
if permission == "main" and not force:
|
||||
raise YunohostError('remove_main_permission_not_allowed')
|
||||
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
operation_logger.start()
|
||||
if not auth.remove('cn=%s,ou=permission' % str(permission + '.' + app)):
|
||||
if not ldap.remove('cn=%s,ou=permission' % str(permission + '.' + app)):
|
||||
raise YunohostError('permission_deletion_failed', permission=permission, app=app)
|
||||
if sync_perm:
|
||||
permission_sync_to_user(auth)
|
||||
permission_sync_to_user()
|
||||
logger.success(m18n.n('permission_deleted', permission=permission, app=app))
|
||||
|
||||
|
||||
def permission_sync_to_user(auth, force=False):
|
||||
def permission_sync_to_user(force=False):
|
||||
"""
|
||||
Sychronise the inheritPermission attribut in the permission object from the
|
||||
user<->group link and the group<->permission link
|
||||
|
@ -456,16 +470,18 @@ def permission_sync_to_user(auth, force=False):
|
|||
# So we need to check before each ldap operation that we really change something in LDAP
|
||||
import os
|
||||
from yunohost.app import app_ssowatconf
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
permission_attrs = [
|
||||
'cn',
|
||||
'member',
|
||||
]
|
||||
group_info = auth.search('ou=groups,dc=yunohost,dc=org',
|
||||
group_info = ldap.search('ou=groups,dc=yunohost,dc=org',
|
||||
'(objectclass=groupOfNamesYnh)', permission_attrs)
|
||||
group_info = {g['cn'][0]: g for g in group_info}
|
||||
|
||||
for per in auth.search('ou=permission,dc=yunohost,dc=org',
|
||||
for per in ldap.search('ou=permission,dc=yunohost,dc=org',
|
||||
'(objectclass=permissionYnh)',
|
||||
['cn', 'inheritPermission', 'groupPermission', 'memberUid']):
|
||||
if 'groupPermission' not in per:
|
||||
|
@ -489,22 +505,22 @@ def permission_sync_to_user(auth, force=False):
|
|||
inheritPermission = {'inheritPermission': user_permission, 'memberUid': uid_val}
|
||||
if force:
|
||||
if per['groupPermission']:
|
||||
if not auth.update('cn=%s,ou=permission' % per['cn'][0], {'groupPermission': []}):
|
||||
if not ldap.update('cn=%s,ou=permission' % per['cn'][0], {'groupPermission': []}):
|
||||
raise YunohostError('permission_update_failed_clear')
|
||||
if not auth.update('cn=%s,ou=permission' % per['cn'][0], {'groupPermission': per['groupPermission']}):
|
||||
if not ldap.update('cn=%s,ou=permission' % per['cn'][0], {'groupPermission': per['groupPermission']}):
|
||||
raise YunohostError('permission_update_failed_populate')
|
||||
if per['inheritPermission']:
|
||||
if not auth.update('cn=%s,ou=permission' % per['cn'][0], {'inheritPermission': []}):
|
||||
if not ldap.update('cn=%s,ou=permission' % per['cn'][0], {'inheritPermission': []}):
|
||||
raise YunohostError('permission_update_failed_clear')
|
||||
if user_permission:
|
||||
if not auth.update('cn=%s,ou=permission' % per['cn'][0], inheritPermission):
|
||||
if not ldap.update('cn=%s,ou=permission' % per['cn'][0], inheritPermission):
|
||||
raise YunohostError('permission_update_failed')
|
||||
else:
|
||||
if not auth.update('cn=%s,ou=permission' % per['cn'][0], inheritPermission):
|
||||
if not ldap.update('cn=%s,ou=permission' % per['cn'][0], inheritPermission):
|
||||
raise YunohostError('permission_update_failed')
|
||||
logger.success(m18n.n('permission_generated'))
|
||||
|
||||
app_ssowatconf(auth)
|
||||
app_ssowatconf()
|
||||
|
||||
# Reload unscd, otherwise the group ain't propagated to the LDAP database
|
||||
os.system('nscd --invalidate=passwd')
|
||||
|
|
|
@ -44,6 +44,8 @@ DEFAULTS = OrderedDict([
|
|||
"choices": ["intermediate", "modern"]}),
|
||||
("security.nginx.compatibility", {"type": "enum", "default": "intermediate",
|
||||
"choices": ["intermediate", "modern"]}),
|
||||
("security.postfix.compatibility", {"type": "enum", "default": "intermediate",
|
||||
"choices": ["intermediate", "modern"]}),
|
||||
])
|
||||
|
||||
|
||||
|
@ -114,7 +116,7 @@ def settings_set(key, value):
|
|||
elif key_type == "enum":
|
||||
if value not in settings[key]["choices"]:
|
||||
raise YunohostError('global_settings_bad_choice_for_enum', setting=key,
|
||||
choice=value,
|
||||
choice=str(value),
|
||||
available_choices=", ".join(settings[key]["choices"]))
|
||||
else:
|
||||
raise YunohostError('global_settings_unknown_type', setting=key,
|
||||
|
@ -292,3 +294,8 @@ def reconfigure_nginx(setting_name, old_value, new_value):
|
|||
def reconfigure_ssh(setting_name, old_value, new_value):
|
||||
if old_value != new_value:
|
||||
service_regen_conf(names=['ssh'])
|
||||
|
||||
@post_change_hook("security.postfix.compatibility")
|
||||
def reconfigure_ssh(setting_name, old_value, new_value):
|
||||
if old_value != new_value:
|
||||
service_regen_conf(names=['postfix'])
|
||||
|
|
|
@ -11,7 +11,7 @@ from moulinette.utils.filesystem import read_file, write_to_file, chown, chmod,
|
|||
SSHD_CONFIG_PATH = "/etc/ssh/sshd_config"
|
||||
|
||||
|
||||
def user_ssh_allow(auth, username):
|
||||
def user_ssh_allow(username):
|
||||
"""
|
||||
Allow YunoHost user connect as ssh.
|
||||
|
||||
|
@ -20,17 +20,19 @@ def user_ssh_allow(auth, username):
|
|||
"""
|
||||
# TODO it would be good to support different kind of shells
|
||||
|
||||
if not _get_user_for_ssh(auth, username):
|
||||
if not _get_user_for_ssh(username):
|
||||
raise YunohostError('user_unknown', user=username)
|
||||
|
||||
auth.update('uid=%s,ou=users' % username, {'loginShell': '/bin/bash'})
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
ldap.update('uid=%s,ou=users' % username, {'loginShell': '/bin/bash'})
|
||||
|
||||
# Somehow this is needed otherwise the PAM thing doesn't forget about the
|
||||
# old loginShell value ?
|
||||
subprocess.call(['nscd', '-i', 'passwd'])
|
||||
|
||||
|
||||
def user_ssh_disallow(auth, username):
|
||||
def user_ssh_disallow(username):
|
||||
"""
|
||||
Disallow YunoHost user connect as ssh.
|
||||
|
||||
|
@ -39,18 +41,20 @@ def user_ssh_disallow(auth, username):
|
|||
"""
|
||||
# TODO it would be good to support different kind of shells
|
||||
|
||||
if not _get_user_for_ssh(auth, username):
|
||||
if not _get_user_for_ssh(username):
|
||||
raise YunohostError('user_unknown', user=username)
|
||||
|
||||
auth.update('uid=%s,ou=users' % username, {'loginShell': '/bin/false'})
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
ldap.update('uid=%s,ou=users' % username, {'loginShell': '/bin/false'})
|
||||
|
||||
# Somehow this is needed otherwise the PAM thing doesn't forget about the
|
||||
# old loginShell value ?
|
||||
subprocess.call(['nscd', '-i', 'passwd'])
|
||||
|
||||
|
||||
def user_ssh_list_keys(auth, username):
|
||||
user = _get_user_for_ssh(auth, username, ["homeDirectory"])
|
||||
def user_ssh_list_keys(username):
|
||||
user = _get_user_for_ssh(username, ["homeDirectory"])
|
||||
if not user:
|
||||
raise Exception("User with username '%s' doesn't exists" % username)
|
||||
|
||||
|
@ -82,8 +86,8 @@ def user_ssh_list_keys(auth, username):
|
|||
return {"keys": keys}
|
||||
|
||||
|
||||
def user_ssh_add_key(auth, username, key, comment):
|
||||
user = _get_user_for_ssh(auth, username, ["homeDirectory", "uid"])
|
||||
def user_ssh_add_key(username, key, comment):
|
||||
user = _get_user_for_ssh(username, ["homeDirectory", "uid"])
|
||||
if not user:
|
||||
raise Exception("User with username '%s' doesn't exists" % username)
|
||||
|
||||
|
@ -116,8 +120,8 @@ def user_ssh_add_key(auth, username, key, comment):
|
|||
write_to_file(authorized_keys_file, authorized_keys_content)
|
||||
|
||||
|
||||
def user_ssh_remove_key(auth, username, key):
|
||||
user = _get_user_for_ssh(auth, username, ["homeDirectory", "uid"])
|
||||
def user_ssh_remove_key(username, key):
|
||||
user = _get_user_for_ssh(username, ["homeDirectory", "uid"])
|
||||
if not user:
|
||||
raise Exception("User with username '%s' doesn't exists" % username)
|
||||
|
||||
|
@ -148,8 +152,8 @@ def user_ssh_remove_key(auth, username, key):
|
|||
#
|
||||
|
||||
|
||||
def _get_user_for_ssh(auth, username, attrs=None):
|
||||
def ssh_root_login_status(auth):
|
||||
def _get_user_for_ssh(username, attrs=None):
|
||||
def ssh_root_login_status():
|
||||
# XXX temporary placed here for when the ssh_root commands are integrated
|
||||
# extracted from https://github.com/YunoHost/yunohost/pull/345
|
||||
# XXX should we support all the options?
|
||||
|
@ -172,7 +176,7 @@ def _get_user_for_ssh(auth, username, attrs=None):
|
|||
'username': 'root',
|
||||
'fullname': '',
|
||||
'mail': '',
|
||||
'ssh_allowed': ssh_root_login_status(auth)["PermitRootLogin"],
|
||||
'ssh_allowed': ssh_root_login_status()["PermitRootLogin"],
|
||||
'shell': root_unix.pw_shell,
|
||||
'home_path': root_unix.pw_dir,
|
||||
}
|
||||
|
@ -189,7 +193,9 @@ def _get_user_for_ssh(auth, username, attrs=None):
|
|||
}
|
||||
|
||||
# TODO escape input using https://www.python-ldap.org/doc/html/ldap-filter.html
|
||||
user = auth.search('ou=users,dc=yunohost,dc=org',
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
user = ldap.search('ou=users,dc=yunohost,dc=org',
|
||||
'(&(objectclass=person)(uid=%s))' % username,
|
||||
attrs)
|
||||
|
||||
|
|
|
@ -1,18 +1,9 @@
|
|||
import pytest
|
||||
|
||||
from moulinette.core import init_authenticator
|
||||
from yunohost.utils.error import YunohostError
|
||||
from yunohost.app import app_install, app_remove
|
||||
from yunohost.domain import _get_maindomain, domain_url_available, _normalize_domain_path
|
||||
|
||||
# Instantiate LDAP Authenticator
|
||||
AUTH_IDENTIFIER = ('ldap', 'as-root')
|
||||
AUTH_PARAMETERS = {'uri': 'ldapi://%2Fvar%2Frun%2Fslapd%2Fldapi',
|
||||
'base_dn': 'dc=yunohost,dc=org',
|
||||
'user_rdn': 'gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth'}
|
||||
auth = init_authenticator(AUTH_IDENTIFIER, AUTH_PARAMETERS)
|
||||
|
||||
|
||||
# Get main domain
|
||||
maindomain = _get_maindomain()
|
||||
|
||||
|
@ -20,7 +11,7 @@ maindomain = _get_maindomain()
|
|||
def setup_function(function):
|
||||
|
||||
try:
|
||||
app_remove(auth, "register_url_app")
|
||||
app_remove("register_url_app")
|
||||
except:
|
||||
pass
|
||||
|
||||
|
@ -28,7 +19,7 @@ def setup_function(function):
|
|||
def teardown_function(function):
|
||||
|
||||
try:
|
||||
app_remove(auth, "register_url_app")
|
||||
app_remove("register_url_app")
|
||||
except:
|
||||
pass
|
||||
|
||||
|
@ -43,28 +34,28 @@ def test_normalize_domain_path():
|
|||
def test_urlavailable():
|
||||
|
||||
# Except the maindomain/macnuggets to be available
|
||||
assert domain_url_available(auth, maindomain, "/macnuggets")
|
||||
assert domain_url_available(maindomain, "/macnuggets")
|
||||
|
||||
# We don't know the domain yolo.swag
|
||||
with pytest.raises(YunohostError):
|
||||
assert domain_url_available(auth, "yolo.swag", "/macnuggets")
|
||||
assert domain_url_available("yolo.swag", "/macnuggets")
|
||||
|
||||
|
||||
def test_registerurl():
|
||||
|
||||
app_install(auth, "./tests/apps/register_url_app_ynh",
|
||||
app_install("./tests/apps/register_url_app_ynh",
|
||||
args="domain=%s&path=%s" % (maindomain, "/urlregisterapp"), force=True)
|
||||
|
||||
assert not domain_url_available(auth, maindomain, "/urlregisterapp")
|
||||
assert not domain_url_available(maindomain, "/urlregisterapp")
|
||||
|
||||
# Try installing at same location
|
||||
with pytest.raises(YunohostError):
|
||||
app_install(auth, "./tests/apps/register_url_app_ynh",
|
||||
app_install("./tests/apps/register_url_app_ynh",
|
||||
args="domain=%s&path=%s" % (maindomain, "/urlregisterapp"), force=True)
|
||||
|
||||
|
||||
def test_registerurl_baddomain():
|
||||
|
||||
with pytest.raises(YunohostError):
|
||||
app_install(auth, "./tests/apps/register_url_app_ynh",
|
||||
app_install("./tests/apps/register_url_app_ynh",
|
||||
args="domain=%s&path=%s" % ("yolo.swag", "/urlregisterapp"), force=True)
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
import pytest
|
||||
import time
|
||||
import requests
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
from mock import ANY
|
||||
|
||||
from moulinette import m18n
|
||||
from moulinette.core import init_authenticator
|
||||
from yunohost.app import app_install, app_remove, app_ssowatconf
|
||||
from yunohost.app import _is_installed
|
||||
from yunohost.backup import backup_create, backup_restore, backup_list, backup_info, backup_delete, _recursive_umount
|
||||
|
@ -19,14 +16,6 @@ from yunohost.tests.test_permission import check_LDAP_db_integrity, check_permis
|
|||
# Get main domain
|
||||
maindomain = ""
|
||||
|
||||
# Instantiate LDAP Authenticator
|
||||
AUTH_IDENTIFIER = ('ldap', 'as-root')
|
||||
AUTH_PARAMETERS = {'uri': 'ldapi://%2Fvar%2Frun%2Fslapd%2Fldapi',
|
||||
'base_dn': 'dc=yunohost,dc=org',
|
||||
'user_rdn': 'gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth'}
|
||||
auth = None
|
||||
|
||||
|
||||
def setup_function(function):
|
||||
|
||||
global maindomain
|
||||
|
@ -34,9 +23,6 @@ def setup_function(function):
|
|||
|
||||
print ""
|
||||
|
||||
global auth
|
||||
auth = init_authenticator(AUTH_IDENTIFIER, AUTH_PARAMETERS)
|
||||
|
||||
assert backup_test_dependencies_are_met()
|
||||
|
||||
clean_tmp_backup_directory()
|
||||
|
@ -76,10 +62,6 @@ def setup_function(function):
|
|||
|
||||
def teardown_function(function):
|
||||
|
||||
print ""
|
||||
global auth
|
||||
auth = init_authenticator(AUTH_IDENTIFIER, AUTH_PARAMETERS)
|
||||
|
||||
assert tmp_backup_directory_is_empty()
|
||||
|
||||
reset_ssowat_conf()
|
||||
|
@ -162,7 +144,7 @@ def reset_ssowat_conf():
|
|||
|
||||
# Make sure we have a ssowat
|
||||
os.system("mkdir -p /etc/ssowat/")
|
||||
app_ssowatconf(auth)
|
||||
app_ssowatconf()
|
||||
|
||||
|
||||
def delete_all_backups():
|
||||
|
@ -174,18 +156,18 @@ def delete_all_backups():
|
|||
def uninstall_test_apps_if_needed():
|
||||
|
||||
if _is_installed("backup_legacy_app"):
|
||||
app_remove(auth, "backup_legacy_app")
|
||||
app_remove("backup_legacy_app")
|
||||
|
||||
if _is_installed("backup_recommended_app"):
|
||||
app_remove(auth, "backup_recommended_app")
|
||||
app_remove("backup_recommended_app")
|
||||
|
||||
if _is_installed("wordpress"):
|
||||
app_remove(auth, "wordpress")
|
||||
app_remove("wordpress")
|
||||
|
||||
|
||||
def install_app(app, path, additionnal_args=""):
|
||||
|
||||
app_install(auth, "./tests/apps/%s" % app,
|
||||
app_install("./tests/apps/%s" % app,
|
||||
args="domain=%s&path=%s%s" % (maindomain, path,
|
||||
additionnal_args), force=True)
|
||||
|
||||
|
@ -265,7 +247,7 @@ def test_backup_and_restore_all_sys():
|
|||
assert not os.path.exists("/etc/ssowat/conf.json")
|
||||
|
||||
# Restore the backup
|
||||
backup_restore(auth, name=archives[0], force=True,
|
||||
backup_restore(name=archives[0], force=True,
|
||||
system=[], apps=None)
|
||||
|
||||
# Check ssowat conf is back
|
||||
|
@ -286,13 +268,13 @@ def test_restore_system_from_Ynh2p4(monkeypatch, mocker):
|
|||
|
||||
# Restore system archive from 2.4
|
||||
try:
|
||||
backup_restore(auth, name=backup_list()["archives"][1],
|
||||
backup_restore(name=backup_list()["archives"][1],
|
||||
system=[],
|
||||
apps=None,
|
||||
force=True)
|
||||
finally:
|
||||
# Restore system as it was
|
||||
backup_restore(auth, name=backup_list()["archives"][0],
|
||||
backup_restore(name=backup_list()["archives"][0],
|
||||
system=[],
|
||||
apps=None,
|
||||
force=True)
|
||||
|
@ -428,7 +410,7 @@ def test_backup_with_no_compress():
|
|||
@pytest.mark.with_wordpress_archive_from_2p4
|
||||
def test_restore_app_wordpress_from_Ynh2p4():
|
||||
|
||||
backup_restore(auth, system=None, name=backup_list()["archives"][0],
|
||||
backup_restore(system=None, name=backup_list()["archives"][0],
|
||||
apps=["wordpress"])
|
||||
|
||||
|
||||
|
@ -446,7 +428,7 @@ def test_restore_app_script_failure_handling(monkeypatch, mocker):
|
|||
assert not _is_installed("wordpress")
|
||||
|
||||
with pytest.raises(YunohostError):
|
||||
backup_restore(auth, system=None, name=backup_list()["archives"][0],
|
||||
backup_restore(system=None, name=backup_list()["archives"][0],
|
||||
apps=["wordpress"])
|
||||
|
||||
m18n.n.assert_any_call('restore_app_failed', app='wordpress')
|
||||
|
@ -467,7 +449,7 @@ def test_restore_app_not_enough_free_space(monkeypatch, mocker):
|
|||
assert not _is_installed("wordpress")
|
||||
|
||||
with pytest.raises(YunohostError):
|
||||
backup_restore(auth, system=None, name=backup_list()["archives"][0],
|
||||
backup_restore(system=None, name=backup_list()["archives"][0],
|
||||
apps=["wordpress"])
|
||||
|
||||
m18n.n.assert_any_call('restore_not_enough_disk_space',
|
||||
|
@ -486,7 +468,7 @@ def test_restore_app_not_in_backup(mocker):
|
|||
mocker.spy(m18n, "n")
|
||||
|
||||
with pytest.raises(YunohostError):
|
||||
backup_restore(auth, system=None, name=backup_list()["archives"][0],
|
||||
backup_restore(system=None, name=backup_list()["archives"][0],
|
||||
apps=["yoloswag"])
|
||||
|
||||
m18n.n.assert_any_call('backup_archive_app_not_found', app="yoloswag")
|
||||
|
@ -499,14 +481,14 @@ def test_restore_app_already_installed(mocker):
|
|||
|
||||
assert not _is_installed("wordpress")
|
||||
|
||||
backup_restore(auth, system=None, name=backup_list()["archives"][0],
|
||||
backup_restore(system=None, name=backup_list()["archives"][0],
|
||||
apps=["wordpress"])
|
||||
|
||||
assert _is_installed("wordpress")
|
||||
|
||||
mocker.spy(m18n, "n")
|
||||
with pytest.raises(YunohostError):
|
||||
backup_restore(auth, system=None, name=backup_list()["archives"][0],
|
||||
backup_restore(system=None, name=backup_list()["archives"][0],
|
||||
apps=["wordpress"])
|
||||
|
||||
m18n.n.assert_any_call('restore_already_installed_app', app="wordpress")
|
||||
|
@ -547,18 +529,18 @@ def _test_backup_and_restore_app(app):
|
|||
assert app in archives_info["apps"].keys()
|
||||
|
||||
# Uninstall the app
|
||||
app_remove(auth, app)
|
||||
app_remove(app)
|
||||
assert not app_is_installed(app)
|
||||
assert app not in user_permission_list(auth)['permissions']
|
||||
assert app not in user_permission_list()['permissions']
|
||||
|
||||
# Restore the app
|
||||
backup_restore(auth, system=None, name=archives[0],
|
||||
backup_restore(system=None, name=archives[0],
|
||||
apps=[app])
|
||||
|
||||
assert app_is_installed(app)
|
||||
|
||||
# Check permission
|
||||
per_list = user_permission_list(auth)['permissions']
|
||||
per_list = user_permission_list()['permissions']
|
||||
assert app in per_list
|
||||
assert "main" in per_list[app]
|
||||
|
||||
|
@ -577,7 +559,7 @@ def test_restore_archive_with_no_json(mocker):
|
|||
|
||||
mocker.spy(m18n, "n")
|
||||
with pytest.raises(YunohostError):
|
||||
backup_restore(auth, name="badbackup", force=True)
|
||||
backup_restore(name="badbackup", force=True)
|
||||
m18n.n.assert_any_call('backup_invalid_archive')
|
||||
|
||||
|
||||
|
|
|
@ -2,20 +2,11 @@ import pytest
|
|||
import time
|
||||
import requests
|
||||
|
||||
from moulinette.core import init_authenticator
|
||||
from yunohost.app import app_install, app_change_url, app_remove, app_map
|
||||
from yunohost.domain import _get_maindomain
|
||||
|
||||
from yunohost.utils.error import YunohostError
|
||||
|
||||
# Instantiate LDAP Authenticator
|
||||
AUTH_IDENTIFIER = ('ldap', 'as-root')
|
||||
AUTH_PARAMETERS = {'uri': 'ldapi://%2Fvar%2Frun%2Fslapd%2Fldapi',
|
||||
'base_dn': 'dc=yunohost,dc=org',
|
||||
'user_rdn': 'gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth'}
|
||||
|
||||
auth = init_authenticator(AUTH_IDENTIFIER, AUTH_PARAMETERS)
|
||||
|
||||
# Get main domain
|
||||
maindomain = _get_maindomain()
|
||||
|
||||
|
@ -25,16 +16,16 @@ def setup_function(function):
|
|||
|
||||
|
||||
def teardown_function(function):
|
||||
app_remove(auth, "change_url_app")
|
||||
app_remove("change_url_app")
|
||||
|
||||
|
||||
def install_changeurl_app(path):
|
||||
app_install(auth, "./tests/apps/change_url_app_ynh",
|
||||
app_install("./tests/apps/change_url_app_ynh",
|
||||
args="domain=%s&path=%s" % (maindomain, path), force=True)
|
||||
|
||||
|
||||
def check_changeurl_app(path):
|
||||
appmap = app_map(auth, raw=True)
|
||||
appmap = app_map(raw=True)
|
||||
|
||||
assert path in appmap[maindomain].keys()
|
||||
|
||||
|
@ -48,7 +39,7 @@ def test_appchangeurl():
|
|||
install_changeurl_app("/changeurl")
|
||||
check_changeurl_app("/changeurl")
|
||||
|
||||
app_change_url(auth, "change_url_app", maindomain, "/newchangeurl")
|
||||
app_change_url("change_url_app", maindomain, "/newchangeurl")
|
||||
|
||||
# For some reason the nginx reload can take some time to propagate ...?
|
||||
time.sleep(2)
|
||||
|
@ -61,4 +52,4 @@ def test_appchangeurl_sameurl():
|
|||
check_changeurl_app("/changeurl")
|
||||
|
||||
with pytest.raises(YunohostError):
|
||||
app_change_url(auth, "change_url_app", maindomain, "changeurl")
|
||||
app_change_url("change_url_app", maindomain, "changeurl")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import pytest
|
||||
|
||||
from moulinette.core import init_authenticator, MoulinetteError
|
||||
from moulinette.core import MoulinetteError
|
||||
from yunohost.app import app_install, app_remove, app_change_url, app_list
|
||||
from yunohost.user import user_list, user_create, user_permission_list, user_delete, user_group_list, user_group_delete, user_permission_add, user_permission_remove, user_permission_clear
|
||||
from yunohost.permission import permission_add, permission_update, permission_remove
|
||||
|
@ -10,41 +10,33 @@ from yunohost.utils.error import YunohostError
|
|||
# Get main domain
|
||||
maindomain = _get_maindomain()
|
||||
|
||||
# Instantiate LDAP Authenticator
|
||||
AUTH_IDENTIFIER = ('ldap', 'as-root')
|
||||
AUTH_PARAMETERS = {'uri': 'ldapi://%2Fvar%2Frun%2Fslapd%2Fldapi',
|
||||
'base_dn': 'dc=yunohost,dc=org',
|
||||
'user_rdn': 'gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth'}
|
||||
|
||||
auth = init_authenticator(AUTH_IDENTIFIER, AUTH_PARAMETERS)
|
||||
|
||||
def clean_user_groups_permission():
|
||||
for u in user_list(auth)['users']:
|
||||
user_delete(auth, u)
|
||||
for u in user_list()['users']:
|
||||
user_delete(u)
|
||||
|
||||
for g in user_group_list(auth)['groups']:
|
||||
for g in user_group_list()['groups']:
|
||||
if g != "all_users":
|
||||
user_group_delete(auth, g)
|
||||
user_group_delete(g)
|
||||
|
||||
for a, per in user_permission_list(auth)['permissions'].items():
|
||||
for a, per in user_permission_list()['permissions'].items():
|
||||
if a in ['wiki', 'blog', 'site']:
|
||||
for p in per:
|
||||
permission_remove(auth, a, p, force=True, sync_perm=False)
|
||||
permission_remove(a, p, force=True, sync_perm=False)
|
||||
|
||||
def setup_function(function):
|
||||
clean_user_groups_permission()
|
||||
|
||||
user_create(auth, "alice", "Alice", "White", "alice@" + maindomain, "test123Ynh")
|
||||
user_create(auth, "bob", "Bob", "Snow", "bob@" + maindomain, "test123Ynh")
|
||||
permission_add(auth, "wiki", "main", [maindomain + "/wiki"], sync_perm=False)
|
||||
permission_add(auth, "blog", "main", sync_perm=False)
|
||||
user_create("alice", "Alice", "White", "alice@" + maindomain, "test123Ynh")
|
||||
user_create("bob", "Bob", "Snow", "bob@" + maindomain, "test123Ynh")
|
||||
permission_add("wiki", "main", [maindomain + "/wiki"], sync_perm=False)
|
||||
permission_add("blog", "main", sync_perm=False)
|
||||
|
||||
user_permission_add(auth, ["blog"], "main", group="alice")
|
||||
user_permission_add(["blog"], "main", group="alice")
|
||||
|
||||
def teardown_function(function):
|
||||
clean_user_groups_permission()
|
||||
try:
|
||||
app_remove(auth, "permissions_app")
|
||||
app_remove("permissions_app")
|
||||
except:
|
||||
pass
|
||||
|
||||
|
@ -65,13 +57,16 @@ def check_LDAP_db_integrity():
|
|||
# One part should be done automatically by the "memberOf" overlay of LDAP.
|
||||
# The other part is done by the the "permission_sync_to_user" function of the permission module
|
||||
|
||||
user_search = auth.search('ou=users,dc=yunohost,dc=org',
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
user_search = ldap.search('ou=users,dc=yunohost,dc=org',
|
||||
'(&(objectclass=person)(!(uid=root))(!(uid=nobody)))',
|
||||
['uid', 'memberOf', 'permission'])
|
||||
group_search = auth.search('ou=groups,dc=yunohost,dc=org',
|
||||
group_search = ldap.search('ou=groups,dc=yunohost,dc=org',
|
||||
'(objectclass=groupOfNamesYnh)',
|
||||
['cn', 'member', 'memberUid', 'permission'])
|
||||
permission_search = auth.search('ou=permission,dc=yunohost,dc=org',
|
||||
permission_search = ldap.search('ou=permission,dc=yunohost,dc=org',
|
||||
'(objectclass=permissionYnh)',
|
||||
['cn', 'groupPermission', 'inheritPermission', 'memberUid'])
|
||||
|
||||
|
@ -141,7 +136,10 @@ def check_permission_for_apps():
|
|||
# We check that the for each installed apps we have at last the "main" permission
|
||||
# and we don't have any permission linked to no apps. The only exception who is not liked to an app
|
||||
# is mail, metronome, and sftp
|
||||
permission_search = auth.search('ou=permission,dc=yunohost,dc=org',
|
||||
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
permission_search = ldap.search('ou=permission,dc=yunohost,dc=org',
|
||||
'(objectclass=permissionYnh)',
|
||||
['cn', 'groupPermission', 'inheritPermission', 'memberUid'])
|
||||
app_l = app_list(installed=True)['apps']
|
||||
|
@ -161,7 +159,7 @@ def check_permission_for_apps():
|
|||
#
|
||||
|
||||
def test_list_permission():
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
|
||||
assert "wiki" in res
|
||||
assert "main" in res['wiki']
|
||||
|
@ -182,27 +180,27 @@ def test_list_permission():
|
|||
#
|
||||
|
||||
def test_add_permission_1():
|
||||
permission_add(auth, "site", "test")
|
||||
permission_add("site", "test")
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert "site" in res
|
||||
assert "test" in res['site']
|
||||
assert "all_users" in res['site']['test']['allowed_groups']
|
||||
assert set(["alice", "bob"]) == set(res['site']['test']['allowed_users'])
|
||||
|
||||
def test_add_permission_2():
|
||||
permission_add(auth, "site", "main", default_allow=False)
|
||||
permission_add("site", "main", default_allow=False)
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert "site" in res
|
||||
assert "main" in res['site']
|
||||
assert [] == res['site']['main']['allowed_groups']
|
||||
assert [] == res['site']['main']['allowed_users']
|
||||
|
||||
def test_remove_permission():
|
||||
permission_remove(auth, "wiki", "main", force=True)
|
||||
permission_remove("wiki", "main", force=True)
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert "wiki" not in res
|
||||
|
||||
#
|
||||
|
@ -212,14 +210,14 @@ def test_remove_permission():
|
|||
def test_add_bad_permission():
|
||||
# Create permission with same name
|
||||
with pytest.raises(YunohostError):
|
||||
permission_add(auth, "wiki", "main")
|
||||
permission_add("wiki", "main")
|
||||
|
||||
def test_remove_bad_permission():
|
||||
# Remove not existant permission
|
||||
with pytest.raises(MoulinetteError):
|
||||
permission_remove(auth, "non_exit", "main", force=True)
|
||||
permission_remove("non_exit", "main", force=True)
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert "wiki" in res
|
||||
assert "main" in res['wiki']
|
||||
assert "blog" in res
|
||||
|
@ -231,9 +229,9 @@ def test_remove_bad_permission():
|
|||
|
||||
def test_remove_main_permission():
|
||||
with pytest.raises(YunohostError):
|
||||
permission_remove(auth, "blog", "main")
|
||||
permission_remove("blog", "main")
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert "mail" in res
|
||||
assert "main" in res['mail']
|
||||
|
||||
|
@ -245,49 +243,49 @@ def test_remove_main_permission():
|
|||
|
||||
def test_allow_first_group():
|
||||
# Remove permission to all_users and define per users
|
||||
user_permission_add(auth, ["wiki"], "main", group="alice")
|
||||
user_permission_add(["wiki"], "main", group="alice")
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert ['alice'] == res['wiki']['main']['allowed_users']
|
||||
assert ['alice'] == res['wiki']['main']['allowed_groups']
|
||||
|
||||
def test_allow_other_group():
|
||||
# Allow new user in a permission
|
||||
user_permission_add(auth, ["blog"], "main", group="bob")
|
||||
user_permission_add(["blog"], "main", group="bob")
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert set(["alice", "bob"]) == set(res['blog']['main']['allowed_users'])
|
||||
assert set(["alice", "bob"]) == set(res['blog']['main']['allowed_groups'])
|
||||
|
||||
def test_disallow_group_1():
|
||||
# Disallow a user in a permission
|
||||
user_permission_remove(auth, ["blog"], "main", group="alice")
|
||||
user_permission_remove(["blog"], "main", group="alice")
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert [] == res['blog']['main']['allowed_users']
|
||||
assert [] == res['blog']['main']['allowed_groups']
|
||||
|
||||
def test_allow_group_1():
|
||||
# Allow a user when he is already allowed
|
||||
user_permission_add(auth, ["blog"], "main", group="alice")
|
||||
user_permission_add(["blog"], "main", group="alice")
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert ["alice"] == res['blog']['main']['allowed_users']
|
||||
assert ["alice"] == res['blog']['main']['allowed_groups']
|
||||
|
||||
def test_disallow_group_1():
|
||||
# Disallow a user when he is already disallowed
|
||||
user_permission_remove(auth, ["blog"], "main", group="bob")
|
||||
user_permission_remove(["blog"], "main", group="bob")
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert ["alice"] == res['blog']['main']['allowed_users']
|
||||
assert ["alice"] == res['blog']['main']['allowed_groups']
|
||||
|
||||
def test_reset_permission():
|
||||
# Reset permission
|
||||
user_permission_clear(auth, ["blog"], "main")
|
||||
user_permission_clear(["blog"], "main")
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert set(["alice", "bob"]) == set(res['blog']['main']['allowed_users'])
|
||||
assert ["all_users"] == res['blog']['main']['allowed_groups']
|
||||
|
||||
|
@ -295,43 +293,43 @@ def test_reset_permission():
|
|||
|
||||
def test_add_url_1():
|
||||
# Add URL in permission which hasn't any URL defined
|
||||
permission_update(auth, "blog", "main", add_url=[maindomain + "/testA"])
|
||||
permission_update("blog", "main", add_url=[maindomain + "/testA"])
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert [maindomain + "/testA"] == res['blog']['main']['URL']
|
||||
|
||||
def test_add_url_2():
|
||||
# Add a second URL in a permission
|
||||
permission_update(auth, "wiki", "main", add_url=[maindomain + "/testA"])
|
||||
permission_update("wiki", "main", add_url=[maindomain + "/testA"])
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert set([maindomain + "/testA", maindomain + "/wiki"]) == set(res['wiki']['main']['URL'])
|
||||
|
||||
def test_remove_url_1():
|
||||
permission_update(auth, "wiki", "main", remove_url=[maindomain + "/wiki"])
|
||||
permission_update("wiki", "main", remove_url=[maindomain + "/wiki"])
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert 'URL' not in res['wiki']['main']
|
||||
|
||||
def test_add_url_3():
|
||||
# Add a url already added
|
||||
permission_update(auth, "wiki", "main", add_url=[maindomain + "/wiki"])
|
||||
permission_update("wiki", "main", add_url=[maindomain + "/wiki"])
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert [maindomain + "/wiki"] == res['wiki']['main']['URL']
|
||||
|
||||
def test_remove_url_2():
|
||||
# Remove a url not added (with a permission which contain some URL)
|
||||
permission_update(auth, "wiki", "main", remove_url=[maindomain + "/not_exist"])
|
||||
permission_update("wiki", "main", remove_url=[maindomain + "/not_exist"])
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert [maindomain + "/wiki"] == res['wiki']['main']['URL']
|
||||
|
||||
def test_remove_url_2():
|
||||
# Remove a url not added (with a permission which contain no URL)
|
||||
permission_update(auth, "blog", "main", remove_url=[maindomain + "/not_exist"])
|
||||
permission_update("blog", "main", remove_url=[maindomain + "/not_exist"])
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert 'URL' not in res['blog']['main']
|
||||
|
||||
#
|
||||
|
@ -341,49 +339,49 @@ def test_remove_url_2():
|
|||
def test_disallow_bad_group_1():
|
||||
# Disallow a group when the group all_users is allowed
|
||||
with pytest.raises(YunohostError):
|
||||
user_permission_remove(auth, "wiki", "main", group="alice")
|
||||
user_permission_remove("wiki", "main", group="alice")
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert ["all_users"] == res['wiki']['main']['allowed_groups']
|
||||
assert set(["alice", "bob"]) == set(res['wiki']['main']['allowed_users'])
|
||||
|
||||
def test_allow_bad_user():
|
||||
# Allow a non existant group
|
||||
with pytest.raises(YunohostError):
|
||||
user_permission_add(auth, ["blog"], "main", group="not_exist")
|
||||
user_permission_add(["blog"], "main", group="not_exist")
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert ["alice"] == res['blog']['main']['allowed_groups']
|
||||
assert ["alice"] == res['blog']['main']['allowed_users']
|
||||
|
||||
def test_disallow_bad_group_2():
|
||||
# Disallow a non existant group
|
||||
with pytest.raises(YunohostError):
|
||||
user_permission_remove(auth, ["blog"], "main", group="not_exist")
|
||||
user_permission_remove(["blog"], "main", group="not_exist")
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert ["alice"] == res['blog']['main']['allowed_groups']
|
||||
assert ["alice"] == res['blog']['main']['allowed_users']
|
||||
|
||||
def test_allow_bad_permission_1():
|
||||
# Allow a user to a non existant permission
|
||||
with pytest.raises(YunohostError):
|
||||
user_permission_add(auth, ["wiki"], "not_exit", group="alice")
|
||||
user_permission_add(["wiki"], "not_exit", group="alice")
|
||||
|
||||
def test_allow_bad_permission_2():
|
||||
# Allow a user to a non existant permission
|
||||
with pytest.raises(YunohostError):
|
||||
user_permission_add(auth, ["not_exit"], "main", group="alice")
|
||||
user_permission_add(["not_exit"], "main", group="alice")
|
||||
|
||||
#
|
||||
# Application interaction
|
||||
#
|
||||
|
||||
def test_install_app():
|
||||
app_install(auth, "./tests/apps/permissions_app_ynh",
|
||||
app_install("./tests/apps/permissions_app_ynh",
|
||||
args="domain=%s&path=%s&admin=%s" % (maindomain, "/urlpermissionapp", "alice"), force=True)
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert "permissions_app" in res
|
||||
assert "main" in res['permissions_app']
|
||||
assert [maindomain + "/urlpermissionapp"] == res['permissions_app']['main']['URL']
|
||||
|
@ -400,25 +398,25 @@ def test_install_app():
|
|||
assert set(["alice", "bob"]) == set(res['permissions_app']['dev']['allowed_users'])
|
||||
|
||||
def test_remove_app():
|
||||
app_install(auth, "./tests/apps/permissions_app_ynh",
|
||||
app_install("./tests/apps/permissions_app_ynh",
|
||||
args="domain=%s&path=%s&admin=%s" % (maindomain, "/urlpermissionapp", "alice"), force=True)
|
||||
app_remove(auth, "permissions_app")
|
||||
app_remove("permissions_app")
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert "permissions_app" not in res
|
||||
|
||||
def test_change_url():
|
||||
app_install(auth, "./tests/apps/permissions_app_ynh",
|
||||
app_install("./tests/apps/permissions_app_ynh",
|
||||
args="domain=%s&path=%s&admin=%s" % (maindomain, "/urlpermissionapp", "alice"), force=True)
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert [maindomain + "/urlpermissionapp"] == res['permissions_app']['main']['URL']
|
||||
assert [maindomain + "/urlpermissionapp/admin"] == res['permissions_app']['admin']['URL']
|
||||
assert [maindomain + "/urlpermissionapp/dev"] == res['permissions_app']['dev']['URL']
|
||||
|
||||
app_change_url(auth, "permissions_app", maindomain, "/newchangeurl")
|
||||
app_change_url("permissions_app", maindomain, "/newchangeurl")
|
||||
|
||||
res = user_permission_list(auth)['permissions']
|
||||
res = user_permission_list()['permissions']
|
||||
assert [maindomain + "/newchangeurl"] == res['permissions_app']['main']['URL']
|
||||
assert [maindomain + "/newchangeurl/admin"] == res['permissions_app']['admin']['URL']
|
||||
assert [maindomain + "/newchangeurl/dev"] == res['permissions_app']['dev']['URL']
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import pytest
|
||||
|
||||
from moulinette.core import init_authenticator, MoulinetteError
|
||||
from moulinette.core import MoulinetteError
|
||||
from yunohost.user import user_list, user_info, user_group_list, user_create, user_delete, user_update, user_group_add, user_group_delete, user_group_update, user_group_info
|
||||
from yunohost.domain import _get_maindomain
|
||||
from yunohost.utils.error import YunohostError
|
||||
|
@ -9,33 +9,25 @@ from yunohost.tests.test_permission import check_LDAP_db_integrity
|
|||
# Get main domain
|
||||
maindomain = _get_maindomain()
|
||||
|
||||
# Instantiate LDAP Authenticator
|
||||
AUTH_IDENTIFIER = ('ldap', 'as-root')
|
||||
AUTH_PARAMETERS = {'uri': 'ldapi://%2Fvar%2Frun%2Fslapd%2Fldapi',
|
||||
'base_dn': 'dc=yunohost,dc=org',
|
||||
'user_rdn': 'gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth'}
|
||||
|
||||
auth = init_authenticator(AUTH_IDENTIFIER, AUTH_PARAMETERS)
|
||||
|
||||
def clean_user_groups():
|
||||
for u in user_list(auth)['users']:
|
||||
user_delete(auth, u)
|
||||
for u in user_list()['users']:
|
||||
user_delete(u)
|
||||
|
||||
for g in user_group_list(auth)['groups']:
|
||||
for g in user_group_list()['groups']:
|
||||
if g != "all_users":
|
||||
user_group_delete(auth, g)
|
||||
user_group_delete(g)
|
||||
|
||||
def setup_function(function):
|
||||
clean_user_groups()
|
||||
|
||||
user_create(auth, "alice", "Alice", "White", "alice@" + maindomain, "test123Ynh")
|
||||
user_create(auth, "bob", "Bob", "Snow", "bob@" + maindomain, "test123Ynh")
|
||||
user_create(auth, "jack", "Jack", "Black", "jack@" + maindomain, "test123Ynh")
|
||||
user_create("alice", "Alice", "White", "alice@" + maindomain, "test123Ynh")
|
||||
user_create("bob", "Bob", "Snow", "bob@" + maindomain, "test123Ynh")
|
||||
user_create("jack", "Jack", "Black", "jack@" + maindomain, "test123Ynh")
|
||||
|
||||
user_group_add(auth, "dev")
|
||||
user_group_add(auth, "apps")
|
||||
user_group_update(auth, "dev", add_user=["alice"])
|
||||
user_group_update(auth, "apps", add_user=["bob"])
|
||||
user_group_add("dev")
|
||||
user_group_add("apps")
|
||||
user_group_update("dev", add_user=["alice"])
|
||||
user_group_update("apps", add_user=["bob"])
|
||||
|
||||
def teardown_function(function):
|
||||
clean_user_groups()
|
||||
|
@ -51,14 +43,14 @@ def check_LDAP_db_integrity_call():
|
|||
#
|
||||
|
||||
def test_list_users():
|
||||
res = user_list(auth)['users']
|
||||
res = user_list()['users']
|
||||
|
||||
assert "alice" in res
|
||||
assert "bob" in res
|
||||
assert "jack" in res
|
||||
|
||||
def test_list_groups():
|
||||
res = user_group_list(auth)['groups']
|
||||
res = user_group_list()['groups']
|
||||
|
||||
assert "all_users" in res
|
||||
assert "alice" in res
|
||||
|
@ -74,33 +66,33 @@ def test_list_groups():
|
|||
#
|
||||
|
||||
def test_create_user():
|
||||
user_create(auth, "albert", "Albert", "Good", "alber@" + maindomain, "test123Ynh")
|
||||
user_create("albert", "Albert", "Good", "alber@" + maindomain, "test123Ynh")
|
||||
|
||||
group_res = user_group_list(auth)['groups']
|
||||
assert "albert" in user_list(auth)['users']
|
||||
group_res = user_group_list()['groups']
|
||||
assert "albert" in user_list()['users']
|
||||
assert "albert" in group_res
|
||||
assert "albert" in group_res['albert']['members']
|
||||
assert "albert" in group_res['all_users']['members']
|
||||
|
||||
def test_del_user():
|
||||
user_delete(auth, "alice")
|
||||
user_delete("alice")
|
||||
|
||||
group_res = user_group_list(auth)['groups']
|
||||
assert "alice" not in user_list(auth)
|
||||
group_res = user_group_list()['groups']
|
||||
assert "alice" not in user_list()
|
||||
assert "alice" not in group_res
|
||||
assert "alice" not in group_res['all_users']['members']
|
||||
|
||||
def test_add_group():
|
||||
user_group_add(auth, "adminsys")
|
||||
user_group_add("adminsys")
|
||||
|
||||
group_res = user_group_list(auth)['groups']
|
||||
group_res = user_group_list()['groups']
|
||||
assert "adminsys" in group_res
|
||||
assert "members" not in group_res['adminsys']
|
||||
|
||||
def test_del_group():
|
||||
user_group_delete(auth, "dev")
|
||||
user_group_delete("dev")
|
||||
|
||||
group_res = user_group_list(auth)['groups']
|
||||
group_res = user_group_list()['groups']
|
||||
assert "dev" not in group_res
|
||||
|
||||
#
|
||||
|
@ -110,79 +102,79 @@ def test_del_group():
|
|||
def test_add_bad_user_1():
|
||||
# Check email already exist
|
||||
with pytest.raises(MoulinetteError):
|
||||
user_create(auth, "alice2", "Alice", "White", "alice@" + maindomain, "test123Ynh")
|
||||
user_create("alice2", "Alice", "White", "alice@" + maindomain, "test123Ynh")
|
||||
|
||||
def test_add_bad_user_2():
|
||||
# Check to short password
|
||||
with pytest.raises(MoulinetteError):
|
||||
user_create(auth, "other", "Alice", "White", "other@" + maindomain, "12")
|
||||
user_create("other", "Alice", "White", "other@" + maindomain, "12")
|
||||
|
||||
def test_add_bad_user_3():
|
||||
# Check user already exist
|
||||
with pytest.raises(MoulinetteError):
|
||||
user_create(auth, "alice", "Alice", "White", "other@" + maindomain, "test123Ynh")
|
||||
user_create("alice", "Alice", "White", "other@" + maindomain, "test123Ynh")
|
||||
|
||||
def test_del_bad_user_1():
|
||||
# Check user not found
|
||||
with pytest.raises(MoulinetteError):
|
||||
user_delete(auth, "not_exit")
|
||||
user_delete("not_exit")
|
||||
|
||||
def test_add_bad_group_1():
|
||||
# Check groups already exist with special group "all_users"
|
||||
with pytest.raises(YunohostError):
|
||||
user_group_add(auth, "all_users")
|
||||
user_group_add("all_users")
|
||||
|
||||
def test_add_bad_group_2():
|
||||
# Check groups already exist (for standard groups)
|
||||
with pytest.raises(MoulinetteError):
|
||||
user_group_add(auth, "dev")
|
||||
user_group_add("dev")
|
||||
|
||||
def test_del_bad_group_1():
|
||||
# Check not allowed to remove this groups
|
||||
with pytest.raises(YunohostError):
|
||||
user_group_delete(auth, "all_users")
|
||||
user_group_delete("all_users")
|
||||
|
||||
def test_del_bad_group_2():
|
||||
# Check groups not found
|
||||
with pytest.raises(MoulinetteError):
|
||||
user_group_delete(auth, "not_exit")
|
||||
user_group_delete("not_exit")
|
||||
|
||||
#
|
||||
# Update function
|
||||
#
|
||||
|
||||
def test_update_user_1():
|
||||
user_update(auth, "alice", firstname="NewName", lastname="NewLast")
|
||||
user_update("alice", firstname="NewName", lastname="NewLast")
|
||||
|
||||
info = user_info(auth, "alice")
|
||||
info = user_info("alice")
|
||||
assert "NewName" == info['firstname']
|
||||
assert "NewLast" == info['lastname']
|
||||
|
||||
def test_update_group_1():
|
||||
user_group_update(auth, "dev", add_user=["bob"])
|
||||
user_group_update("dev", add_user=["bob"])
|
||||
|
||||
group_res = user_group_list(auth)['groups']
|
||||
group_res = user_group_list()['groups']
|
||||
assert set(["alice", "bob"]) == set(group_res['dev']['members'])
|
||||
|
||||
def test_update_group_2():
|
||||
# Try to add a user in a group when the user is already in
|
||||
user_group_update(auth, "apps", add_user=["bob"])
|
||||
user_group_update("apps", add_user=["bob"])
|
||||
|
||||
group_res = user_group_list(auth)['groups']
|
||||
group_res = user_group_list()['groups']
|
||||
assert ["bob"] == group_res['apps']['members']
|
||||
|
||||
def test_update_group_3():
|
||||
# Try to remove a user in a group
|
||||
user_group_update(auth, "apps", remove_user=["bob"])
|
||||
user_group_update("apps", remove_user=["bob"])
|
||||
|
||||
group_res = user_group_list(auth)['groups']
|
||||
group_res = user_group_list()['groups']
|
||||
assert "members" not in group_res['apps']
|
||||
|
||||
def test_update_group_4():
|
||||
# Try to remove a user in a group when it is not already in
|
||||
user_group_update(auth, "apps", remove_user=["jack"])
|
||||
user_group_update("apps", remove_user=["jack"])
|
||||
|
||||
group_res = user_group_list(auth)['groups']
|
||||
group_res = user_group_list()['groups']
|
||||
assert ["bob"] == group_res['apps']['members']
|
||||
|
||||
#
|
||||
|
@ -192,27 +184,27 @@ def test_update_group_4():
|
|||
def test_bad_update_user_1():
|
||||
# Check user not found
|
||||
with pytest.raises(YunohostError):
|
||||
user_update(auth, "not_exit", firstname="NewName", lastname="NewLast")
|
||||
user_update("not_exit", firstname="NewName", lastname="NewLast")
|
||||
|
||||
|
||||
def bad_update_group_1():
|
||||
# Check groups not found
|
||||
with pytest.raises(YunohostError):
|
||||
user_group_update(auth, "not_exit", add_user=["alice"])
|
||||
user_group_update("not_exit", add_user=["alice"])
|
||||
|
||||
def test_bad_update_group_2():
|
||||
# Check remove user in groups "all_users" not allowed
|
||||
with pytest.raises(YunohostError):
|
||||
user_group_update(auth, "all_users", remove_user=["alice"])
|
||||
user_group_update("all_users", remove_user=["alice"])
|
||||
|
||||
def test_bad_update_group_3():
|
||||
# Check remove user in it own group not allowed
|
||||
with pytest.raises(YunohostError):
|
||||
user_group_update(auth, "alice", remove_user=["alice"])
|
||||
user_group_update("alice", remove_user=["alice"])
|
||||
|
||||
def test_bad_update_group_1():
|
||||
# Check add bad user in group
|
||||
with pytest.raises(YunohostError):
|
||||
user_group_update(auth, "dev", add_user=["not_exist"])
|
||||
user_group_update("dev", add_user=["not_exist"])
|
||||
|
||||
assert "not_exist" not in user_group_list(auth)["groups"]["dev"]
|
||||
assert "not_exist" not in user_group_list()["groups"]["dev"]
|
||||
|
|
|
@ -30,17 +30,11 @@ import json
|
|||
import subprocess
|
||||
import pwd
|
||||
import socket
|
||||
from glob import glob
|
||||
from xmlrpclib import Fault
|
||||
from importlib import import_module
|
||||
from collections import OrderedDict
|
||||
|
||||
import apt
|
||||
import apt.progress
|
||||
|
||||
from moulinette import msettings, msignals, m18n
|
||||
from moulinette.core import init_authenticator
|
||||
from yunohost.utils.error import YunohostError
|
||||
from moulinette import msignals, m18n
|
||||
from moulinette.utils.log import getActionLogger
|
||||
from moulinette.utils.process import check_output, call_async_output
|
||||
from moulinette.utils.filesystem import read_json, write_to_json
|
||||
|
@ -48,11 +42,12 @@ from yunohost.app import app_fetchlist, app_info, app_upgrade, app_ssowatconf, a
|
|||
from yunohost.domain import domain_add, domain_list, _get_maindomain, _set_maindomain
|
||||
from yunohost.dyndns import _dyndns_available, _dyndns_provides
|
||||
from yunohost.firewall import firewall_upnp
|
||||
from yunohost.service import service_status, service_log, service_start, service_enable
|
||||
from yunohost.service import service_status, service_start, service_enable
|
||||
from yunohost.regenconf import regen_conf
|
||||
from yunohost.monitor import monitor_disk, monitor_system
|
||||
from yunohost.utils.packages import ynh_packages_version
|
||||
from yunohost.utils.packages import ynh_packages_version, _dump_sources_list, _list_upgradable_apt_packages
|
||||
from yunohost.utils.network import get_public_ip
|
||||
from yunohost.utils.error import YunohostError
|
||||
from yunohost.log import is_unit_operation, OperationLogger
|
||||
|
||||
# FIXME this is a duplicate from apps.py
|
||||
|
@ -69,31 +64,27 @@ def tools_ldapinit():
|
|||
|
||||
"""
|
||||
|
||||
# Instantiate LDAP Authenticator
|
||||
AUTH_IDENTIFIER = ('ldap', 'as-root')
|
||||
AUTH_PARAMETERS = {'uri': 'ldapi://%2Fvar%2Frun%2Fslapd%2Fldapi',
|
||||
'base_dn': 'dc=yunohost,dc=org',
|
||||
'user_rdn': 'gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth'}
|
||||
auth = init_authenticator(AUTH_IDENTIFIER, AUTH_PARAMETERS)
|
||||
|
||||
with open('/usr/share/yunohost/yunohost-config/moulinette/ldap_scheme.yml') as f:
|
||||
ldap_map = yaml.load(f)
|
||||
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
for rdn, attr_dict in ldap_map['parents'].items():
|
||||
try:
|
||||
auth.add(rdn, attr_dict)
|
||||
ldap.add(rdn, attr_dict)
|
||||
except Exception as e:
|
||||
logger.warn("Error when trying to inject '%s' -> '%s' into ldap: %s" % (rdn, attr_dict, e))
|
||||
|
||||
for rdn, attr_dict in ldap_map['children'].items():
|
||||
try:
|
||||
auth.add(rdn, attr_dict)
|
||||
ldap.add(rdn, attr_dict)
|
||||
except Exception as e:
|
||||
logger.warn("Error when trying to inject '%s' -> '%s' into ldap: %s" % (rdn, attr_dict, e))
|
||||
|
||||
for rdn, attr_dict in ldap_map['depends_children'].items():
|
||||
try:
|
||||
auth.add(rdn, attr_dict)
|
||||
ldap.add(rdn, attr_dict)
|
||||
except Exception as e:
|
||||
logger.warn("Error when trying to inject '%s' -> '%s' into ldap: %s" % (rdn, attr_dict, e))
|
||||
|
||||
|
@ -109,7 +100,7 @@ def tools_ldapinit():
|
|||
'userPassword': 'yunohost'
|
||||
}
|
||||
|
||||
auth.update('cn=admin', admin_dict)
|
||||
ldap.update('cn=admin', admin_dict)
|
||||
|
||||
# Force nscd to refresh cache to take admin creation into account
|
||||
subprocess.call(['nscd', '-i', 'passwd'])
|
||||
|
@ -122,10 +113,9 @@ def tools_ldapinit():
|
|||
raise YunohostError('installation_failed')
|
||||
|
||||
logger.success(m18n.n('ldap_initialized'))
|
||||
return auth
|
||||
|
||||
|
||||
def tools_adminpw(auth, new_password, check_strength=True):
|
||||
def tools_adminpw(new_password, check_strength=True):
|
||||
"""
|
||||
Change admin password
|
||||
|
||||
|
@ -147,8 +137,11 @@ def tools_adminpw(auth, new_password, check_strength=True):
|
|||
|
||||
new_hash = _hash_user_password(new_password)
|
||||
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
try:
|
||||
auth.update("cn=admin", {"userPassword": new_hash, })
|
||||
ldap.update("cn=admin", {"userPassword": new_hash, })
|
||||
except:
|
||||
logger.exception('unable to change admin password')
|
||||
raise YunohostError('admin_password_change_failed')
|
||||
|
@ -172,7 +165,7 @@ def tools_adminpw(auth, new_password, check_strength=True):
|
|||
|
||||
|
||||
@is_unit_operation()
|
||||
def tools_maindomain(operation_logger, auth, new_domain=None):
|
||||
def tools_maindomain(operation_logger, new_domain=None):
|
||||
"""
|
||||
Check the current main domain, or change it
|
||||
|
||||
|
@ -186,7 +179,7 @@ def tools_maindomain(operation_logger, auth, new_domain=None):
|
|||
return {'current_main_domain': _get_maindomain()}
|
||||
|
||||
# Check domain exists
|
||||
if new_domain not in domain_list(auth)['domains']:
|
||||
if new_domain not in domain_list()['domains']:
|
||||
raise YunohostError('domain_unknown')
|
||||
|
||||
operation_logger.related_to.append(('domain', new_domain))
|
||||
|
@ -215,7 +208,7 @@ def tools_maindomain(operation_logger, auth, new_domain=None):
|
|||
_set_hostname(new_domain)
|
||||
|
||||
# Generate SSOwat configuration file
|
||||
app_ssowatconf(auth)
|
||||
app_ssowatconf()
|
||||
|
||||
# Regen configurations
|
||||
try:
|
||||
|
@ -342,7 +335,7 @@ def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False,
|
|||
|
||||
# Initialize LDAP for YunoHost
|
||||
# TODO: Improve this part by integrate ldapinit into conf_regen hook
|
||||
auth = tools_ldapinit()
|
||||
tools_ldapinit()
|
||||
|
||||
# Create required folders
|
||||
folders_to_create = [
|
||||
|
@ -416,11 +409,11 @@ def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False,
|
|||
|
||||
# New domain config
|
||||
regen_conf(['nsswitch'], force=True)
|
||||
domain_add(auth, domain, dyndns)
|
||||
tools_maindomain(auth, domain)
|
||||
domain_add(domain, dyndns)
|
||||
tools_maindomain(domain)
|
||||
|
||||
# Change LDAP admin password
|
||||
tools_adminpw(auth, password, check_strength=not force_password)
|
||||
tools_adminpw(password, check_strength=not force_password)
|
||||
|
||||
# Enable UPnP silently and reload firewall
|
||||
firewall_upnp('enable', no_refresh=True)
|
||||
|
@ -472,28 +465,31 @@ def tools_regen_conf(names=[], with_diff=False, force=False, dry_run=False,
|
|||
return regen_conf(names, with_diff, force, dry_run, list_pending)
|
||||
|
||||
|
||||
def tools_update(ignore_apps=False, ignore_packages=False):
|
||||
def tools_update(apps=False, system=False):
|
||||
"""
|
||||
Update apps & package cache, then display changelog
|
||||
Update apps & system package cache
|
||||
|
||||
Keyword arguments:
|
||||
ignore_apps -- Ignore app list update and changelog
|
||||
ignore_packages -- Ignore apt cache update and changelog
|
||||
|
||||
system -- Fetch available system packages upgrades (equivalent to apt update)
|
||||
apps -- Fetch the application list to check which apps can be upgraded
|
||||
"""
|
||||
# "packages" will list upgradable packages
|
||||
packages = []
|
||||
if not ignore_packages:
|
||||
|
||||
# If neither --apps nor --system specified, do both
|
||||
if not apps and not system:
|
||||
apps = True
|
||||
system = True
|
||||
|
||||
upgradable_system_packages = []
|
||||
if system:
|
||||
|
||||
# Update APT cache
|
||||
# LC_ALL=C is here to make sure the results are in english
|
||||
command = "LC_ALL=C apt update"
|
||||
# TODO : add @is_unit_operation to tools_update so that the
|
||||
# debug output can be fetched when there's an issue...
|
||||
|
||||
# Filter boring message about "apt not having a stable CLI interface"
|
||||
# Also keep track of wether or not we encountered a warning...
|
||||
warnings = []
|
||||
|
||||
def is_legit_warning(m):
|
||||
legit_warning = m.rstrip() and "apt does not have a stable CLI interface" not in m.rstrip()
|
||||
if legit_warning:
|
||||
|
@ -516,161 +512,208 @@ def tools_update(ignore_apps=False, ignore_packages=False):
|
|||
elif warnings:
|
||||
logger.error(m18n.n('update_apt_cache_warning', sourceslist='\n'.join(_dump_sources_list())))
|
||||
|
||||
packages = list(_list_upgradable_apt_packages())
|
||||
upgradable_system_packages = list(_list_upgradable_apt_packages())
|
||||
logger.debug(m18n.n('done'))
|
||||
|
||||
# "apps" will list upgradable packages
|
||||
apps = []
|
||||
if not ignore_apps:
|
||||
upgradable_apps = []
|
||||
if apps:
|
||||
logger.info(m18n.n('updating_app_lists'))
|
||||
try:
|
||||
app_fetchlist()
|
||||
except YunohostError:
|
||||
# FIXME : silent exception !?
|
||||
pass
|
||||
|
||||
app_list_installed = os.listdir(APPS_SETTING_PATH)
|
||||
for app_id in app_list_installed:
|
||||
upgradable_apps = list(_list_upgradable_apps())
|
||||
|
||||
app_dict = app_info(app_id, raw=True)
|
||||
if len(upgradable_apps) == 0 and len(upgradable_system_packages) == 0:
|
||||
logger.info(m18n.n('already_up_to_date'))
|
||||
|
||||
if app_dict["upgradable"] == "yes":
|
||||
apps.append({
|
||||
'id': app_id,
|
||||
'label': app_dict['settings']['label']
|
||||
})
|
||||
|
||||
if len(apps) == 0 and len(packages) == 0:
|
||||
logger.info(m18n.n('packages_no_upgrade'))
|
||||
|
||||
return {'packages': packages, 'apps': apps}
|
||||
return {'system': upgradable_system_packages, 'apps': upgradable_apps}
|
||||
|
||||
|
||||
# TODO : move this to utils/packages.py ?
|
||||
def _list_upgradable_apt_packages():
|
||||
def _list_upgradable_apps():
|
||||
|
||||
# List upgradable packages
|
||||
# LC_ALL=C is here to make sure the results are in english
|
||||
upgradable_raw = check_output("LC_ALL=C apt list --upgradable")
|
||||
app_list_installed = os.listdir(APPS_SETTING_PATH)
|
||||
for app_id in app_list_installed:
|
||||
|
||||
# Dirty parsing of the output
|
||||
upgradable_raw = [l.strip() for l in upgradable_raw.split("\n") if l.strip()]
|
||||
for line in upgradable_raw:
|
||||
# Remove stupid warning and verbose messages >.>
|
||||
if "apt does not have a stable CLI interface" in line or "Listing..." in line:
|
||||
continue
|
||||
# line should look like :
|
||||
# yunohost/stable 3.5.0.2+201903211853 all [upgradable from: 3.4.2.4+201903080053]
|
||||
line = line.split()
|
||||
if len(line) != 6:
|
||||
logger.warning("Failed to parse this line : %s" % ' '.join(line))
|
||||
continue
|
||||
app_dict = app_info(app_id, raw=True)
|
||||
|
||||
yield {
|
||||
"name": line[0].split("/")[0],
|
||||
"new_version": line[1],
|
||||
"current_version": line[5].strip("]"),
|
||||
}
|
||||
|
||||
|
||||
def _dump_sources_list():
|
||||
|
||||
filenames = glob("/etc/apt/sources.list") + glob("/etc/apt/sources.list.d/*")
|
||||
for filename in filenames:
|
||||
with open(filename, "r") as f:
|
||||
for line in f.readlines():
|
||||
if line.startswith("#") or not line.strip():
|
||||
continue
|
||||
yield filename.replace("/etc/apt/", "") + ":" + line.strip()
|
||||
if app_dict["upgradable"] == "yes":
|
||||
yield {
|
||||
'id': app_id,
|
||||
'label': app_dict['settings']['label']
|
||||
}
|
||||
|
||||
|
||||
@is_unit_operation()
|
||||
def tools_upgrade(operation_logger, auth, ignore_apps=False, ignore_packages=False):
|
||||
def tools_upgrade(operation_logger, apps=None, system=False):
|
||||
"""
|
||||
Update apps & package cache, then display changelog
|
||||
|
||||
Keyword arguments:
|
||||
ignore_apps -- Ignore apps upgrade
|
||||
ignore_packages -- Ignore APT packages upgrade
|
||||
|
||||
apps -- List of apps to upgrade (or [] to update all apps)
|
||||
system -- True to upgrade system
|
||||
"""
|
||||
from yunohost.utils import packages
|
||||
if packages.dpkg_is_broken():
|
||||
raise YunohostError("dpkg_is_broken")
|
||||
|
||||
failure = False
|
||||
# Check for obvious conflict with other dpkg/apt commands already running in parallel
|
||||
if not packages.dpkg_lock_available():
|
||||
raise YunohostError("dpkg_lock_not_available")
|
||||
|
||||
# Retrieve interface
|
||||
is_api = True if msettings.get('interface') == 'api' else False
|
||||
if system is not False and apps is not None:
|
||||
raise YunohostError("tools_upgrade_cant_both")
|
||||
|
||||
if not ignore_packages:
|
||||
if system is False and apps is None:
|
||||
raise YunohostError("tools_upgrade_at_least_one")
|
||||
|
||||
apt.apt_pkg.init()
|
||||
apt.apt_pkg.config.set("DPkg::Options::", "--force-confdef")
|
||||
apt.apt_pkg.config.set("DPkg::Options::", "--force-confold")
|
||||
#
|
||||
# Apps
|
||||
# This is basically just an alias to yunohost app upgrade ...
|
||||
#
|
||||
|
||||
cache = apt.Cache()
|
||||
cache.open(None)
|
||||
cache.upgrade(True)
|
||||
if apps is not None:
|
||||
|
||||
# If API call
|
||||
if is_api:
|
||||
critical_packages = ("moulinette", "yunohost",
|
||||
"yunohost-admin", "ssowat", "python")
|
||||
critical_upgrades = set()
|
||||
# Make sure there's actually something to upgrade
|
||||
|
||||
for pkg in cache.get_changes():
|
||||
if pkg.name in critical_packages:
|
||||
critical_upgrades.add(pkg.name)
|
||||
# Temporarily keep package ...
|
||||
pkg.mark_keep()
|
||||
upgradable_apps = [app["id"] for app in _list_upgradable_apps()]
|
||||
|
||||
# ... and set a hourly cron up to upgrade critical packages
|
||||
if critical_upgrades:
|
||||
logger.info(m18n.n('packages_upgrade_critical_later',
|
||||
packages=', '.join(critical_upgrades)))
|
||||
with open('/etc/cron.d/yunohost-upgrade', 'w+') as f:
|
||||
f.write('00 * * * * root PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin apt-get install %s -y && rm -f /etc/cron.d/yunohost-upgrade\n' % ' '.join(critical_upgrades))
|
||||
if not upgradable_apps:
|
||||
logger.info(m18n.n("app_no_upgrade"))
|
||||
return
|
||||
elif len(apps) and all(app not in upgradable_apps for app in apps):
|
||||
logger.info(m18n.n("apps_already_up_to_date"))
|
||||
return
|
||||
|
||||
if cache.get_changes():
|
||||
logger.info(m18n.n('upgrading_packages'))
|
||||
# Actually start the upgrades
|
||||
|
||||
operation_logger.start()
|
||||
try:
|
||||
os.environ["DEBIAN_FRONTEND"] = "noninteractive"
|
||||
# Apply APT changes
|
||||
# TODO: Logs output for the API
|
||||
cache.commit(apt.progress.text.AcquireProgress(),
|
||||
apt.progress.base.InstallProgress())
|
||||
except Exception as e:
|
||||
failure = True
|
||||
logger.warning('unable to upgrade packages: %s' % str(e))
|
||||
logger.error(m18n.n('packages_upgrade_failed'))
|
||||
operation_logger.error(m18n.n('packages_upgrade_failed'))
|
||||
else:
|
||||
logger.info(m18n.n('done'))
|
||||
operation_logger.success()
|
||||
finally:
|
||||
del os.environ["DEBIAN_FRONTEND"]
|
||||
else:
|
||||
logger.info(m18n.n('packages_no_upgrade'))
|
||||
|
||||
if not ignore_apps:
|
||||
try:
|
||||
app_upgrade(auth)
|
||||
app_upgrade(app=apps)
|
||||
except Exception as e:
|
||||
failure = True
|
||||
logger.warning('unable to upgrade apps: %s' % str(e))
|
||||
logger.error(m18n.n('app_upgrade_some_app_failed'))
|
||||
|
||||
if not failure:
|
||||
logger.success(m18n.n('system_upgraded'))
|
||||
return
|
||||
|
||||
# Return API logs if it is an API call
|
||||
if is_api:
|
||||
return {"log": service_log('yunohost-api', number="100").values()[0]}
|
||||
#
|
||||
# System
|
||||
#
|
||||
|
||||
if system is True:
|
||||
|
||||
# Check that there's indeed some packages to upgrade
|
||||
upgradables = list(_list_upgradable_apt_packages())
|
||||
if not upgradables:
|
||||
logger.info(m18n.n('already_up_to_date'))
|
||||
|
||||
logger.info(m18n.n('upgrading_packages'))
|
||||
operation_logger.start()
|
||||
|
||||
# Critical packages are packages that we can't just upgrade
|
||||
# randomly from yunohost itself... upgrading them is likely to
|
||||
critical_packages = ("moulinette", "yunohost", "yunohost-admin", "ssowat", "python")
|
||||
|
||||
critical_packages_upgradable = [p for p in upgradables if p["name"] in critical_packages]
|
||||
noncritical_packages_upgradable = [p for p in upgradables if p["name"] not in critical_packages]
|
||||
|
||||
# Prepare dist-upgrade command
|
||||
dist_upgrade = "DEBIAN_FRONTEND=noninteractive"
|
||||
dist_upgrade += " APT_LISTCHANGES_FRONTEND=none"
|
||||
dist_upgrade += " apt-get"
|
||||
dist_upgrade += " --fix-broken --show-upgraded --assume-yes"
|
||||
for conf_flag in ["old", "miss", "def"]:
|
||||
dist_upgrade += ' -o Dpkg::Options::="--force-conf{}"'.format(conf_flag)
|
||||
dist_upgrade += " dist-upgrade"
|
||||
|
||||
#
|
||||
# "Regular" packages upgrade
|
||||
#
|
||||
if noncritical_packages_upgradable:
|
||||
|
||||
logger.info(m18n.n("tools_upgrade_regular_packages"))
|
||||
|
||||
# Mark all critical packages as held
|
||||
for package in critical_packages:
|
||||
check_output("apt-mark hold %s" % package)
|
||||
|
||||
# Doublecheck with apt-mark showhold that packages are indeed held ...
|
||||
held_packages = check_output("apt-mark showhold").split("\n")
|
||||
if any(p not in held_packages for p in critical_packages):
|
||||
logger.warning(m18n.n("tools_upgrade_cant_hold_critical_packages"))
|
||||
operation_logger.error(m18n.n('packages_upgrade_failed'))
|
||||
raise YunohostError(m18n.n('packages_upgrade_failed'))
|
||||
|
||||
logger.debug("Running apt command :\n{}".format(dist_upgrade))
|
||||
|
||||
callbacks = (
|
||||
lambda l: logger.info(l.rstrip() + "\r"),
|
||||
lambda l: logger.warning(l.rstrip()),
|
||||
)
|
||||
returncode = call_async_output(dist_upgrade, callbacks, shell=True)
|
||||
if returncode != 0:
|
||||
logger.warning('tools_upgrade_regular_packages_failed',
|
||||
packages_list=', '.join(noncritical_packages_upgradable))
|
||||
operation_logger.error(m18n.n('packages_upgrade_failed'))
|
||||
raise YunohostError(m18n.n('packages_upgrade_failed'))
|
||||
|
||||
#
|
||||
# Critical packages upgrade
|
||||
#
|
||||
if critical_packages_upgradable:
|
||||
|
||||
logger.info(m18n.n("tools_upgrade_special_packages"))
|
||||
|
||||
# Mark all critical packages as unheld
|
||||
for package in critical_packages:
|
||||
check_output("apt-mark unhold %s" % package)
|
||||
|
||||
# Doublecheck with apt-mark showhold that packages are indeed unheld ...
|
||||
held_packages = check_output("apt-mark showhold").split("\n")
|
||||
if any(p in held_packages for p in critical_packages):
|
||||
logger.warning(m18n.n("tools_upgrade_cant_unhold_critical_packages"))
|
||||
operation_logger.error(m18n.n('packages_upgrade_failed'))
|
||||
raise YunohostError(m18n.n('packages_upgrade_failed'))
|
||||
|
||||
#
|
||||
# Here we use a dirty hack to run a command after the current
|
||||
# "yunohost tools upgrade", because the upgrade of yunohost
|
||||
# will also trigger other yunohost commands (e.g. "yunohost tools migrations migrate")
|
||||
# (also the upgrade of the package, if executed from the webadmin, is
|
||||
# likely to kill/restart the api which is in turn likely to kill this
|
||||
# command before it ends...)
|
||||
#
|
||||
logfile = operation_logger.log_path
|
||||
command = dist_upgrade + " 2>&1 | tee -a {}".format(logfile)
|
||||
|
||||
MOULINETTE_LOCK = "/var/run/moulinette_yunohost.lock"
|
||||
wait_until_end_of_yunohost_command = "(while [ -f {} ]; do sleep 2; done)".format(MOULINETTE_LOCK)
|
||||
mark_success = "(echo 'Done!' | tee -a {} && echo 'success: true' >> {})".format(logfile, operation_logger.md_path)
|
||||
mark_failure = "(echo 'Failed :(' | tee -a {} && echo 'success: false' >> {})".format(logfile, operation_logger.md_path)
|
||||
update_log_metadata = "sed -i \"s/ended_at: .*$/ended_at: $(date -u +'%Y-%m-%d %H:%M:%S.%N')/\" {}"
|
||||
update_log_metadata = update_log_metadata.format(operation_logger.md_path)
|
||||
|
||||
upgrade_completed = "\n" + m18n.n("tools_upgrade_special_packages_completed")
|
||||
command = "(({wait} && {cmd}) && {mark_success} || {mark_failure}; {update_metadata}; echo '{done}') &".format(
|
||||
wait=wait_until_end_of_yunohost_command,
|
||||
cmd=command,
|
||||
mark_success=mark_success,
|
||||
mark_failure=mark_failure,
|
||||
update_metadata=update_log_metadata,
|
||||
done=upgrade_completed)
|
||||
|
||||
logger.warning(m18n.n("tools_upgrade_special_packages_explanation"))
|
||||
logger.debug("Running command :\n{}".format(command))
|
||||
os.system(command)
|
||||
return
|
||||
|
||||
else:
|
||||
logger.success(m18n.n('system_upgraded'))
|
||||
operation_logger.success()
|
||||
|
||||
|
||||
def tools_diagnosis(auth, private=False):
|
||||
def tools_diagnosis(private=False):
|
||||
"""
|
||||
Return global info about current yunohost instance to help debugging
|
||||
|
||||
|
@ -765,7 +808,7 @@ def tools_diagnosis(auth, private=False):
|
|||
diagnosis['private']['public_ip']['IPv6'] = get_public_ip(6)
|
||||
|
||||
# Domains
|
||||
diagnosis['private']['domains'] = domain_list(auth)['domains']
|
||||
diagnosis['private']['domains'] = domain_list()['domains']
|
||||
|
||||
diagnosis['private']['regen_conf'] = regen_conf(with_diff=True, dry_run=True)
|
||||
|
||||
|
@ -1089,18 +1132,21 @@ def tools_migrations_state():
|
|||
return read_json(MIGRATIONS_STATE_PATH)
|
||||
|
||||
|
||||
def tools_shell(auth, command=None):
|
||||
def tools_shell(command=None):
|
||||
"""
|
||||
Launch an (i)python shell in the YunoHost context.
|
||||
|
||||
This is entirely aim for development.
|
||||
"""
|
||||
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
if command:
|
||||
exec(command)
|
||||
return
|
||||
|
||||
logger.warn("The \033[1;34mauth\033[0m is available in this context")
|
||||
logger.warn("The \033[1;34mldap\033[0m interface is available in this context")
|
||||
try:
|
||||
from IPython import embed
|
||||
embed()
|
||||
|
|
|
@ -42,7 +42,7 @@ from yunohost.log import is_unit_operation
|
|||
logger = getActionLogger('yunohost.user')
|
||||
|
||||
|
||||
def user_list(auth, fields=None):
|
||||
def user_list(fields=None):
|
||||
"""
|
||||
List users
|
||||
|
||||
|
@ -53,6 +53,8 @@ def user_list(auth, fields=None):
|
|||
fields -- fields to fetch
|
||||
|
||||
"""
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
|
||||
user_attrs = {
|
||||
'uid': 'username',
|
||||
'cn': 'fullname',
|
||||
|
@ -76,7 +78,8 @@ def user_list(auth, fields=None):
|
|||
else:
|
||||
attrs = ['uid', 'cn', 'mail', 'mailuserquota', 'loginShell']
|
||||
|
||||
result = auth.search('ou=users,dc=yunohost,dc=org',
|
||||
ldap = _get_ldap_interface()
|
||||
result = ldap.search('ou=users,dc=yunohost,dc=org',
|
||||
'(&(objectclass=person)(!(uid=root))(!(uid=nobody)))',
|
||||
attrs)
|
||||
|
||||
|
@ -99,7 +102,7 @@ def user_list(auth, fields=None):
|
|||
|
||||
|
||||
@is_unit_operation([('username', 'user')])
|
||||
def user_create(operation_logger, auth, username, firstname, lastname, mail, password,
|
||||
def user_create(operation_logger, username, firstname, lastname, mail, password,
|
||||
mailbox_quota="0"):
|
||||
"""
|
||||
Create user
|
||||
|
@ -116,12 +119,15 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas
|
|||
from yunohost.domain import domain_list, _get_maindomain
|
||||
from yunohost.hook import hook_callback
|
||||
from yunohost.utils.password import assert_password_is_strong_enough
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
|
||||
# Ensure sufficiently complex password
|
||||
assert_password_is_strong_enough("user", password)
|
||||
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
# Validate uniqueness of username and mail in LDAP
|
||||
auth.validate_uniqueness({
|
||||
ldap.validate_uniqueness({
|
||||
'uid': username,
|
||||
'mail': mail,
|
||||
'cn': username
|
||||
|
@ -144,7 +150,7 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas
|
|||
raise YunohostError('mail_unavailable')
|
||||
|
||||
# Check that the mail domain exists
|
||||
if mail.split("@")[1] not in domain_list(auth)['domains']:
|
||||
if mail.split("@")[1] not in domain_list()['domains']:
|
||||
raise YunohostError('mail_domain_unknown', domain=mail.split("@")[1])
|
||||
|
||||
operation_logger.start()
|
||||
|
@ -178,7 +184,7 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas
|
|||
}
|
||||
|
||||
# If it is the first user, add some aliases
|
||||
if not auth.search(base='ou=users,dc=yunohost,dc=org', filter='uid=*'):
|
||||
if not ldap.search(base='ou=users,dc=yunohost,dc=org', filter='uid=*'):
|
||||
attr_dict['mail'] = [attr_dict['mail']] + aliases
|
||||
|
||||
# If exists, remove the redirection from the SSO
|
||||
|
@ -198,7 +204,7 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas
|
|||
except IOError as e:
|
||||
raise YunohostError('ssowat_persistent_conf_write_error', error=e.strerror)
|
||||
|
||||
if auth.add('uid=%s,ou=users' % username, attr_dict):
|
||||
if ldap.add('uid=%s,ou=users' % username, attr_dict):
|
||||
# Invalidate passwd to take user creation into account
|
||||
subprocess.call(['nscd', '-i', 'passwd'])
|
||||
|
||||
|
@ -212,9 +218,9 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas
|
|||
exc_info=1)
|
||||
|
||||
# Create group for user and add to group 'all_users'
|
||||
user_group_add(auth, groupname=username, gid=uid, sync_perm=False)
|
||||
user_group_update(auth, groupname=username, add_user=username, force=True, sync_perm=False)
|
||||
user_group_update(auth, groupname='all_users', add_user=username, force=True, sync_perm=True)
|
||||
user_group_add(groupname=username, gid=uid, sync_perm=False)
|
||||
user_group_update(groupname=username, add_user=username, force=True, sync_perm=False)
|
||||
user_group_update(groupname='all_users', add_user=username, force=True, sync_perm=True)
|
||||
|
||||
# TODO: Send a welcome mail to user
|
||||
logger.success(m18n.n('user_created'))
|
||||
|
@ -228,7 +234,7 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas
|
|||
|
||||
|
||||
@is_unit_operation([('username', 'user')])
|
||||
def user_delete(operation_logger, auth, username, purge=False):
|
||||
def user_delete(operation_logger, username, purge=False):
|
||||
"""
|
||||
Delete user
|
||||
|
||||
|
@ -238,28 +244,32 @@ def user_delete(operation_logger, auth, username, purge=False):
|
|||
|
||||
"""
|
||||
from yunohost.hook import hook_callback
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
|
||||
operation_logger.start()
|
||||
if auth.remove('uid=%s,ou=users' % username):
|
||||
|
||||
ldap = _get_ldap_interface()
|
||||
if ldap.remove('uid=%s,ou=users' % username):
|
||||
# Invalidate passwd to take user deletion into account
|
||||
subprocess.call(['nscd', '-i', 'passwd'])
|
||||
|
||||
if purge:
|
||||
subprocess.call(['rm', '-rf', '/home/{0}'.format(username)])
|
||||
subprocess.call(['rm', '-rf', '/var/mail/{0}'.format(username)])
|
||||
else:
|
||||
raise YunohostError('user_deletion_failed')
|
||||
|
||||
user_group_delete(auth, username, force=True, sync_perm=True)
|
||||
user_group_delete(username, force=True, sync_perm=True)
|
||||
|
||||
group_list = auth.search('ou=groups,dc=yunohost,dc=org',
|
||||
group_list = ldap.search('ou=groups,dc=yunohost,dc=org',
|
||||
'(&(objectclass=groupOfNamesYnh)(memberUid=%s))'
|
||||
% username, ['cn'])
|
||||
for group in group_list:
|
||||
user_list = auth.search('ou=groups,dc=yunohost,dc=org',
|
||||
user_list = ldap.search('ou=groups,dc=yunohost,dc=org',
|
||||
'cn=' + group['cn'][0],
|
||||
['memberUid'])[0]
|
||||
user_list['memberUid'].remove(username)
|
||||
if not auth.update('cn=%s,ou=groups' % group['cn'][0], user_list):
|
||||
if not ldap.update('cn=%s,ou=groups' % group['cn'][0], user_list):
|
||||
raise YunohostError('group_update_failed')
|
||||
|
||||
hook_callback('post_user_delete', args=[username, purge])
|
||||
|
@ -267,8 +277,8 @@ def user_delete(operation_logger, auth, username, purge=False):
|
|||
logger.success(m18n.n('user_deleted'))
|
||||
|
||||
|
||||
@is_unit_operation([('username', 'user')], exclude=['auth', 'change_password'])
|
||||
def user_update(operation_logger, auth, username, firstname=None, lastname=None, mail=None,
|
||||
@is_unit_operation([('username', 'user')], exclude=['change_password'])
|
||||
def user_update(operation_logger, username, firstname=None, lastname=None, mail=None,
|
||||
change_password=None, add_mailforward=None, remove_mailforward=None,
|
||||
add_mailalias=None, remove_mailalias=None, mailbox_quota=None):
|
||||
"""
|
||||
|
@ -289,12 +299,14 @@ def user_update(operation_logger, auth, username, firstname=None, lastname=None,
|
|||
from yunohost.domain import domain_list, _get_maindomain
|
||||
from yunohost.app import app_ssowatconf
|
||||
from yunohost.utils.password import assert_password_is_strong_enough
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
|
||||
domains = domain_list(auth)['domains']
|
||||
domains = domain_list()['domains']
|
||||
|
||||
# Populate user informations
|
||||
ldap = _get_ldap_interface()
|
||||
attrs_to_fetch = ['givenName', 'sn', 'mail', 'maildrop']
|
||||
result = auth.search(base='ou=users,dc=yunohost,dc=org', filter='uid=' + username, attrs=attrs_to_fetch)
|
||||
result = ldap.search(base='ou=users,dc=yunohost,dc=org', filter='uid=' + username, attrs=attrs_to_fetch)
|
||||
if not result:
|
||||
raise YunohostError('user_unknown', user=username)
|
||||
user = result[0]
|
||||
|
@ -326,7 +338,7 @@ def user_update(operation_logger, auth, username, firstname=None, lastname=None,
|
|||
'webmaster@' + main_domain,
|
||||
'postmaster@' + main_domain,
|
||||
]
|
||||
auth.validate_uniqueness({'mail': mail})
|
||||
ldap.validate_uniqueness({'mail': mail})
|
||||
if mail[mail.find('@') + 1:] not in domains:
|
||||
raise YunohostError('mail_domain_unknown', domain=mail[mail.find('@') + 1:])
|
||||
if mail in aliases:
|
||||
|
@ -339,7 +351,7 @@ def user_update(operation_logger, auth, username, firstname=None, lastname=None,
|
|||
if not isinstance(add_mailalias, list):
|
||||
add_mailalias = [add_mailalias]
|
||||
for mail in add_mailalias:
|
||||
auth.validate_uniqueness({'mail': mail})
|
||||
ldap.validate_uniqueness({'mail': mail})
|
||||
if mail[mail.find('@') + 1:] not in domains:
|
||||
raise YunohostError('mail_domain_unknown', domain=mail[mail.find('@') + 1:])
|
||||
user['mail'].append(mail)
|
||||
|
@ -379,15 +391,15 @@ def user_update(operation_logger, auth, username, firstname=None, lastname=None,
|
|||
|
||||
operation_logger.start()
|
||||
|
||||
if auth.update('uid=%s,ou=users' % username, new_attr_dict):
|
||||
if ldap.update('uid=%s,ou=users' % username, new_attr_dict):
|
||||
logger.success(m18n.n('user_updated'))
|
||||
app_ssowatconf(auth)
|
||||
return user_info(auth, username)
|
||||
app_ssowatconf()
|
||||
return user_info(username)
|
||||
else:
|
||||
raise YunohostError('user_update_failed')
|
||||
|
||||
|
||||
def user_info(auth, username):
|
||||
def user_info(username):
|
||||
"""
|
||||
Get user informations
|
||||
|
||||
|
@ -395,16 +407,20 @@ def user_info(auth, username):
|
|||
username -- Username or mail to get informations
|
||||
|
||||
"""
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
user_attrs = [
|
||||
'cn', 'mail', 'uid', 'maildrop', 'givenName', 'sn', 'mailuserquota'
|
||||
]
|
||||
|
||||
if len(username.split('@')) is 2:
|
||||
if len(username.split('@')) == 2:
|
||||
filter = 'mail=' + username
|
||||
else:
|
||||
filter = 'uid=' + username
|
||||
|
||||
result = auth.search('ou=users,dc=yunohost,dc=org', filter, user_attrs)
|
||||
result = ldap.search('ou=users,dc=yunohost,dc=org', filter, user_attrs)
|
||||
|
||||
if result:
|
||||
user = result[0]
|
||||
|
@ -437,7 +453,7 @@ def user_info(auth, username):
|
|||
|
||||
if service_status("dovecot")["status"] != "running":
|
||||
logger.warning(m18n.n('mailbox_used_space_dovecot_down'))
|
||||
elif not user_permission_list(auth, app="mail", permission="main", username=username)['permissions']:
|
||||
elif not user_permission_list(app="mail", permission="main", username=username)['permissions']:
|
||||
logger.warning(m18n.n('mailbox_disabled', user=username))
|
||||
else:
|
||||
cmd = 'doveadm -f flow quota get -u %s' % user['uid'][0]
|
||||
|
@ -473,7 +489,7 @@ def user_info(auth, username):
|
|||
#
|
||||
# Group subcategory
|
||||
#
|
||||
def user_group_list(auth, fields=None):
|
||||
def user_group_list(fields=None):
|
||||
"""
|
||||
List users
|
||||
|
||||
|
@ -484,6 +500,8 @@ def user_group_list(auth, fields=None):
|
|||
fields -- fields to fetch
|
||||
|
||||
"""
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
group_attr = {
|
||||
'cn': 'groupname',
|
||||
'member': 'members',
|
||||
|
@ -502,7 +520,7 @@ def user_group_list(auth, fields=None):
|
|||
else:
|
||||
attrs = ['cn', 'member']
|
||||
|
||||
result = auth.search('ou=groups,dc=yunohost,dc=org',
|
||||
result = ldap.search('ou=groups,dc=yunohost,dc=org',
|
||||
'(objectclass=groupOfNamesYnh)',
|
||||
attrs)
|
||||
|
||||
|
@ -516,7 +534,7 @@ def user_group_list(auth, fields=None):
|
|||
if attr == "member":
|
||||
entry[group_attr[attr]] = []
|
||||
for v in values:
|
||||
entry[group_attr[attr]].append(v.split("=")[1].split(",")[0])
|
||||
entry[group_attr[attr]].append(v.split("=")[1].split(",")[0])
|
||||
elif attr == "permission":
|
||||
entry[group_attr[attr]] = {}
|
||||
for v in values:
|
||||
|
@ -536,7 +554,7 @@ def user_group_list(auth, fields=None):
|
|||
|
||||
|
||||
@is_unit_operation([('groupname', 'user')])
|
||||
def user_group_add(operation_logger, auth, groupname, gid=None, sync_perm=True):
|
||||
def user_group_add(operation_logger, groupname, gid=None, sync_perm=True):
|
||||
"""
|
||||
Create group
|
||||
|
||||
|
@ -545,11 +563,14 @@ def user_group_add(operation_logger, auth, groupname, gid=None, sync_perm=True):
|
|||
|
||||
"""
|
||||
from yunohost.permission import permission_sync_to_user
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
|
||||
operation_logger.start()
|
||||
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
# Validate uniqueness of groupname in LDAP
|
||||
conflict = auth.get_conflict({
|
||||
conflict = ldap.get_conflict({
|
||||
'cn': groupname
|
||||
}, base_dn='ou=groups,dc=yunohost,dc=org')
|
||||
if conflict:
|
||||
|
@ -575,17 +596,17 @@ def user_group_add(operation_logger, auth, groupname, gid=None, sync_perm=True):
|
|||
'gidNumber': gid,
|
||||
}
|
||||
|
||||
if auth.add('cn=%s,ou=groups' % groupname, attr_dict):
|
||||
if ldap.add('cn=%s,ou=groups' % groupname, attr_dict):
|
||||
logger.success(m18n.n('group_created', group=groupname))
|
||||
if sync_perm:
|
||||
permission_sync_to_user(auth)
|
||||
permission_sync_to_user()
|
||||
return {'name': groupname}
|
||||
|
||||
raise YunohostError('group_creation_failed', group=groupname)
|
||||
|
||||
|
||||
@is_unit_operation([('groupname', 'user')])
|
||||
def user_group_delete(operation_logger, auth, groupname, force=False, sync_perm=True):
|
||||
def user_group_delete(operation_logger, groupname, force=False, sync_perm=True):
|
||||
"""
|
||||
Delete user
|
||||
|
||||
|
@ -594,22 +615,24 @@ def user_group_delete(operation_logger, auth, groupname, force=False, sync_perm=
|
|||
|
||||
"""
|
||||
from yunohost.permission import permission_sync_to_user
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
|
||||
forbidden_groups = ["all_users", "admins"] + user_list(auth, fields=['uid'])['users'].keys()
|
||||
forbidden_groups = ["all_users", "admins"] + user_list(fields=['uid'])['users'].keys()
|
||||
if not force and groupname in forbidden_groups:
|
||||
raise YunohostError('group_deletion_not_allowed', group=groupname)
|
||||
|
||||
operation_logger.start()
|
||||
if not auth.remove('cn=%s,ou=groups' % groupname):
|
||||
ldap = _get_ldap_interface()
|
||||
if not ldap.remove('cn=%s,ou=groups' % groupname):
|
||||
raise YunohostError('group_deletion_failed', group=groupname)
|
||||
|
||||
logger.success(m18n.n('group_deleted', group=groupname))
|
||||
if sync_perm:
|
||||
permission_sync_to_user(auth)
|
||||
permission_sync_to_user()
|
||||
|
||||
|
||||
@is_unit_operation([('groupname', 'user')])
|
||||
def user_group_update(operation_logger, auth, groupname, add_user=None, remove_user=None, force=False, sync_perm=True):
|
||||
def user_group_update(operation_logger, groupname, add_user=None, remove_user=None, force=False, sync_perm=True):
|
||||
"""
|
||||
Update user informations
|
||||
|
||||
|
@ -621,13 +644,16 @@ def user_group_update(operation_logger, auth, groupname, add_user=None, remove_u
|
|||
"""
|
||||
|
||||
from yunohost.permission import permission_sync_to_user
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
|
||||
if (groupname == 'all_users' or groupname == 'admins') and not force:
|
||||
raise YunohostError('edit_group_not_allowed', group=groupname)
|
||||
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
# Populate group informations
|
||||
attrs_to_fetch = ['member']
|
||||
result = auth.search(base='ou=groups,dc=yunohost,dc=org',
|
||||
result = ldap.search(base='ou=groups,dc=yunohost,dc=org',
|
||||
filter='cn=' + groupname, attrs=attrs_to_fetch)
|
||||
if not result:
|
||||
raise YunohostError('group_unknown', group=groupname)
|
||||
|
@ -639,7 +665,7 @@ def user_group_update(operation_logger, auth, groupname, add_user=None, remove_u
|
|||
else:
|
||||
group['member'] = []
|
||||
|
||||
existing_users = user_list(auth, fields=['uid'])['users'].keys()
|
||||
existing_users = user_list(fields=['uid'])['users'].keys()
|
||||
|
||||
if add_user:
|
||||
if not isinstance(add_user, list):
|
||||
|
@ -683,16 +709,16 @@ def user_group_update(operation_logger, auth, groupname, add_user=None, remove_u
|
|||
operation_logger.start()
|
||||
|
||||
if new_group_list['member'] != set(group['member']):
|
||||
if not auth.update('cn=%s,ou=groups' % groupname, new_group_list):
|
||||
if not ldap.update('cn=%s,ou=groups' % groupname, new_group_list):
|
||||
raise YunohostError('group_update_failed', group=groupname)
|
||||
|
||||
logger.success(m18n.n('group_updated', group=groupname))
|
||||
if sync_perm:
|
||||
permission_sync_to_user(auth)
|
||||
return user_group_info(auth, groupname)
|
||||
permission_sync_to_user()
|
||||
return user_group_info(groupname)
|
||||
|
||||
|
||||
def user_group_info(auth, groupname):
|
||||
def user_group_info(groupname):
|
||||
"""
|
||||
Get user informations
|
||||
|
||||
|
@ -700,10 +726,14 @@ def user_group_info(auth, groupname):
|
|||
groupname -- Groupname to get informations
|
||||
|
||||
"""
|
||||
|
||||
from yunohost.utils.ldap import _get_ldap_interface
|
||||
ldap = _get_ldap_interface()
|
||||
|
||||
group_attrs = [
|
||||
'cn', 'member', 'permission'
|
||||
]
|
||||
result = auth.search('ou=groups,dc=yunohost,dc=org', "cn=" + groupname, group_attrs)
|
||||
result = ldap.search('ou=groups,dc=yunohost,dc=org', "cn=" + groupname, group_attrs)
|
||||
|
||||
if not result:
|
||||
raise YunohostError('group_unknown', group=groupname)
|
||||
|
@ -723,33 +753,33 @@ def user_group_info(auth, groupname):
|
|||
# Permission subcategory
|
||||
#
|
||||
|
||||
def user_permission_list(auth, app=None, permission=None, username=None, group=None, sync_perm=True):
|
||||
def user_permission_list(app=None, permission=None, username=None, group=None, sync_perm=True):
|
||||
import yunohost.permission
|
||||
return yunohost.permission.user_permission_list(auth, app, permission, username, group)
|
||||
return yunohost.permission.user_permission_list(app, permission, username, group)
|
||||
|
||||
|
||||
@is_unit_operation([('app', 'user')])
|
||||
def user_permission_add(operation_logger, auth, app, permission="main", username=None, group=None, sync_perm=True):
|
||||
def user_permission_add(operation_logger, app, permission="main", username=None, group=None, sync_perm=True):
|
||||
import yunohost.permission
|
||||
return yunohost.permission.user_permission_update(operation_logger, auth, app, permission=permission,
|
||||
return yunohost.permission.user_permission_update(operation_logger, app, permission=permission,
|
||||
add_username=username, add_group=group,
|
||||
del_username=None, del_group=None,
|
||||
sync_perm=sync_perm)
|
||||
|
||||
|
||||
@is_unit_operation([('app', 'user')])
|
||||
def user_permission_remove(operation_logger, auth, app, permission="main", username=None, group=None, sync_perm=True):
|
||||
def user_permission_remove(operation_logger, app, permission="main", username=None, group=None, sync_perm=True):
|
||||
import yunohost.permission
|
||||
return yunohost.permission.user_permission_update(operation_logger, auth, app, permission=permission,
|
||||
return yunohost.permission.user_permission_update(operation_logger, app, permission=permission,
|
||||
add_username=None, add_group=None,
|
||||
del_username=username, del_group=group,
|
||||
sync_perm=sync_perm)
|
||||
|
||||
|
||||
@is_unit_operation([('app', 'user')])
|
||||
def user_permission_clear(operation_logger, auth, app, permission=None, sync_perm=True):
|
||||
def user_permission_clear(operation_logger, app, permission=None, sync_perm=True):
|
||||
import yunohost.permission
|
||||
return yunohost.permission.user_permission_clear(operation_logger, auth, app, permission,
|
||||
return yunohost.permission.user_permission_clear(operation_logger, app, permission,
|
||||
sync_perm=sync_perm)
|
||||
|
||||
|
||||
|
@ -759,24 +789,24 @@ def user_permission_clear(operation_logger, auth, app, permission=None, sync_per
|
|||
import yunohost.ssh
|
||||
|
||||
|
||||
def user_ssh_allow(auth, username):
|
||||
return yunohost.ssh.user_ssh_allow(auth, username)
|
||||
def user_ssh_allow(username):
|
||||
return yunohost.ssh.user_ssh_allow(username)
|
||||
|
||||
|
||||
def user_ssh_disallow(auth, username):
|
||||
return yunohost.ssh.user_ssh_disallow(auth, username)
|
||||
def user_ssh_disallow(username):
|
||||
return yunohost.ssh.user_ssh_disallow(username)
|
||||
|
||||
|
||||
def user_ssh_list_keys(auth, username):
|
||||
return yunohost.ssh.user_ssh_list_keys(auth, username)
|
||||
def user_ssh_list_keys(username):
|
||||
return yunohost.ssh.user_ssh_list_keys(username)
|
||||
|
||||
|
||||
def user_ssh_add_key(auth, username, key, comment):
|
||||
return yunohost.ssh.user_ssh_add_key(auth, username, key, comment)
|
||||
def user_ssh_add_key(username, key, comment):
|
||||
return yunohost.ssh.user_ssh_add_key(username, key, comment)
|
||||
|
||||
|
||||
def user_ssh_remove_key(auth, username, key):
|
||||
return yunohost.ssh.user_ssh_remove_key(auth, username, key)
|
||||
def user_ssh_remove_key(username, key):
|
||||
return yunohost.ssh.user_ssh_remove_key(username, key)
|
||||
|
||||
#
|
||||
# End SSH subcategory
|
||||
|
|
52
src/yunohost/utils/ldap.py
Normal file
52
src/yunohost/utils/ldap.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
""" License
|
||||
|
||||
Copyright (C) 2019 YunoHost
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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
|
||||
along with this program; if not, see http://www.gnu.org/licenses
|
||||
|
||||
"""
|
||||
|
||||
import atexit
|
||||
from moulinette.core import init_authenticator
|
||||
|
||||
# We use a global variable to do some caching
|
||||
# to avoid re-authenticating in case we call _get_ldap_authenticator multiple times
|
||||
_ldap_interface = None
|
||||
|
||||
def _get_ldap_interface():
|
||||
|
||||
global _ldap_interface
|
||||
|
||||
if _ldap_interface is None:
|
||||
# Instantiate LDAP Authenticator
|
||||
AUTH_IDENTIFIER = ('ldap', 'as-root')
|
||||
AUTH_PARAMETERS = {'uri': 'ldapi://%2Fvar%2Frun%2Fslapd%2Fldapi',
|
||||
'base_dn': 'dc=yunohost,dc=org',
|
||||
'user_rdn': 'gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth'}
|
||||
_ldap_interface = init_authenticator(AUTH_IDENTIFIER, AUTH_PARAMETERS)
|
||||
|
||||
return _ldap_interface
|
||||
|
||||
# Add this to properly close / delete the ldap interface / authenticator
|
||||
# when Python exits ...
|
||||
# Otherwise there's a risk that some funky error appears at the very end
|
||||
# of the command due to Python stuff being unallocated in wrong order.
|
||||
def _destroy_ldap_interface():
|
||||
global _ldap_interface
|
||||
if _ldap_interface is not None:
|
||||
del _ldap_interface
|
||||
|
||||
atexit.register(_destroy_ldap_interface)
|
|
@ -481,3 +481,48 @@ def dpkg_is_broken():
|
|||
return False
|
||||
return any(re.match("^[0-9]+$", f)
|
||||
for f in os.listdir("/var/lib/dpkg/updates/"))
|
||||
|
||||
def dpkg_lock_available():
|
||||
return os.system("lsof /var/lib/dpkg/lock >/dev/null") != 0
|
||||
|
||||
def _list_upgradable_apt_packages():
|
||||
|
||||
from moulinette.utils.process import check_output
|
||||
|
||||
# List upgradable packages
|
||||
# LC_ALL=C is here to make sure the results are in english
|
||||
upgradable_raw = check_output("LC_ALL=C apt list --upgradable")
|
||||
|
||||
# Dirty parsing of the output
|
||||
upgradable_raw = [l.strip() for l in upgradable_raw.split("\n") if l.strip()]
|
||||
for line in upgradable_raw:
|
||||
|
||||
# Remove stupid warning and verbose messages >.>
|
||||
if "apt does not have a stable CLI interface" in line or "Listing..." in line:
|
||||
continue
|
||||
|
||||
# line should look like :
|
||||
# yunohost/stable 3.5.0.2+201903211853 all [upgradable from: 3.4.2.4+201903080053]
|
||||
line = line.split()
|
||||
if len(line) != 6:
|
||||
logger.warning("Failed to parse this line : %s" % ' '.join(line))
|
||||
continue
|
||||
|
||||
yield {
|
||||
"name": line[0].split("/")[0],
|
||||
"new_version": line[1],
|
||||
"current_version": line[5].strip("]"),
|
||||
}
|
||||
|
||||
|
||||
def _dump_sources_list():
|
||||
|
||||
from glob import glob
|
||||
|
||||
filenames = glob("/etc/apt/sources.list") + glob("/etc/apt/sources.list.d/*")
|
||||
for filename in filenames:
|
||||
with open(filename, "r") as f:
|
||||
for line in f.readlines():
|
||||
if line.startswith("#") or not line.strip():
|
||||
continue
|
||||
yield filename.replace("/etc/apt/", "") + ":" + line.strip()
|
||||
|
|
Loading…
Add table
Reference in a new issue