Ticket #153: privacy.3.diff
| File privacy.3.diff, 23.8 KB (added by Waldemar Kornewald <wkornewald>, 5 years ago) |
|---|
-
trac/ticket/api.py
102 102 field = {'name': 'owner', 'label': 'Owner'} 103 103 if self.restrict_owner: 104 104 field['type'] = 'select' 105 users = [''] # for clearing assignment106 105 perm = PermissionSystem(self.env) 107 for username, name, email in self.env.get_known_users(db): 108 if perm.get_user_permissions(username).get('TICKET_MODIFY'): 109 users.append(username) 110 field['options'] = users 106 def valid_owner(username): 107 return perm.get_user_permissions(username).get('TICKET_MODIFY') 108 field['options'] = [username for username, name, email 109 in self.env.get_known_users() 110 if valid_owner(username)] 111 111 field['optional'] = True 112 112 else: 113 113 field['type'] = 'text' -
trac/ticket/web_ui.py
602 602 data = { 603 603 'ticket': ticket, 604 604 'context': Context(self.env, req, 'ticket', ticket.id, db=db), 605 'changes': changes ,605 'changes': changes 606 606 } 607 607 608 608 output = Chrome(self.env).render_template(req, 'ticket.rss', data, -
trac/ticket/report.py
23 23 from trac.db import get_column_names 24 24 from trac.perm import IPermissionRequestor 25 25 from trac.util import sorted 26 from trac.util.text import to_unicode, unicode_urlencode26 from trac.util.text import obfuscate_email_address, to_unicode, unicode_urlencode 27 27 from trac.util.html import html 28 28 from trac.web.api import IRequestHandler, RequestDone 29 29 from trac.web.chrome import add_link, add_stylesheet, INavigationContributor … … 278 278 279 279 # Get the email addresses of all known users 280 280 email_map = {} 281 for username, name, email in self.env.get_known_users(): 282 if email: 283 email_map[username] = email 281 show_email_addresses = self.config.getbool('trac', 282 'show_email_addresses') 283 if show_email_addresses: 284 for username, name, email in self.env.get_known_users(): 285 if email: 286 email_map[username] = email 284 287 285 288 # Structure the rows and cells: 286 289 # - group rows according to __group__ value, if defined … … 313 316 # Special casing based on column name 314 317 col = col.strip('_') 315 318 if col == 'reporter': 316 if '@' in value: 319 if show_email_addresses: 320 if '@' in value: 321 cell['author'] = value 322 elif value in email_map: 323 cell['author'] = email_map[value] 324 else: 317 325 cell['author'] = value 318 elif value in email_map:319 cell['author'] = email_map[value]320 326 elif col == 'resource': 321 327 resource = value 322 328 cell_group.append(cell) -
trac/ticket/query.py
684 684 query.verbose = True 685 685 db = self.env.get_db_cnx() 686 686 results = query.execute(req, db) 687 for result in results: 688 if result['reporter'].find('@') == -1: 689 result['reporter'] = '' 687 if self.config.getbool('trac', 'show_email_addresses'): 688 for result in results: 689 if result['reporter'].find('@') == -1: 690 result['reporter'] = '' 690 691 query_href = req.abs_href.query(group=query.group, 691 692 groupdesc=query.groupdesc and 1 or None, 692 693 verbose=query.verbose and 1 or None, -
trac/versioncontrol/web_ui/log.py
179 179 changes = get_changes(repos, revs) 180 180 extra_changes = {} 181 181 email_map = {} 182 show_email_addresses = self.config.getbool('trac', 183 'show_email_addresses') 182 184 if format == 'rss': 183 185 # Get the email addresses of all known users 184 email_map = {}185 for username,name,email in self.env.get_known_users():186 if email:187 email_map[username] = email186 if show_email_addresses: 187 for username,name,email in self.env.get_known_users(): 188 if email: 189 email_map[username] = email 188 190 elif format == 'changelog': 189 191 for rev in revs: 190 192 changeset = changes[rev] -
trac/perm.py
246 246 # IPermissionRequestor methods 247 247 248 248 def get_permission_actions(self): 249 """Implement the global `TRAC_ADMIN` meta permission.""" 250 actions = [] 249 """Implement the global `TRAC_ADMIN` meta permission and the 250 `EMAIL_VIEW` permission which allows for showing email addresses 251 when "show_email_addresses" is "false".""" 252 actions = ['EMAIL_VIEW'] 251 253 for requestor in [r for r in self.requestors if r is not self]: 252 254 for action in requestor.get_permission_actions(): 253 255 if isinstance(action, tuple): 254 256 actions.append(action[0]) 255 257 else: 256 258 actions.append(action) 257 return [('TRAC_ADMIN', actions) ]259 return [('TRAC_ADMIN', actions), 'EMAIL_VIEW'] 258 260 259 261 260 262 class PermissionCache(object): -
trac/timeline/web_ui.py
139 139 if format == 'rss': 140 140 # Get the email addresses of all known users 141 141 email_map = {} 142 for username, name, email in self.env.get_known_users(): 143 if email: 144 email_map[username] = email 142 if self.config.getbool('trac', 'show_email_addresses'): 143 for username, name, email in self.env.get_known_users(): 144 if email: 145 email_map[username] = email 145 146 data['email_map'] = email_map 146 147 return 'timeline.rss', data, 'application/rss+xml' 147 148 -
trac/web/chrome.py
34 34 get_module_path 35 35 from trac.util.compat import partial, set 36 36 from trac.util.html import plaintext 37 from trac.util.text import pretty_size, shorten_line, unicode_quote_plus, \38 to_unicode37 from trac.util.text import pretty_size, obfuscate_email_address, \ 38 shorten_line, unicode_quote_plus, to_unicode 39 39 from trac.util.datefmt import pretty_timedelta, format_datetime, format_date, \ 40 40 format_time, http_date 41 41 from trac.web.api import IRequestHandler, HTTPNotFound … … 194 194 logo_height = IntOption('header_logo', 'height', -1, 195 195 """Height of the header logo image in pixels.""") 196 196 197 show_email_addresses = BoolOption('trac', 'show_email_addresses', 'false', 198 """Show email addresses instead of usernames. If false, we obfuscate 199 email addresses (''since 0.11'').""") 200 197 201 templates = None 198 202 199 203 # A dictionary of default context data for templates … … 209 213 'groupby': compat.groupby, 210 214 'http_date': http_date, 211 215 'itemgetter': compat.itemgetter, 216 'obfuscate_email_address': obfuscate_email_address, 212 217 'paginate': presentation.paginate, 213 218 'partial': partial, 214 219 'plaintext': plaintext, … … 468 473 if req: 469 474 tzinfo = req.tz 470 475 476 d['show_email_addresses'] = self.show_email_addresses or \ 477 'EMAIL_VIEW' in req.perm 471 478 d.update({ 472 479 'req': req, 473 480 'abs_href': req and req.abs_href or self.env.abs_href, -
trac/util/text.py
170 170 except ImportError: 171 171 return t 172 172 173 def obfuscate_email_address(address): 174 if address: 175 at = address.find('@') 176 if at != -1: 177 return address[:at] + "@..." + ((address[-1] == '>' and '>') or '') 178 return address 173 179 174 180 # -- Conversion 175 181 -
templates/ticket_view.html
54 54 py:with="fields = [f for f in fields if not f.skip]"> 55 55 <tr> 56 56 <th id="h_reporter">Reported by:</th> 57 <td headers="h_reporter" class="searchable" >${ticket.reporter}</td>57 <td headers="h_reporter" class="searchable" py:with="r=ticket.reporter">${show_email_addresses and r or obfuscate_email_address(r)}</td> 58 58 <th id="h_owner">Assigned to:</th> 59 <td headers="h_owner" >${ticket.owner}59 <td headers="h_owner" py:with="o=ticket.owner">${show_email_addresses and o or obfuscate_email_address(o)} 60 60 <py:if test="ticket.status == 'assigned'">(accepted)</py:if> 61 61 </td> 62 62 </tr> … … 84 84 </span> 85 85 Description 86 86 <span py:if="description_change" class="lastmod" 87 title="$description_change.date" >88 (last modified by ${ description_change.author})87 title="$description_change.date" py:with="a=description_change.author"> 88 (last modified by ${show_email_addresses and a or obfuscate_email_address(a)}) 89 89 (<a href="${href.ticket(ticket.id, action='diff', version=description_change.cnum)}">diff</a>) 90 90 </span> 91 91 </h3> … … 127 127 </py:if> 128 128 129 129 </span> 130 ${change.date} changed by ${ change.author}130 ${change.date} changed by ${show_email_addresses and change.author or obfuscate_email_address(change.author)} 131 131 </h3> 132 132 <ul py:if="change.fields" class="changes"> 133 133 <li py:for="field_name, field in change.fields.items()" -
templates/report.rss
1 1 <?xml version="1.0"?> 2 <rss version="2.0" xmlns:py="http://genshi.edgewall.org/"> 2 <rss version="2.0" xmlns:py="http://genshi.edgewall.org/" 3 xmlns:dc="http://purl.org/dc/elements/1.1/"> 3 4 <channel> 4 5 <title>$project.name: $report.title</title> 5 6 <link>${abs_href.report(report.id)}</link> … … 17 18 <py:with vars="col = cell.header.col.strip('_')"> 18 19 <py:choose> 19 20 <py:when test="col == 'reporter'"> 20 <author py:if="cell.author">$cell.author</author> 21 <py:if test="cell.author"> 22 <py:choose> 23 <author py:when="show_email_addresses">$cell.author</author> 24 <dc:creator py:otherwise="">${obfuscate_email_address(cell.author)}</dc:creator> 25 </py:choose> 26 </py:if> 21 27 </py:when> 22 28 <py:when test="col in ('time', 'changetime', 'created', 'modified')"> 23 29 <!-- FIXME: we end up with multiple pubDate --> -
templates/macros.html
151 151 <py:def function="show_one_attachment(attachment)"> 152 152 <a href="${context.href('attachment', context.resource, context.id, attachment.filename)}" 153 153 title="View attachment">$attachment.filename</a> 154 (${sizeinfo(attachment.size)}) - added by <em>$attachment.author</em>154 (${sizeinfo(attachment.size)}) - added by <em>${show_email_addresses and attachment.author or obfuscate_email_address(attachment.author)}</em> 155 155 ${dateinfo(attachment.date)} ago. 156 156 </py:def> 157 157 <py:choose test=""> -
templates/wiki_history.html
47 47 <a href="${href.wiki(page.name, version=item.version)}" title="View this version">$item.version</a> 48 48 </td> 49 49 <td class="date">${format_datetime(item.date)}</td> 50 <td class="author" title="${item.ipnr and 'IP-Address: ' + item.ipnr or None">$ item.author</td>50 <td class="author" title="${item.ipnr and 'IP-Address: ' + item.ipnr or None">${show_email_addresses and item.author or obfuscate_email_address(item.author)}</td> 51 51 <td class="comment">${context.wiki_to_oneliner(item.comment, shorten=True)}</td> 52 52 </tr> 53 53 </tbody> -
templates/revisionlog.rss
1 1 <?xml version="1.0"?> 2 <rss version="2.0" xmlns:py="http://genshi.edgewall.org/"> 2 <rss version="2.0" xmlns:py="http://genshi.edgewall.org/" 3 xmlns:dc="http://purl.org/dc/elements/1.1/"> 3 4 <channel py:with="log_href = abs_href.log(path, rev=rev)"> 4 5 <title>Revisions of $path</title> 5 6 <link>$log_href</link> … … 13 14 </image> 14 15 15 16 <item py:for="item in items" py:with="change = changes[item.rev]; item_context = context('changeset', change.rev, abs_urls=True)"> 16 <author py:if="change.author" py:with="a = change.author">${a and '@' in a and a or email_map.get(a)}</author> 17 <py:if test="change.author"> 18 <py:choose> 19 <author py:when="show_email_addresses" py:with="a = change.author">${a and '@' in a and a or email_map.get(a) or a}</author> 20 <dc:creator py:otherwise="">${change.author}</dc:creator> 21 </py:choose> 22 </py:if> 17 23 <pubDate>${http_date(change.date)}</pubDate> 18 24 <title>Revision $item.rev: ${shorten_line(change.message)}</title> 19 25 <link>${abs_href.changeset(rev, path)}</link> -
templates/timeline.html
38 38 <py:for each="event in events"> 39 39 <dt class="${event.kind}"><a href="${event.href}"> 40 40 <span class="time">${format_time(event.date, str('%H:%M'))}</span> ${event.title} 41 <py:if test="event.author" >by ${event.author}</py:if>41 <py:if test="event.author" py:with="a=event.author">by ${show_email_addresses and a or obfuscate_email_address(a)}</py:if> 42 42 </a></dt> 43 43 <dd class="${event.kind}" py:with="wikify = event.use_oneliner and partial(event.context.wiki_to_oneliner, shorten=event.shorten_oneliner) or event.context.wiki_to_html"> 44 44 ${event.markup} -
templates/timeline.rss
1 1 <?xml version="1.0"?> 2 <rss version="2.0" xmlns:py="http://genshi.edgewall.org/"> 2 <rss version="2.0" xmlns:py="http://genshi.edgewall.org/" 3 xmlns:dc="http://purl.org/dc/elements/1.1/"> 3 4 <channel> 4 5 <title>${project.name}</title> 5 6 <link>${abs_href.timeline()}</link> … … 14 15 15 16 <item py:for="event in events"> 16 17 <title>${plaintext(event.title, keeplinebreaks=False)}</title> 17 <py:with vars="author=event.author; author = author and '@' in author and author or email_map.get(author)"> 18 <author py:if="author">$author</author> 19 </py:with> 18 <py:choose> 19 <py:when test="show_email_addresses"> 20 <py:with vars="author=event.author; author = author and '@' in author and author or email_map.get(author)"> 21 <author py:if="author">$author</author> 22 </py:with> 23 </py:when> 24 <py:otherwise> 25 <dc:creator py:if="event.author" py:with="a=event.author">${show_email_addresses and a or obfuscate_email_address(a)}</dc:creator> 26 </py:otherwise> 27 </py:choose> 20 28 <pubDate>${http_date(event.date)}</pubDate> 21 29 <link>${event.abs_href}</link> 22 30 <guid isPermaLink="false">${event.abs_href}/${event.dateuid()}</guid> -
templates/ticket.rss
1 1 <?xml version="1.0"?> 2 <rss version="2.0" xmlns:py="http://genshi.edgewall.org/"> 2 <rss version="2.0" xmlns:py="http://genshi.edgewall.org/" 3 xmlns:dc="http://purl.org/dc/elements/1.1/"> 3 4 <channel py:with="abs_context = context(abs_urls=True)"> 4 5 <title>${project.name}: Ticket $title</title> 5 6 <link>${abs_href.ticket(ticket.id)}</link> … … 13 14 <generator>Trac $trac.version</generator> 14 15 15 16 <item py:for="change in changes"> 16 <author py:if="change.author">$change.author</author> 17 <py:if test="change.author"> 18 <py:choose> 19 <author py:when="show_email_addresses">$change.author</author> 20 <dc:creator py:otherwise="">${obfuscate_email_address(change.author)}</dc:creator> 21 </py:choose> 22 </py:if> 17 23 <pubDate>${http_date(change.date)}</pubDate> 18 24 <title>$change.title</title> 19 25 <link>${abs_href.ticket(ticket.id)}<py:if test="change.cnum">#comment:$change.cnum</py:if></link> … … 38 44 </py:for> 39 45 </ul> 40 46 </py:if> 41 ${unicode(abs_context.wiki_to_html(change.comment , absurls=True))}47 ${unicode(abs_context.wiki_to_html(change.comment))} 42 48 </description> 43 49 <category>Ticket</category> 44 50 </item> -
templates/attachment.html
76 76 <table id="info" summary="Description"> 77 77 <tbody> 78 78 <tr> 79 <th scope="col" >79 <th scope="col" py:with="a=attachment.author"> 80 80 File $attachment.filename, ${sizeinfo(attachment.size)} 81 (added by $ attachment.author, ${dateinfo(attachment.date)} ago)81 (added by ${show_email_addresses and a or obfuscate_email_address(a)}, ${dateinfo(attachment.date)} ago) 82 82 </th> 83 83 </tr> 84 84 <tr> -
templates/wiki_diff.html
46 46 <dt class="property author">Author:</dt> 47 47 <dd class="author" py:choose=""> 48 48 <em py:when="multi" class="multi">(multiple changes)</em> 49 <py:otherwise>$ change.author<span py:if="change.ipnr" class="ipnr">(IP: $change.ipnr)</span></py:otherwise>49 <py:otherwise>${show_email_addresses and change.author or obfuscate_email_address(change.author)} <span py:if="change.ipnr" class="ipnr">(IP: $change.ipnr)</span></py:otherwise> 50 50 </dd> 51 51 <dt class="property message">Comment:</dt> 52 52 <dd class="message" py:choose=""> -
templates/wiki_view.html
41 41 <table id="info" summary="Revision info"> 42 42 <tbody> 43 43 <tr><th scope="row"> 44 Version $page.version (modified by $page.author, ${dateinfo(page.time)} ago)44 Version $page.version (modified by ${show_email_addresses and page.author or obfuscate_email_address(page.author)}, ${dateinfo(page.time)} ago) 45 45 </th></tr> 46 46 <tr><td class="message"> 47 47 ${context.wiki_to_html(page.comment or '--')} -
templates/query_div.html
50 50 <td py:otherwise="" class="$name" py:choose=""> 51 51 <a py:when="name == 'summary'" href="$result.href" title="View ticket">$value</a> 52 52 <span py:when="isinstance(value, datetime)">${format_datetime(value)}</span> 53 <span py:when="name in ('owner', 'reporter')">${show_email_addresses and value or obfuscate_email_address(value)}</span> 53 54 <span py:otherwise="">$value</span> 54 55 </td> 55 56 </py:with> -
templates/query.rss
1 1 <?xml version="1.0"?> 2 <rss version="2.0" xmlns:py="http://genshi.edgewall.org/"> 2 <rss version="2.0" xmlns:py="http://genshi.edgewall.org/" 3 xmlns:dc="http://purl.org/dc/elements/1.1/"> 3 4 <channel> 4 5 <title>$project.name: Ticket Query</title> 5 6 <link>$query_href</link> … … 16 17 <guid isPermaLink="false">$href</guid> 17 18 <title>#$result.id: $result.summary</title> 18 19 <pubDate py:if="result.time">${http_date(result.time)}</pubDate> 19 <author py:if="result.reporter">$result.reporter</author> 20 <py:if test="result.reporter"> 21 <py:choose> 22 <author py:when="show_email_addresses">$result.reporter</author> 23 <dc:creator py:otherwise="">${obfuscate_email_address(result.reporter)}</dc:creator> 24 </py:choose> 25 </py:if> 20 26 <description>${unicode(context('ticket', result.id, abs_urls=True).wiki_to_html(result.description))}</description> 21 27 <category>Results</category> 22 28 <comments>$href#changelog</comments> -
templates/ticket_diff.html
50 50 <dt class="property author">Author:</dt> 51 51 <dd class="author" py:choose=""> 52 52 <em py:when="multi" class="multi">(multiple changes)</em> 53 <py:otherwise >$change.author<span py:if="change.ipnr" class="ipnr">(IP: $change.ipnr)</span></py:otherwise>53 <py:otherwise py:with="a=change.author">${show_email_addressses and a or obfuscate_email_address(a)} <span py:if="change.ipnr" class="ipnr">(IP: $change.ipnr)</span></py:otherwise> 54 54 </dd> 55 55 <dt class="property message">Comment:</dt> 56 56 <dd class="message" py:choose="">
