1#
2# Copyright 2017 - The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16_PERMISSION_GROUPS = 3  # 3 permission groups: owner, group, all users
17_READ_PERMISSION = 4
18_WRITE_PERMISSION = 2
19_EXECUTE_PERMISSION = 1
20
21
22def _HasPermission(permission_bits, groupIndex, permission):
23    """Determines if the permission bits grant a permission to a group.
24
25    Args:
26        permission_bits: string, the octal permissions string (e.g. 741)
27        groupIndex: int, the index of the group into the permissions string.
28                    (e.g. 0 is owner group). If set to -1, then all groups are
29                    checked.
30        permission: the value of the permission.
31
32    Returns:
33        True if the group(s) has read permission.
34
35    Raises:
36        ValueError if the group or permission bits are invalid
37    """
38    if groupIndex >= _PERMISSION_GROUPS:
39        raise ValueError("Invalid group: %s" % str(groupIndex))
40
41    if len(permission_bits) != _PERMISSION_GROUPS:
42        raise ValueError("Invalid permission bits: %s" % str(permission_bits))
43
44    # Define the start/end group index
45    start = groupIndex
46    end = groupIndex + 1
47    if groupIndex < 0:
48        start = 0
49        end = _PERMISSION_GROUPS
50
51    for i in range(start, end):
52        perm = int(permission_bits[i])  # throws ValueError if not an integer
53        if perm > 7:
54            raise ValueError("Invalid permission bit: %s" % str(perm))
55        if perm & permission == 0:
56            # Return false if any group lacks the permission
57            return False
58    # Return true if no group lacks the permission
59    return True
60
61
62def IsReadable(permission_bits):
63    """Determines if the permission bits grant read permission to any group.
64
65    Args:
66        permission_bits: string, the octal permissions string (e.g. 741)
67
68    Returns:
69        True if any group has read permission.
70
71    Raises:
72        ValueError if the group or permission bits are invalid
73    """
74    return any([
75        _HasPermission(permission_bits, i, _READ_PERMISSION)
76        for i in range(_PERMISSION_GROUPS)
77    ])
78
79
80def IsWritable(permission_bits):
81    """Determines if the permission bits grant write permission to any group.
82
83    Args:
84        permission_bits: string, the octal permissions string (e.g. 741)
85
86    Returns:
87        True if any group has write permission.
88
89    Raises:
90        ValueError if the group or permission bits are invalid
91    """
92    return any([
93        _HasPermission(permission_bits, i, _WRITE_PERMISSION)
94        for i in range(_PERMISSION_GROUPS)
95    ])
96
97
98def IsExecutable(permission_bits):
99    """Determines if the permission bits grant execute permission to any group.
100
101    Args:
102        permission_bits: string, the octal permissions string (e.g. 741)
103
104    Returns:
105        True if any group has execute permission.
106
107    Raises:
108        ValueError if the group or permission bits are invalid
109    """
110    return any([
111        _HasPermission(permission_bits, i, _EXECUTE_PERMISSION)
112        for i in range(_PERMISSION_GROUPS)
113    ])
114
115
116def IsReadOnly(permission_bits):
117    """Determines if the permission bits grant read-only permission.
118
119    Read-only permission is granted if some group has read access but no group
120    has write access.
121
122    Args:
123        permission_bits: string, the octal permissions string (e.g. 741)
124
125    Returns:
126        True if any group has read permission, none have write.
127
128    Raises:
129        ValueError if the group or permission bits are invalid
130    """
131    return IsReadable(permission_bits) and not IsWritable(permission_bits)
132
133
134def IsWriteOnly(permission_bits):
135    """Determines if the permission bits grant write-only permission.
136
137    Write-only permission is granted if some group has write access but no group
138    has read access.
139
140    Args:
141        permission_bits: string, the octal permissions string (e.g. 741)
142
143    Returns:
144        True if any group has write permission, none have read.
145
146    Raises:
147        ValueError if the group or permission bits are invalid
148    """
149    return IsWritable(permission_bits) and not IsReadable(permission_bits)
150
151
152def IsReadWrite(permission_bits):
153    """Determines if the permission bits grant read/write permissions.
154
155    Read-write permission is granted if some group has read access and some has
156    write access. The groups may be different.
157
158    Args:
159        permission_bits: string, the octal permissions string (e.g. 741)
160
161    Returns:
162        True if read and write permissions are granted to any group(s).
163
164    Raises:
165        ValueError if the group or permission bits are invalid
166    """
167    return IsReadable(permission_bits) and IsWritable(permission_bits)
168