Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

# -*- coding: utf-8 -*- 

# Module: Utils 

# Author: asciidisco 

# Created on: 24.07.2017 

# License: MIT https://goo.gl/WA1kby 

 

"""Settings interface for Kodi, includes en-/decryption of credentials""" 

 

import base64 

import uuid 

import time 

import xbmc 

try: 

import pyDes 

except ImportError: 

USE_PYDES = False 

else: 

USE_PYDES = True 

 

 

class Settings(object): 

"""Settings interface for Kodi, includes en-/decryption of credentials""" 

 

def __init__(self, utils, dialogs, constants): 

""" 

Injects instances, sets encryption var & addon_id 

 

:param utils: Utils instance 

:type utils: resources.lib.Utils 

:param dialogs: Dialogs instance 

:type dialogs: resources.lib.Dialogs 

:param constants: Constants instance 

:type constants: resources.lib.Constants 

""" 

self.utils = utils 

self.dialogs = dialogs 

self.constants = constants 

self.use_encryption = USE_PYDES 

self.addon_id = self.constants.get_addon_id() 

 

def uniq_id(self, delay=1): 

""" 

Returns a unique id based on the devices MAC address 

 

:param delay: Retry delay in sec 

:type delay: int 

:returns: string -- Unique secret 

""" 

mac_addr = self.__get_mac_address(delay=delay) 

if ':' in mac_addr and delay == 2: 

return uuid.uuid5(uuid.NAMESPACE_DNS, str(mac_addr)).bytes 

else: 

error_msg = '[%s] error: failed to get device id (%s)' 

self.utils.log(error_msg % (self.addon_id, str(mac_addr))) 

self.dialogs.show_storing_credentials_failed() 

return 'UnsafeStaticSecret' 

 

def encode(self, data): 

""" 

Encodes data 

 

:param data: Data to be encoded 

:type data: str 

:returns: string -- Encoded data 

""" 

key_handle = pyDes.triple_des( 

self.uniq_id(delay=2), 

pyDes.CBC, 

"\0\0\0\0\0\0\0\0", 

padmode=pyDes.PAD_PKCS5) 

encrypted = key_handle.encrypt( 

data=data) 

return base64.b64encode(s=encrypted) 

 

def decode(self, data): 

""" 

Decodes data 

 

:param data: Data to be decoded 

:type data: str 

:returns: string -- Decoded data 

""" 

key_handle = pyDes.triple_des( 

self.uniq_id(delay=2), 

pyDes.CBC, 

"\0\0\0\0\0\0\0\0", 

padmode=pyDes.PAD_PKCS5) 

decrypted = key_handle.decrypt( 

data=base64.b64decode(s=data)) 

return decrypted 

 

def has_credentials(self): 

""" 

checks if credentials are set 

 

:returns: bool -- Credentials set 

""" 

addon = self.utils.get_addon() 

user = addon.getSetting('email') 

password = addon.getSetting('password') 

return user != '' or password != '' 

 

def set_credentials(self): 

""" 

Opens up the email & password dialogs and stores entered credentials 

 

:returns: tuple -- Credential pai 

""" 

addon = self.utils.get_addon() 

user = self.dialogs.show_email_dialog() 

password = self.dialogs.show_password_dialog() 

do_encrypt = addon.getSetting('encrypt_credentials') 

if do_encrypt == 'True' and self.use_encryption is True: 

_mail = self.encode(user) 

_password = self.encode(password) 

else: 

_mail = user 

_password = password 

addon.setSetting('email', _mail) 

addon.setSetting('password', _password) 

return (user, password) 

 

def get_credentials(self): 

""" 

Returns credentials in clear text 

 

:returns: tuple -- Clear text credentials 

""" 

addon = self.utils.get_addon() 

user = addon.getSetting('email') 

password = addon.getSetting('password') 

if '@' in user: 

return (user, password) 

return (self.decode(user), self.decode(password)) 

 

@classmethod 

def __get_mac_address(cls, delay=1): 

""" 

Returns the users mac address 

 

:param delay: retry delay in sec 

:type delay: int 

:returns: string -- Devices MAC address 

""" 

mac_addr = xbmc.getInfoLabel('Network.MacAddress') 

# hack response busy 

i = 0 

while ':' not in mac_addr and i < 3: 

i += 1 

time.sleep(delay) 

mac_addr = xbmc.getInfoLabel('Network.MacAddress') 

return mac_addr