Skip to content

Commit f5d2d20

Browse files
authored
Merge pull request #36 from Quentame/storage/fix-dsm-5
Fix : DSM 5 can't fetch Storage data Add DSM 5 tests + fix DSM 5 issues
2 parents 1569715 + 4096d78 commit f5d2d20

File tree

8 files changed

+700
-283
lines changed

8 files changed

+700
-283
lines changed

synology_dsm/api/storage/storage.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,7 @@ def _get_disk(self, disk_id):
144144
def _get_disks_for_volume(self, volume_id):
145145
"""Returns a list of disk for a specific volume."""
146146
disks = []
147-
pools = self._data.get("storagePools", [])
148-
for pool in pools:
147+
for pool in self.storage_pools:
149148
if pool["deploy_path"] == volume_id:
150149
for disk_id in pool["disks"]:
151150
disks.append(self._get_disk(disk_id))

synology_dsm/synology_dsm.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ class SynologyDSM(object):
2828
API_INFO = "SYNO.API.Info"
2929
API_AUTH = "SYNO.API.Auth"
3030

31+
DSM_5_WEIRD_URL_API = [
32+
SynoStorage.API_KEY,
33+
]
34+
3135
def __init__(
3236
self,
3337
dsm_ip,
@@ -74,16 +78,22 @@ def _debuglog(self, message):
7478
if self._debugmode:
7579
print("DEBUG: " + message)
7680

77-
def _build_url(self, api):
78-
if (
79-
api == SynoStorage.API_KEY
81+
def _is_weird_api_url(self, api):
82+
"""Returns True if the API URL is not common (nas_base_url/webapi/path?params) [Only handles DSM 5 for now]."""
83+
return (
84+
api in self.DSM_5_WEIRD_URL_API
8085
and self._information
8186
and self._information.version
8287
and int(self._information.version) < 7321 # < DSM 6
83-
):
84-
return (
85-
"%s/webman/modules/StorageManager/storagehandler.cgi?" % self._base_url
86-
)
88+
)
89+
90+
def _build_url(self, api):
91+
if self._is_weird_api_url(api):
92+
if api == SynoStorage.API_KEY:
93+
return (
94+
"%s/webman/modules/StorageManager/storagehandler.cgi?"
95+
% self._base_url
96+
)
8797

8898
return "%s/webapi/%s?" % (self._base_url, self.apis[api]["path"])
8999

@@ -176,15 +186,18 @@ def _request(
176186
if not self._session_id and api not in [self.API_AUTH, self.API_INFO]:
177187
self.login()
178188

179-
# Check if API is available
180-
if not self.apis.get(api):
181-
raise SynologyDSMAPINotExistsException(api)
182-
183189
# Build request params
184190
if not params:
185191
params = {}
186192
params["api"] = api
187-
params["version"] = self.apis[api]["maxVersion"]
193+
params["version"] = 1
194+
195+
if not self._is_weird_api_url(api):
196+
# Check if API is available
197+
if not self.apis.get(api):
198+
raise SynologyDSMAPINotExistsException(api)
199+
params["version"] = self.apis[api]["maxVersion"]
200+
188201
params["method"] = method
189202

190203
if api == SynoStorage.API_KEY:

tests/__init__.py

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,37 @@
2525
DSM_6_CORE_UTILIZATION,
2626
DSM_6_STORAGE_STORAGE,
2727
)
28+
from .api_data.dsm_5 import (
29+
DSM_5_API_INFO,
30+
DSM_5_AUTH_LOGIN,
31+
DSM_5_AUTH_LOGIN_2SA,
32+
DSM_5_AUTH_LOGIN_2SA_OTP,
33+
DSM_5_DSM_INFORMATION,
34+
DSM_5_CORE_UTILIZATION,
35+
DSM_5_STORAGE_STORAGE,
36+
)
37+
38+
API_SWITCHER = {
39+
5: {
40+
"API_INFO": DSM_5_API_INFO,
41+
"AUTH_LOGIN": DSM_5_AUTH_LOGIN,
42+
"AUTH_LOGIN_2SA": DSM_5_AUTH_LOGIN_2SA,
43+
"AUTH_LOGIN_2SA_OTP": DSM_5_AUTH_LOGIN_2SA_OTP,
44+
"DSM_INFORMATION": DSM_5_DSM_INFORMATION,
45+
"CORE_UTILIZATION": DSM_5_CORE_UTILIZATION,
46+
"STORAGE_STORAGE": DSM_5_STORAGE_STORAGE,
47+
},
48+
6: {
49+
"API_INFO": DSM_6_API_INFO,
50+
"AUTH_LOGIN": DSM_6_AUTH_LOGIN,
51+
"AUTH_LOGIN_2SA": DSM_6_AUTH_LOGIN_2SA,
52+
"AUTH_LOGIN_2SA_OTP": DSM_6_AUTH_LOGIN_2SA_OTP,
53+
"DSM_INFORMATION": DSM_6_DSM_INFORMATION,
54+
"CORE_UTILIZATION": DSM_6_CORE_UTILIZATION,
55+
"STORAGE_STORAGE": DSM_6_STORAGE_STORAGE,
56+
},
57+
}
58+
2859

2960
if six.PY2:
3061
from future.moves.urllib.parse import urlencode
@@ -43,7 +74,7 @@
4374
class SynologyDSMMock(SynologyDSM):
4475
"""Mocked SynologyDSM."""
4576

46-
API_URI = "entry.cgi"
77+
API_URI = "api="
4778

4879
def __init__(
4980
self,
@@ -66,8 +97,11 @@ def __init__(
6697
debugmode,
6798
)
6899

100+
self.dsm_version = 6
101+
69102
def _execute_request(self, method, url, **kwargs):
70103
url += urlencode(kwargs["params"])
104+
71105
if "no_internet" in url:
72106
raise SynologyDSMRequestException(
73107
ConnError(
@@ -98,38 +132,38 @@ def _execute_request(self, method, url, **kwargs):
98132
raise SynologyDSMRequestException(RequestException("Bad request"))
99133

100134
if self.API_INFO in url:
101-
return DSM_6_API_INFO
135+
return API_SWITCHER[self.dsm_version]["API_INFO"]
102136

103137
if self.API_AUTH in url:
104138
if VALID_USER_2SA in url and VALID_PASSWORD in url:
105139
if "otp_code" not in url and "device_id" not in url:
106-
return DSM_6_AUTH_LOGIN_2SA
140+
return API_SWITCHER[self.dsm_version]["AUTH_LOGIN_2SA"]
107141

108142
if "device_id" in url and DEVICE_TOKEN in url:
109-
return DSM_6_AUTH_LOGIN
143+
return API_SWITCHER[self.dsm_version]["AUTH_LOGIN"]
110144

111145
if "otp_code" in url:
112146
if VALID_OTP in url:
113-
return DSM_6_AUTH_LOGIN_2SA_OTP
147+
return API_SWITCHER[self.dsm_version]["AUTH_LOGIN_2SA_OTP"]
114148
return ERROR_AUTH_OTP_AUTHENTICATE_FAILED
115149

116150
if VALID_USER in url and VALID_PASSWORD in url:
117-
return DSM_6_AUTH_LOGIN
151+
return API_SWITCHER[self.dsm_version]["AUTH_LOGIN"]
118152

119153
return ERROR_AUTH_INVALID_CREDENTIALS
120154

121155
if self.API_URI in url:
122-
if not self._session_id or not self._syno_token:
156+
if not self._session_id:
123157
return ERROR_INSUFFICIENT_USER_PRIVILEGE
124158

125159
if SynoDSMInformation.API_KEY in url:
126-
return DSM_6_DSM_INFORMATION
160+
return API_SWITCHER[self.dsm_version]["DSM_INFORMATION"]
127161

128162
if SynoCoreUtilization.API_KEY in url:
129-
return DSM_6_CORE_UTILIZATION
163+
return API_SWITCHER[self.dsm_version]["CORE_UTILIZATION"]
130164

131165
if SynoStorage.API_KEY in url:
132-
return DSM_6_STORAGE_STORAGE
166+
return API_SWITCHER[self.dsm_version]["STORAGE_STORAGE"]
133167

134168
if (
135169
"SYNO.FileStation.Upload" in url
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
"""DSM 5 SYNO.API.Auth data."""
2-
from tests.const import ( # pylint: disable=unused-import
2+
from tests.const import (
33
SESSION_ID,
44
DEVICE_TOKEN,
5-
SYNO_TOKEN,
65
ERROR_AUTH_OTP_NOT_SPECIFIED,
76
)
87

9-
10-
DSM_5_AUTH_LOGIN = {}
8+
# No synotoken for an unknown reason
9+
DSM_5_AUTH_LOGIN = {
10+
"data": {"is_portal_port": False, "sid": SESSION_ID},
11+
"success": True,
12+
}
1113
DSM_5_AUTH_LOGIN_2SA = ERROR_AUTH_OTP_NOT_SPECIFIED
12-
DSM_5_AUTH_LOGIN_2SA_OTP = {}
14+
DSM_5_AUTH_LOGIN_2SA_OTP = {
15+
"data": {"did": DEVICE_TOKEN, "is_portal_port": False, "sid": SESSION_ID},
16+
"success": True,
17+
}

0 commit comments

Comments
 (0)