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

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

""" 

Code used by checkviewaccess management _output 

""" 

from django.conf import settings 

from django.contrib.auth import get_user_model 

from django.utils import timezone 

try: 

from django.utils.translation import gettext as _ 

except: 

from django.utils.translation import ugettext as _ 

 

from django_roles_access.models import ViewAccess 

 

User = get_user_model() 

APP_NAME_FOR_NONE = _(u'Undefined app') 

 

NOT_SECURED_DEFAULT = _(u'WARNING: View has no security configured ' 

u'(ViewAccess) and application type is "NOT_SECURED".' 

u' No access is checked at all.') 

 

SECURED_DEFAULT = _(u'No security configured for the view (ViewAccess ' 

u'object) and application type is "SECURED". User is ' 

u'required to be authenticated to access the view.') 

 

PUBLIC_DEFAULT = _(u'No security configured for the view (ViewAccess object)' 

u' and application type is "PUBLIC". Anonymous user can' 

u' access the view.') 

 

NONE_TYPE_DEFAULT = _(u'ERROR: Django roles access middleware is active; or ' 

u'view is protected with Django roles decorator or mixin,' 

u' and has no application or application has no type. ' 

u'There are no View Access object for the view. Is not ' 

u'possible to determine behavior for access view. Access' 

u' to view is determined by view implementation.') 

 

 

def walk_site_url(_url_patterns, recursive_url='', 

view_name=None, app_name=None): 

result = [] 

for url in _url_patterns: 

if hasattr(url, 'pattern'): 

# Running With Django 2 

pattern = str(url.pattern) 

else: 

# Running with Django 1 

pattern = str(url.regex.pattern) 

pattern = pattern.strip('^').strip('$') # For better presentation 

if hasattr(url, 'url_patterns'): 

# When url object has 'url_patterns' attribute means is a Resolver 

if url.namespace: 

if view_name: 

new_view_name = view_name + ":" + url.namespace 

else: 

new_view_name = url.namespace 

else: 

new_view_name = None 

result.extend(walk_site_url(url.url_patterns, 

recursive_url + pattern, 

new_view_name, url.app_name)) 

else: 

if view_name: 

new_view_name = view_name + ":" + url.name 

else: 

new_view_name = url.name 

result.append((recursive_url + pattern, url.callback, 

new_view_name, app_name)) 

 

return result 

 

 

def get_views_by_app(site_urls): 

installed_apps = settings.INSTALLED_APPS 

result = {key: [] for key in installed_apps} 

for site_url in site_urls: 

try: 

url, callback, view_name, app_name = site_url 

except: 

raise TypeError 

if not app_name: 

app_name = APP_NAME_FOR_NONE 

try: 

result[app_name].append((url, callback, view_name)) 

except KeyError: 

result[app_name] = [(url, callback, view_name)] 

return result 

 

 

def get_view_analyze_report(app_type): 

if app_type == 'NOT_SECURED': 

return u'\t' + NOT_SECURED_DEFAULT 

elif app_type == 'SECURED': 

return u'\t' + SECURED_DEFAULT 

elif app_type == 'PUBLIC': 

return u'\t' + PUBLIC_DEFAULT 

else: 

return u'\t' + NONE_TYPE_DEFAULT 

 

 

def check_django_roles_is_used(view): 

if hasattr(view, 'access_by_role'): 

return True 

elif 'dispatch' in dir(view): 

if hasattr(view.dispatch, 'access_by_role'): 

return True 

return False 

 

 

def analyze_by_role(view_access): 

result = u'' 

if view_access.type == 'br': 

if view_access.roles.count() != 0: 

result = _(u'Roles with access: ') 

for role in view_access.roles.all(): 

result += role.name + u', ' 

result = result[:-2] 

else: 

result = _(u'ERROR: No roles configured to access de view.') 

return result 

 

 

def view_access_analyzer(app_type, callback, view_name, site_active): 

result = _(u'No Django roles access tool used. Access to view depends on ' 

u'its implementation.') 

view_access = ViewAccess.objects.filter(view=view_name).first() 

if site_active: 

if view_access: 

view_access_type = dict(ViewAccess.ACCESS_TYPES)[view_access.type] 

result = _(u'View access is of type {}.'.format(view_access_type)) 

result += analyze_by_role(view_access) 

else: 

result = get_view_analyze_report(app_type) 

else: 

if check_django_roles_is_used(callback): 

if view_access: 

view_access_type = \ 

dict(ViewAccess.ACCESS_TYPES)[view_access.type] 

result = _( 

u'View access is of type {}.'.format(view_access_type)) 

result += analyze_by_role(view_access) 

else: 

result = get_view_analyze_report(app_type) 

else: 

if view_access: 

result = _(u'ERROR: View access object exist for the view, ' 

u'but no Django role access tool is used: neither ' 

u'decorator, mixin, or middleware.') 

return result 

 

 

class OutputReport(object): 

 

HEADER = _(u'Start checking views access.\nStart gathering information.') 

MIDDLEWARE_STATUS = _('Django roles access middleware is active:') 

END_HEADER = _(u'Finish gathering information.') 

CONSOLE = 'console' 

CSV = 'csv' 

CSV_COLUMNS = _(u'App Name,Type,View Name,Url,Status,Status description') 

 

def __init__(self, stdout, style): 

self.stdout = stdout 

self.style = style 

self._format = 'console' 

self._row = u'' 

 

def set_format(self, _format): 

self._format = _format 

 

def add_to_row(self, data): 

self._row += data 

 

def write(self, text): 

self.stdout.write(self.style.SUCCESS(text)) 

 

def write_header(self): 

if self._format == self.CONSOLE: 

self.write(self.HEADER) 

elif self._format == self.CSV: 

self.write(_(u'Reported: {}'.format(timezone.now()))) 

 

def write_middleware_status(self, status): 

output = self.MIDDLEWARE_STATUS + ' {}.\n'.format(status) 

self.stdout.write(self.style.SUCCESS(output)) 

 

def write_end_of_head(self): 

if self._format == self.CONSOLE: 

output = self.END_HEADER 

else: # self._format == self.CSV: 

output = self.CSV_COLUMNS 

self.write(output) 

 

def process_application_data(self, app_name, app_type, view_list): 

output = _(u'\tAnalyzing: {}\n'.format(app_name)) 

_app_type = app_type 

if app_type is None: 

output += _(u'\t\t{} has no type.'.format(app_name, app_type)) 

_app_type = _('no type') 

else: 

output += _(u'\t\t{} is {} type.'.format(app_name, app_type)) 

if len(view_list) == 0: 

output += _(u'\t\t{} does not have configured views.'.format( 

app_name)) 

_app_type += ',,,,' 

if self._format == self.CONSOLE: 

self.write(output) 

elif self._format == self.CSV: 

self.add_to_row('{},{},'.format(app_name, _app_type)) 

 

def process_view_data(self, view_name, url): 

if self._format == self.CONSOLE: 

_output = _(u'\n\t\tAnalysis for view: {}'.format(view_name)) 

_output += _(u'\n\t\tView url: {}'.format(url)) 

self.write(_output) 

elif self._format == self.CSV: 

self.add_to_row('{},{},'.format(view_name, url)) 

 

def write_view_access_analyzer(self, text): 

if self._format == self.CONSOLE: 

if 'ERROR:' in text: 

self.stdout.write(self.style.ERROR('\t\t' + text)) 

elif 'WARNING:' in text: 

self.stdout.write(self.style.WARNING('\t\t' + text)) 

else: 

self.write('\t\t' + text) 

elif self._format == self.CSV: 

_row = self._row.split(',') 

if 'ERROR:' in text: 

self.add_to_row(u'Error,{}\n'.format(text.split('ERROR: ')[1])) 

_output = self.style.ERROR(self._row) 

elif 'WARNING:' in text: 

self.add_to_row(u'Warning,{}\n'.format( 

text.split('WARNING: ')[1])) 

_output = self.style.WARNING(self._row) 

else: 

self.add_to_row(u'Normal,{}\n'.format(text)) 

_output = self.style.SUCCESS(self._row) 

self.stdout.write(_output) 

# Delete view information to start cycle again. 

# only app_name and app_type are left. 

self._row = _row[0] + ',' + _row[1] + ',' 

 

def close_application_data(self, app_name): 

if self._format == self.CONSOLE: 

_output = _(u'\tFinish analyzing {}.').format(app_name) 

self.write(_output) 

elif self._format == self.CSV: 

self._row = u'' 

 

def write_footer(self): 

if self._format == self.CONSOLE: 

_output = _(u'End checking view access.') 

self.write(_output) 

elif self._format == self.CSV: 

self._row = u'\n'