Solve the easier portion of #1890 - prevent authenticated users impersonating
other users in ticket/comment/attachment/wikipage creation.

Also, hide the redundant "Your email or username:" field from authenticated
users.

* templates/attachment.cs, templates/newticket.cs, templates/ticket.cs,
  templates/wiki.cs: Only show "Your email or username:" field if not
    authenticated.

* trac/util/__init__.py (get_reporter_id): Refactor a bit.
    Add optional second argument specifying a request argument to prefer over
    session name/email information for anonymous requests.

* trac/attachment.py (AttachmentModule._do_save),
* trac/wiki/web_ui.py (WikiModule._do_save, WikiModule._render_editor),
* trac/ticket/web_ui.py (NewticketModule.process_request,
  NewticketModule._do_create, TicketModule.process_request,
  TicketModule._do_save):
    At every appropriate point, use get_reporter_id() to retrieve author
    or reporter names, thus (for authenticated requests) giving req.authname
    precedence over req.args['author' or 'reporter'].
Index: templates/ticket.cs
===================================================================
--- templates/ticket.cs	(revision 3391)
+++ templates/ticket.cs	(working copy)
@@ -140,12 +140,14 @@
  <hr />
  <h3><a name="edit" onfocus="document.getElementById('comment').focus()">Add/Change #<?cs
    var:ticket.id ?> (<?cs var:ticket.summary ?>)</a></h3>
+ <?cs if:trac.authname == "anonymous" ?>
+  <div class="field">
+   <label for="author">Your email or username:</label><br />
+   <input type="text" id="author" name="author" size="40"
+     value="<?cs var:ticket.reporter_id ?>" /><br />
+  </div>
+ <?cs /if ?>
  <div class="field">
-  <label for="author">Your email or username:</label><br />
-  <input type="text" id="author" name="author" size="40"
-    value="<?cs var:ticket.reporter_id ?>" /><br />
- </div>
- <div class="field">
   <fieldset class="iefix">
    <label for="comment">Comment (you may use <a tabindex="42" href="<?cs
      var:trac.href.wiki ?>/WikiFormatting">WikiFormatting</a> here):</label><br />
Index: templates/attachment.cs
===================================================================
--- templates/attachment.cs	(revision 3391)
+++ templates/attachment.cs	(working copy)
@@ -14,12 +14,14 @@
   </div>
   <fieldset>
    <legend>Attachment Info</legend>
+   <?cs if:trac.authname == "anonymous" ?>
+    <div class="field">
+     <label>Your email or username:<br />
+     <input type="text" name="author" size="30" value="<?cs
+       var:attachment.author?>" /></label>
+    </div>
+   <?cs /if ?>
    <div class="field">
-    <label>Your email or username:<br />
-    <input type="text" name="author" size="30" value="<?cs
-      var:attachment.author?>" /></label>
-   </div>
-   <div class="field">
     <label>Description of the file (optional):<br />
     <input type="text" name="description" size="60" /></label>
    </div>
Index: templates/newticket.cs
===================================================================
--- templates/newticket.cs	(revision 3391)
+++ templates/newticket.cs	(working copy)
@@ -11,12 +11,14 @@
 <?cs include:"site_newticket.cs" ?>
 <form id="newticket" method="post" action="<?cs
   var:trac.href.newticket ?>#preview">
+ <?cs if:trac.authname == "anonymous" ?>
+  <div class="field">
+   <label for="reporter">Your email or username:</label><br />
+   <input type="text" id="reporter" name="reporter" size="40" value="<?cs
+     var:newticket.reporter ?>" /><br />
+  </div>
+ <?cs /if ?>
  <div class="field">
-  <label for="reporter">Your email or username:</label><br />
-  <input type="text" id="reporter" name="reporter" size="40" value="<?cs
-    var:newticket.reporter ?>" /><br />
- </div>
- <div class="field">
   <label for="summary">Short summary:</label><br />
   <input id="summary" type="text" name="summary" size="80" value="<?cs
     var:newticket.summary ?>"/>
Index: templates/wiki.cs
===================================================================
--- templates/wiki.cs	(revision 3391)
+++ templates/wiki.cs	(working copy)
@@ -240,12 +240,14 @@
     </div>
     <fieldset id="changeinfo">
      <legend>Change information</legend>
+     <?cs if:trac.authname == "anonymous" ?>
+      <div class="field">
+       <label>Your email or username:<br />
+       <input id="author" type="text" name="author" size="30" value="<?cs
+         var:wiki.author ?>" /></label>
+      </div>
+     <?cs /if ?>
      <div class="field">
-      <label>Your email or username:<br />
-      <input id="author" type="text" name="author" size="30" value="<?cs
-        var:wiki.author ?>" /></label>
-     </div>
-     <div class="field">
       <label>Comment about this change (optional):<br />
       <input id="comment" type="text" name="comment" size="60" value="<?cs
         var:wiki.comment?>" /></label>
Index: trac/attachment.py
===================================================================
--- trac/attachment.py	(revision 3391)
+++ trac/attachment.py	(working copy)
@@ -362,7 +362,7 @@
             raise TracError('No file uploaded')
 
         attachment.description = req.args.get('description', '')
-        attachment.author = req.args.get('author', '')
+        attachment.author = get_reporter_id(req, 'author')
         attachment.ipnr = req.remote_addr
         if req.args.get('replace'):
             try:
Index: trac/ticket/web_ui.py
===================================================================
--- trac/ticket/web_ui.py	(revision 3391)
+++ trac/ticket/web_ui.py	(working copy)
@@ -106,7 +106,7 @@
 
         ticket = Ticket(self.env, db=db)
         ticket.populate(req.args)
-        ticket.values.setdefault('reporter', get_reporter_id(req))
+        ticket.values['reporter'] = get_reporter_id(req, 'reporter')
 
         if ticket.values.has_key('description'):
             description = wiki_to_html(ticket['description'], self.env, req, db)
@@ -159,8 +159,8 @@
             raise TracError('Tickets must contain a summary.')
 
         ticket = Ticket(self.env, db=db)
-        ticket.values.setdefault('reporter', get_reporter_id(req))
         ticket.populate(req.args)
+        ticket.values['reporter'] = get_reporter_id(req, 'reporter')
         self._validate_ticket(req, ticket)
 
         ticket.insert(db=db)
@@ -249,7 +249,6 @@
         id = int(req.args.get('id'))
 
         ticket = Ticket(self.env, id, db=db)
-        reporter_id = get_reporter_id(req)
 
         if req.method == 'POST':
             if not req.args.has_key('preview'):
@@ -264,7 +263,6 @@
                 req.hdf['ticket.reassign_owner'] = req.args.get('reassign_owner') \
                                                    or req.authname
                 req.hdf['ticket.resolve_resolution'] = req.args.get('resolve_resolution')
-                reporter_id = req.args.get('author')
                 comment = req.args.get('comment')
                 if comment:
                     req.hdf['ticket.comment'] = comment
@@ -276,7 +274,8 @@
             # Store a timestamp in order to detect "mid air collisions"
             req.hdf['ticket.ts'] = ticket.time_changed
 
-        self._insert_ticket_data(req, db, ticket, reporter_id)
+        self._insert_ticket_data(req, db, ticket,
+                                 get_reporter_id(req, 'author'))
 
         mime = Mimeview(self.env)
         format = req.args.get('format')
@@ -516,7 +515,7 @@
         internal_cnum = cnum
         if cnum and replyto: # record parent.child relationship
             internal_cnum = '%s.%s' % (replyto, cnum)
-        ticket.save_changes(req.args.get('author', req.authname),
+        ticket.save_changes(get_reporter_id(req, 'author'),
                             req.args.get('comment'), when=now, db=db,
                             cnum=internal_cnum)
         db.commit()
Index: trac/wiki/web_ui.py
===================================================================
--- trac/wiki/web_ui.py	(revision 3391)
+++ trac/wiki/web_ui.py	(working copy)
@@ -207,7 +207,7 @@
         for manipulator in self.page_manipulators:
             manipulator.validate_wiki_page(req, page)
 
-        page.save(req.args.get('author'), req.args.get('comment'),
+        page.save(get_reporter_id(req, 'author'), req.args.get('comment'),
                   req.remote_addr)
         req.redirect(req.href.wiki(page.name))
 
@@ -307,7 +307,7 @@
         if preview:
             page.readonly = req.args.has_key('readonly')
 
-        author = req.args.get('author', get_reporter_id(req))
+        author = get_reporter_id(req, 'author')
         comment = req.args.get('comment', '')
         editrows = req.args.get('editrows')
         if editrows:
Index: trac/util/__init__.py
===================================================================
--- trac/util/__init__.py	(revision 3391)
+++ trac/util/__init__.py	(working copy)
@@ -39,18 +39,20 @@
 
 # -- req/session utils
 
-def get_reporter_id(req):
+def get_reporter_id(req, arg_name=None):
+    if req.authname != 'anonymous':
+        return req.authname
+    if arg_name:
+        r = req.args.get(arg_name)
+        if r:
+            return r
     name = req.session.get('name', None)
     email = req.session.get('email', None)
-    
-    if req.authname != 'anonymous':
-        return req.authname
-    elif name and email:
+    if name and email:
         return '%s <%s>' % (name, email)
-    elif not name and email:
+    if not name and email:
         return email
-    else:
-        return req.authname
+    return req.authname # == 'anonymous'
 
 
 # -- algorithmic utilities
