Hi Stephen and Andrew, I've installed this on py[23].patchwork.dja.id.au
> diff --git a/htdocs/css/style.css b/htdocs/css/style.css > index 5218f6d..af2f073 100644 > --- a/htdocs/css/style.css > +++ b/htdocs/css/style.css > @@ -369,7 +369,6 @@ table.form th.headerrow { > } > > table.form th { > - font-weight: normal; What does this change? > text-align: left; > vertical-align: top; > padding-top: 0.6em; > diff --git a/patchwork/templates/patchwork/profile.html > b/patchwork/templates/patchwork/profile.html > index f976195..2005687 100644 > --- a/patchwork/templates/patchwork/profile.html > +++ b/patchwork/templates/patchwork/profile.html > @@ -134,7 +134,35 @@ address.</p> > > <div class="box"> > <h2>Authentication</h2> > -<a href="{% url 'password_change' %}">Change password</a> > + > +<table class="form"> > + <tr> > + <th>Password:</th> > + <td><a href="{% url 'password_change' %}">Change password</a> > + </tr> > + <tr> > + <th>API Token:</th> > + <td> > + {% if api_token %} > + <input id="token" style="width: 25em;" readonly value="{{ api_token }}"> > + <button type="button" class="btn-copy" title="Copy to clipboard" > + data-clipboard-target="#token">Copy</button> This doesn't work for me in Chrome: Uncaught ReferenceError: Clipboard is not defined at HTMLDocument.<anonymous> (py3.patchwork.dja.id.au/:26) at c (jquery-1.10.1.min.js:4) at Object.fireWith [as resolveWith] (jquery-1.10.1.min.js:4) at Function.ready (jquery-1.10.1.min.js:4) at HTMLDocument.q (jquery-1.10.1.min.js:4) The rest seems to work fine, I can create and use tokens (as far as I can tell - I haven't tried to do anything with the permissions they grant.) > + {% endif %} > + </td> > + <tr> > + <th></th> > + <td> > + <form method="post" action="{%url 'generate_token' %}"> That should probably be "{% url" -- a space between % and url. Regards, Daniel > + {% csrf_token %} > + {% if api_token %} > + <input type="submit" value="Regenerate token"/> > + {% else %} > + <input type="submit" value="Generate token"/> > + {% endif %} > + </form> > + </td> > + </tr> > +</table> > </div> > > </div> > diff --git a/patchwork/urls.py b/patchwork/urls.py > index be996c0..285d565 100644 > --- a/patchwork/urls.py > +++ b/patchwork/urls.py > @@ -235,6 +235,10 @@ if settings.ENABLE_REST_API: > > urlpatterns += [ > url(r'^api/(?:(?P<version>(1.0))/)?', include(api_patterns)), > + > + # token change > + url(r'^user/generate-token/$', user_views.generate_token, > + name='generate_token'), > ] > > > diff --git a/patchwork/views/user.py b/patchwork/views/user.py > index 375d3d9..d99fedf 100644 > --- a/patchwork/views/user.py > +++ b/patchwork/views/user.py > @@ -41,6 +41,7 @@ from patchwork.models import Person > from patchwork.models import Project > from patchwork.models import State > from patchwork.views import generic_list > +from patchwork.views import utils > > > def register(request): > @@ -126,6 +127,7 @@ def profile(request): > .extra(select={'is_optout': optout_query}) > context['linked_emails'] = people > context['linkform'] = EmailForm() > + context['api_token'] = request.user.profile.token > > return render(request, 'patchwork/profile.html', context) > > @@ -232,3 +234,9 @@ def todo_list(request, project_id): > context['action_required_states'] = \ > State.objects.filter(action_required=True).all() > return render(request, 'patchwork/todo-list.html', context) > + > + > +@login_required > +def generate_token(request): > + utils.regenerate_token(request.user) > + return HttpResponseRedirect(reverse('user-profile')) > -- > 2.9.4 > > _______________________________________________ > Patchwork mailing list > Patchwork@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/patchwork _______________________________________________ Patchwork mailing list Patchwork@lists.ozlabs.org https://lists.ozlabs.org/listinfo/patchwork