blob: f5df68dfe52fd6c4907dddee1c93f9c00f71156a [file] [log] [blame]
#
# Copyright 2017 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
from vts.runners.host import const
_PERMISSION_GROUPS = 3 # 3 permission groups: owner, group, all users
_READ_PERMISSION = 4
_WRITE_PERMISSION = 2
_EXECUTE_PERMISSION = 1
def Exists(filepath, shell):
"""Determines if a file exists.
Args:
filepath: string, path to file
shell: an instance of the VTS shell
Returns:
True if the file exists, False otherwise"""
cmd = "ls %s" % filepath
results = shell.Execute(cmd)
if results[const.EXIT_CODE][0] != 0:
return False
out_str = str(results[const.STDOUT])
return out_str.find(filepath) == 0
def ReadFileContent(filepath, shell):
"""Read the content of a file and perform assertions.
Args:
filepath: string, path to file
shell: an instance of the VTS shell
Returns:
string, content of file
Raises:
IOError if the file does not exist."""
cmd = "cat %s" % filepath
results = shell.Execute(cmd)
logging.info("%s: Shell command '%s' results: %s", filepath, cmd,
results)
# checks the exit code
if results[const.EXIT_CODE][0] != 0:
raise IOError(results[const.STDERR][0])
return results[const.STDOUT][0]
def GetPermission(path, shell):
"""Read the file permission bits of a path.
Args:
filepath: string, path to a file or directory
shell: an instance of the VTS shell
Returns:
String, octal permission bits for the path
Raises:
IOError if the path does not exist or has invalid permission bits.
"""
cmd = "stat -c %%a %s" % path
results = shell.Execute(cmd)
logging.info("%s: Shell command '%s' results: %s", path, cmd,
results)
# checks the exit code
if results[const.EXIT_CODE][0] != 0:
raise IOError(results[const.STDERR][0])
accessBits = results[const.STDOUT][0].strip()
if len(accessBits) != 3:
raise IOError("%s: Wrong number of access bits (%s)" %
(path, accessBits))
return accessBits
def _HasPermission(permission_bits, groupIndex, permission):
"""Determines if the permission bits grant a permission to a group.
Args:
permission_bits: string, the octal permissions string (e.g. 741)
groupIndex: int, the index of the group into the permissions string.
(e.g. 0 is owner group). If set to -1, then all groups are
checked.
permission: the value of the permission.
Returns:
True if the group(s) has read permission.
Raises:
ValueError if the group or permission bits are invalid"""
if groupIndex >= _PERMISSION_GROUPS:
raise ValueError("Invalid group: %s" % str(groupIndex))
if len(permission_bits) != _PERMISSION_GROUPS:
raise ValueError("Invalid permission bits: %s" % str(permission_bits))
# Define the start/end group index
start = groupIndex
end = groupIndex + 1
if groupIndex < 0:
start = 0
end = _PERMISSION_GROUPS
for i in range(start, end):
perm = int(permission_bits[i]) # throws ValueError if not an integer
if perm > 7:
raise ValueError("Invalid permission bit: %s" % str(perm))
if perm & permission == 0:
# Return false if any group lacks the permission
return False
# Return true if no group lacks the permission
return True
def IsReadable(permission_bits):
"""Determines if the permission bits grant read permission to any group.
Args:
permission_bits: string, the octal permissions string (e.g. 741)
Returns:
True if any group has read permission.
Raises:
ValueError if the group or permission bits are invalid"""
return any([_HasPermission(permission_bits, i, _READ_PERMISSION) for i in
range(_PERMISSION_GROUPS)])
def IsWritable(permission_bits):
"""Determines if the permission bits grant write permission to any group.
Args:
permission_bits: string, the octal permissions string (e.g. 741)
Returns:
True if any group has write permission.
Raises:
ValueError if the group or permission bits are invalid"""
return any([_HasPermission(permission_bits, i, _WRITE_PERMISSION) for i in
range(_PERMISSION_GROUPS)])
def IsExecutable(permission_bits):
"""Determines if the permission bits grant execute permission to any group.
Args:
permission_bits: string, the octal permissions string (e.g. 741)
Returns:
True if any group has execute permission.
Raises:
ValueError if the group or permission bits are invalid"""
return any([_HasPermission(permission_bits, i, _EXECUTE_PERMISSION) for i in
range(_PERMISSION_GROUPS)])
def IsReadOnly(permission_bits):
"""Determines if the permission bits grant read-only permission.
Read-only permission is granted if some group has read access but no group
has write access.
Args:
permission_bits: string, the octal permissions string (e.g. 741)
Returns:
True if any group has read permission, none have write.
Raises:
ValueError if the group or permission bits are invalid"""
return IsReadable(permission_bits) and not IsWritable(permission_bits)
def IsWriteOnly(permission_bits):
"""Determines if the permission bits grant write-only permission.
Write-only permission is granted if some group has write access but no group
has read access.
Args:
permission_bits: string, the octal permissions string (e.g. 741)
Returns:
True if any group has write permission, none have read.
Raises:
ValueError if the group or permission bits are invalid"""
return IsWritable(permission_bits) and not IsReadable(permission_bits)
def IsReadWrite(permission_bits):
"""Determines if the permission bits grant read/write permissions.
Read-write permission is granted if some group has read access and some has
write access. The groups may be different.
Args:
permission_bits: string, the octal permissions string (e.g. 741)
Returns:
True if read and write permissions are granted to any group(s).
Raises:
ValueError if the group or permission bits are invalid"""
return IsReadable(permission_bits) and IsWritable(permission_bits)