diff mbox series

models: Add commit_url_format to Project

Message ID 20190806122049.11455-1-mpe@ellerman.id.au
State Changes Requested
Headers show
Series models: Add commit_url_format to Project | expand

Commit Message

Michael Ellerman Aug. 6, 2019, 12:20 p.m. UTC
Add a new field to Project, commit_url_format, which specifies a
format string that can be used to generate a link to a particular
commit for a project.

This is used in the display of a patch, to render the patch's commit
as a clickable link back to the commit on the SCM website.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---

Passes tox tests.
Not entirely sure about the schema changes, I just cribbed from the
existing fields.
I think the use of mark_safe() is correct, but would appreciate some
review on that.
---
 docs/api/schemas/latest/patchwork.yaml        | 11 ++++++++++
 docs/api/schemas/patchwork.j2                 | 11 ++++++++++
 docs/api/schemas/v1.0/patchwork.yaml          | 11 ++++++++++
 docs/api/schemas/v1.1/patchwork.yaml          | 11 ++++++++++
 patchwork/api/embedded.py                     |  3 ++-
 patchwork/api/project.py                      |  4 ++--
 .../0034_project_commit_url_format.py         | 20 +++++++++++++++++++
 patchwork/models.py                           |  9 +++++++++
 patchwork/templates/patchwork/submission.html |  2 +-
 patchwork/templatetags/patch.py               | 12 +++++++++++
 10 files changed, 90 insertions(+), 4 deletions(-)
 create mode 100644 patchwork/migrations/0034_project_commit_url_format.py

Comments

Andrew Donnellan Aug. 6, 2019, 11:22 p.m. UTC | #1
On 6/8/19 10:20 pm, Michael Ellerman wrote:
> Add a new field to Project, commit_url_format, which specifies a
> format string that can be used to generate a link to a particular
> commit for a project.
> 
> This is used in the display of a patch, to render the patch's commit
> as a clickable link back to the commit on the SCM website.
> 
> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>

Argh, I've actually got a series of my own pending to do exactly this, 
just had to tidy up the documentation before sending it :)

I'll take a look at this and compare later today.

> ---
> 
> Passes tox tests.
> Not entirely sure about the schema changes, I just cribbed from the
> existing fields.
> I think the use of mark_safe() is correct, but would appreciate some
> review on that.
> ---
>   docs/api/schemas/latest/patchwork.yaml        | 11 ++++++++++
>   docs/api/schemas/patchwork.j2                 | 11 ++++++++++
>   docs/api/schemas/v1.0/patchwork.yaml          | 11 ++++++++++
>   docs/api/schemas/v1.1/patchwork.yaml          | 11 ++++++++++
>   patchwork/api/embedded.py                     |  3 ++-
>   patchwork/api/project.py                      |  4 ++--
>   .../0034_project_commit_url_format.py         | 20 +++++++++++++++++++
>   patchwork/models.py                           |  9 +++++++++
>   patchwork/templates/patchwork/submission.html |  2 +-
>   patchwork/templatetags/patch.py               | 12 +++++++++++
>   10 files changed, 90 insertions(+), 4 deletions(-)
>   create mode 100644 patchwork/migrations/0034_project_commit_url_format.py
> 
> diff --git a/docs/api/schemas/latest/patchwork.yaml b/docs/api/schemas/latest/patchwork.yaml
> index 724b05e..c9e6c4f 100644
> --- a/docs/api/schemas/latest/patchwork.yaml
> +++ b/docs/api/schemas/latest/patchwork.yaml
> @@ -1846,6 +1846,9 @@ openapi: '3.0.0'
>             type: string
>             format: uri
>             maxLength: 2000
> +        commit_url_format:
> +          title: Web SCM URL format for a particular commit
> +          type: string
>           maintainers:
>             type: array
>             items:
> @@ -2162,6 +2165,10 @@ openapi: '3.0.0'
>             format: uri
>             readOnly: true
>             maxLength: 2000
> +        commit_url_format:
> +          title: Web SCM URL format for a particular commit
> +          type: string
> +          readOnly: true
>       SeriesEmbedded:
>         type: object
>         properties:
> @@ -2301,6 +2308,10 @@ openapi: '3.0.0'
>             type: string
>             format: uri
>             readOnly: true
> +        commit_url_format:
> +          title: Web SCM URL format for a particular commit
> +          type: string
> +          readOnly: true
>       ErrorUserUpdate:
>         type: object
>         properties:
> diff --git a/docs/api/schemas/patchwork.j2 b/docs/api/schemas/patchwork.j2
> index 5e2f5e4..c0676f2 100644
> --- a/docs/api/schemas/patchwork.j2
> +++ b/docs/api/schemas/patchwork.j2
> @@ -1861,6 +1861,9 @@ openapi: '3.0.0'
>             type: string
>             format: uri
>             maxLength: 2000
> +        commit_url_format:
> +          title: Web SCM URL format for a particular commit
> +          type: string
>           maintainers:
>             type: array
>             items:
> @@ -2185,6 +2188,10 @@ openapi: '3.0.0'
>             format: uri
>             readOnly: true
>             maxLength: 2000
> +        commit_url_format:
> +          title: Web SCM URL format for a particular commit
> +          type: string
> +          readOnly: true
>       SeriesEmbedded:
>         type: object
>         properties:
> @@ -2326,6 +2333,10 @@ openapi: '3.0.0'
>             type: string
>             format: uri
>             readOnly: true
> +        commit_url_format:
> +          title: Web SCM URL format for a particular commit
> +          type: string
> +          readOnly: true
>       ErrorUserUpdate:
>         type: object
>         properties:
> diff --git a/docs/api/schemas/v1.0/patchwork.yaml b/docs/api/schemas/v1.0/patchwork.yaml
> index 02f3a15..370dffe 100644
> --- a/docs/api/schemas/v1.0/patchwork.yaml
> +++ b/docs/api/schemas/v1.0/patchwork.yaml
> @@ -1811,6 +1811,9 @@ openapi: '3.0.0'
>             type: string
>             format: uri
>             maxLength: 2000
> +        commit_url_format:
> +          title: Web SCM URL format for a particular commit
> +          type: string
>           maintainers:
>             type: array
>             items:
> @@ -2101,6 +2104,10 @@ openapi: '3.0.0'
>             format: uri
>             readOnly: true
>             maxLength: 2000
> +        commit_url_format:
> +          title: Web SCM URL format for a particular commit
> +          type: string
> +          readOnly: true
>       SeriesEmbedded:
>         type: object
>         properties:
> @@ -2235,6 +2242,10 @@ openapi: '3.0.0'
>             type: string
>             format: uri
>             readOnly: true
> +        commit_url_format:
> +          title: Web SCM URL format for a particular commit
> +          type: string
> +          readOnly: true
>       ErrorUserUpdate:
>         type: object
>         properties:
> diff --git a/docs/api/schemas/v1.1/patchwork.yaml b/docs/api/schemas/v1.1/patchwork.yaml
> index 0c086ed..778d10f 100644
> --- a/docs/api/schemas/v1.1/patchwork.yaml
> +++ b/docs/api/schemas/v1.1/patchwork.yaml
> @@ -1846,6 +1846,9 @@ openapi: '3.0.0'
>             type: string
>             format: uri
>             maxLength: 2000
> +        commit_url_format:
> +          title: Web SCM URL format for a particular commit
> +          type: string
>           maintainers:
>             type: array
>             items:
> @@ -2162,6 +2165,10 @@ openapi: '3.0.0'
>             format: uri
>             readOnly: true
>             maxLength: 2000
> +        commit_url_format:
> +          title: Web SCM URL format for a particular commit
> +          type: string
> +          readOnly: true
>       SeriesEmbedded:
>         type: object
>         properties:
> @@ -2301,6 +2308,10 @@ openapi: '3.0.0'
>             type: string
>             format: uri
>             readOnly: true
> +        commit_url_format:
> +          title: Web SCM URL format for a particular commit
> +          type: string
> +          readOnly: true
>       ErrorUserUpdate:
>         type: object
>         properties:
> diff --git a/patchwork/api/embedded.py b/patchwork/api/embedded.py
> index 60fb9a4..305594a 100644
> --- a/patchwork/api/embedded.py
> +++ b/patchwork/api/embedded.py
> @@ -158,7 +158,8 @@ from patchwork import models
>           class Meta:
>               model = models.Project
>               fields = ('id', 'url', 'name', 'link_name', 'list_id',
> -                      'list_email', 'web_url', 'scm_url', 'webscm_url')
> +                      'list_email', 'web_url', 'scm_url', 'webscm_url',
> +                      'commit_url_format')
>               read_only_fields = fields
>               extra_kwargs = {
>                   'url': {'view_name': 'api-project-detail'},
> diff --git a/patchwork/api/project.py b/patchwork/api/project.py
> index d7bb1f2..408e9db 100644
> --- a/patchwork/api/project.py
> +++ b/patchwork/api/project.py
> @@ -26,7 +26,7 @@ from patchwork.models import Project
>           model = Project
>           fields = ('id', 'url', 'name', 'link_name', 'list_id', 'list_email',
>                     'web_url', 'scm_url', 'webscm_url', 'maintainers',
> -                  'subject_match')
> +                  'subject_match', 'commit_url_format')
>           read_only_fields = ('name', 'link_name', 'list_id', 'list_email',
>                               'maintainers', 'subject_match')
>           versioned_fields = {
> @@ -68,7 +68,7 @@ from patchwork.models import Project
>       """List projects."""
>   
>       search_fields = ('link_name', 'list_id', 'list_email', 'web_url',
> -                     'scm_url', 'webscm_url')
> +                     'scm_url', 'webscm_url', 'commit_url_format')
>       ordering_fields = ('id', 'name', 'link_name', 'list_id')
>       ordering = 'id'
>   
> diff --git a/patchwork/migrations/0034_project_commit_url_format.py b/patchwork/migrations/0034_project_commit_url_format.py
> new file mode 100644
> index 0000000..4670674
> --- /dev/null
> +++ b/patchwork/migrations/0034_project_commit_url_format.py
> @@ -0,0 +1,20 @@
> +# -*- coding: utf-8 -*-
> +# Generated by Django 1.11.22 on 2019-08-06 21:16
> +from __future__ import unicode_literals
> +
> +from django.db import migrations, models
> +
> +
> +class Migration(migrations.Migration):
> +
> +    dependencies = [
> +        ('patchwork', '0033_remove_patch_series_model'),
> +    ]
> +
> +    operations = [
> +        migrations.AddField(
> +            model_name='project',
> +            name='commit_url_format',
> +            field=models.CharField(blank=True, help_text=b'SCM web URL for a particular commit. The string will be passed to str.format(), the commit SHA will be named "commit". Example format for cgit: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id={commit} or github: https://github.com/torvalds/linux/commit/{commit}', max_length=2000),
> +        ),
> +    ]
> diff --git a/patchwork/models.py b/patchwork/models.py
> index a7eee4d..fd2335e 100644
> --- a/patchwork/models.py
> +++ b/patchwork/models.py
> @@ -77,6 +77,15 @@ from patchwork.hasher import hash_diff
>       web_url = models.CharField(max_length=2000, blank=True)
>       scm_url = models.CharField(max_length=2000, blank=True)
>       webscm_url = models.CharField(max_length=2000, blank=True)
> +    commit_url_format = models.CharField(
> +        max_length=2000,
> +        blank=True,
> +        help_text='SCM web URL for a particular commit. The string will be '
> +        'passed to str.format(), the commit SHA will be named "commit". '
> +        'Example format for cgit: https://git.kernel.org/pub/scm/linux/'
> +        'kernel/git/torvalds/linux.git/commit/?id={commit} or github: '
> +        'https://github.com/torvalds/linux/commit/{commit}'
> +    )
>   
>       # configuration options
>   
> diff --git a/patchwork/templates/patchwork/submission.html b/patchwork/templates/patchwork/submission.html
> index b1ae542..ea673d1 100644
> --- a/patchwork/templates/patchwork/submission.html
> +++ b/patchwork/templates/patchwork/submission.html
> @@ -45,7 +45,7 @@ function toggle_div(link_id, headers_id)
>   {% if submission.commit_ref %}
>    <tr>
>     <th>Commit</th>
> -  <td>{{ submission.commit_ref }}</td>
> +  <td>{{ submission|patch_commit_display }}</td>
>    </tr>
>   {% endif %}
>   {% if submission.delegate %}
> diff --git a/patchwork/templatetags/patch.py b/patchwork/templatetags/patch.py
> index 757f873..628725d 100644
> --- a/patchwork/templatetags/patch.py
> +++ b/patchwork/templatetags/patch.py
> @@ -66,3 +66,15 @@ register = template.Library()
>   @stringfilter
>   def msgid(value):
>       return escape(value.strip('<>'))
> +
> +
> +@register.filter(name='patch_commit_display')
> +def patch_commit_display(patch):
> +    commit = escape(patch.commit_ref)
> +    if not patch.project.commit_url_format:
> +        return commit
> +
> +    # NB. This is safe because we escaped commit above and the format string
> +    # can only be set by an administrator.
> +    return mark_safe('<a href="%s">%s</a>' % (
> +        patch.project.commit_url_format.format(commit=commit), commit))
>
Andrew Donnellan Aug. 7, 2019, 12:30 a.m. UTC | #2
On 7/8/19 9:22 am, Andrew Donnellan wrote:
> On 6/8/19 10:20 pm, Michael Ellerman wrote:
>> Add a new field to Project, commit_url_format, which specifies a
>> format string that can be used to generate a link to a particular
>> commit for a project.
>>
>> This is used in the display of a patch, to render the patch's commit
>> as a clickable link back to the commit on the SCM website.
>>
>> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
> 
> Argh, I've actually got a series of my own pending to do exactly this, 
> just had to tidy up the documentation before sending it :)
> 
> I'll take a look at this and compare later today.

I correct myself, I have patches to add mailing list archive links, 
which is slightly different!

My series includes a minor bump to the API versioning, which per 
docs/development/releasing.rst is our policy when adding new fields. 
I'll tidy that up and send it and perhaps you can rebase your API 
changes on top of that?

> 
>> ---
>>
>> Passes tox tests.
>> Not entirely sure about the schema changes, I just cribbed from the
>> existing fields.
>> I think the use of mark_safe() is correct, but would appreciate some
>> review on that.
>> ---
>>   docs/api/schemas/latest/patchwork.yaml        | 11 ++++++++++
>>   docs/api/schemas/patchwork.j2                 | 11 ++++++++++
>>   docs/api/schemas/v1.0/patchwork.yaml          | 11 ++++++++++
>>   docs/api/schemas/v1.1/patchwork.yaml          | 11 ++++++++++
>>   patchwork/api/embedded.py                     |  3 ++-
>>   patchwork/api/project.py                      |  4 ++--
>>   .../0034_project_commit_url_format.py         | 20 +++++++++++++++++++
>>   patchwork/models.py                           |  9 +++++++++
>>   patchwork/templates/patchwork/submission.html |  2 +-
>>   patchwork/templatetags/patch.py               | 12 +++++++++++
>>   10 files changed, 90 insertions(+), 4 deletions(-)
>>   create mode 100644 
>> patchwork/migrations/0034_project_commit_url_format.py
>>
>> diff --git a/docs/api/schemas/latest/patchwork.yaml 
>> b/docs/api/schemas/latest/patchwork.yaml
>> index 724b05e..c9e6c4f 100644
>> --- a/docs/api/schemas/latest/patchwork.yaml
>> +++ b/docs/api/schemas/latest/patchwork.yaml
>> @@ -1846,6 +1846,9 @@ openapi: '3.0.0'
>>             type: string
>>             format: uri
>>             maxLength: 2000
>> +        commit_url_format:
>> +          title: Web SCM URL format for a particular commit
>> +          type: string
>>           maintainers:
>>             type: array
>>             items:
>> @@ -2162,6 +2165,10 @@ openapi: '3.0.0'
>>             format: uri
>>             readOnly: true
>>             maxLength: 2000
>> +        commit_url_format:
>> +          title: Web SCM URL format for a particular commit
>> +          type: string
>> +          readOnly: true
>>       SeriesEmbedded:
>>         type: object
>>         properties:
>> @@ -2301,6 +2308,10 @@ openapi: '3.0.0'
>>             type: string
>>             format: uri
>>             readOnly: true
>> +        commit_url_format:
>> +          title: Web SCM URL format for a particular commit
>> +          type: string
>> +          readOnly: true
>>       ErrorUserUpdate:
>>         type: object
>>         properties:
>> diff --git a/docs/api/schemas/patchwork.j2 
>> b/docs/api/schemas/patchwork.j2
>> index 5e2f5e4..c0676f2 100644
>> --- a/docs/api/schemas/patchwork.j2
>> +++ b/docs/api/schemas/patchwork.j2
>> @@ -1861,6 +1861,9 @@ openapi: '3.0.0'
>>             type: string
>>             format: uri
>>             maxLength: 2000
>> +        commit_url_format:
>> +          title: Web SCM URL format for a particular commit
>> +          type: string
>>           maintainers:
>>             type: array
>>             items:
>> @@ -2185,6 +2188,10 @@ openapi: '3.0.0'
>>             format: uri
>>             readOnly: true
>>             maxLength: 2000
>> +        commit_url_format:
>> +          title: Web SCM URL format for a particular commit
>> +          type: string
>> +          readOnly: true
>>       SeriesEmbedded:
>>         type: object
>>         properties:
>> @@ -2326,6 +2333,10 @@ openapi: '3.0.0'
>>             type: string
>>             format: uri
>>             readOnly: true
>> +        commit_url_format:
>> +          title: Web SCM URL format for a particular commit
>> +          type: string
>> +          readOnly: true
>>       ErrorUserUpdate:
>>         type: object
>>         properties:
>> diff --git a/docs/api/schemas/v1.0/patchwork.yaml 
>> b/docs/api/schemas/v1.0/patchwork.yaml
>> index 02f3a15..370dffe 100644
>> --- a/docs/api/schemas/v1.0/patchwork.yaml
>> +++ b/docs/api/schemas/v1.0/patchwork.yaml
>> @@ -1811,6 +1811,9 @@ openapi: '3.0.0'
>>             type: string
>>             format: uri
>>             maxLength: 2000
>> +        commit_url_format:
>> +          title: Web SCM URL format for a particular commit
>> +          type: string
>>           maintainers:
>>             type: array
>>             items:
>> @@ -2101,6 +2104,10 @@ openapi: '3.0.0'
>>             format: uri
>>             readOnly: true
>>             maxLength: 2000
>> +        commit_url_format:
>> +          title: Web SCM URL format for a particular commit
>> +          type: string
>> +          readOnly: true
>>       SeriesEmbedded:
>>         type: object
>>         properties:
>> @@ -2235,6 +2242,10 @@ openapi: '3.0.0'
>>             type: string
>>             format: uri
>>             readOnly: true
>> +        commit_url_format:
>> +          title: Web SCM URL format for a particular commit
>> +          type: string
>> +          readOnly: true
>>       ErrorUserUpdate:
>>         type: object
>>         properties:
>> diff --git a/docs/api/schemas/v1.1/patchwork.yaml 
>> b/docs/api/schemas/v1.1/patchwork.yaml
>> index 0c086ed..778d10f 100644
>> --- a/docs/api/schemas/v1.1/patchwork.yaml
>> +++ b/docs/api/schemas/v1.1/patchwork.yaml
>> @@ -1846,6 +1846,9 @@ openapi: '3.0.0'
>>             type: string
>>             format: uri
>>             maxLength: 2000
>> +        commit_url_format:
>> +          title: Web SCM URL format for a particular commit
>> +          type: string
>>           maintainers:
>>             type: array
>>             items:
>> @@ -2162,6 +2165,10 @@ openapi: '3.0.0'
>>             format: uri
>>             readOnly: true
>>             maxLength: 2000
>> +        commit_url_format:
>> +          title: Web SCM URL format for a particular commit
>> +          type: string
>> +          readOnly: true
>>       SeriesEmbedded:
>>         type: object
>>         properties:
>> @@ -2301,6 +2308,10 @@ openapi: '3.0.0'
>>             type: string
>>             format: uri
>>             readOnly: true
>> +        commit_url_format:
>> +          title: Web SCM URL format for a particular commit
>> +          type: string
>> +          readOnly: true
>>       ErrorUserUpdate:
>>         type: object
>>         properties:
>> diff --git a/patchwork/api/embedded.py b/patchwork/api/embedded.py
>> index 60fb9a4..305594a 100644
>> --- a/patchwork/api/embedded.py
>> +++ b/patchwork/api/embedded.py
>> @@ -158,7 +158,8 @@ from patchwork import models
>>           class Meta:
>>               model = models.Project
>>               fields = ('id', 'url', 'name', 'link_name', 'list_id',
>> -                      'list_email', 'web_url', 'scm_url', 'webscm_url')
>> +                      'list_email', 'web_url', 'scm_url', 'webscm_url',
>> +                      'commit_url_format')
>>               read_only_fields = fields
>>               extra_kwargs = {
>>                   'url': {'view_name': 'api-project-detail'},
>> diff --git a/patchwork/api/project.py b/patchwork/api/project.py
>> index d7bb1f2..408e9db 100644
>> --- a/patchwork/api/project.py
>> +++ b/patchwork/api/project.py
>> @@ -26,7 +26,7 @@ from patchwork.models import Project
>>           model = Project
>>           fields = ('id', 'url', 'name', 'link_name', 'list_id', 
>> 'list_email',
>>                     'web_url', 'scm_url', 'webscm_url', 'maintainers',
>> -                  'subject_match')
>> +                  'subject_match', 'commit_url_format')
>>           read_only_fields = ('name', 'link_name', 'list_id', 
>> 'list_email',
>>                               'maintainers', 'subject_match')
>>           versioned_fields = {
>> @@ -68,7 +68,7 @@ from patchwork.models import Project
>>       """List projects."""
>>       search_fields = ('link_name', 'list_id', 'list_email', 'web_url',
>> -                     'scm_url', 'webscm_url')
>> +                     'scm_url', 'webscm_url', 'commit_url_format')
>>       ordering_fields = ('id', 'name', 'link_name', 'list_id')
>>       ordering = 'id'
>> diff --git a/patchwork/migrations/0034_project_commit_url_format.py 
>> b/patchwork/migrations/0034_project_commit_url_format.py
>> new file mode 100644
>> index 0000000..4670674
>> --- /dev/null
>> +++ b/patchwork/migrations/0034_project_commit_url_format.py
>> @@ -0,0 +1,20 @@
>> +# -*- coding: utf-8 -*-
>> +# Generated by Django 1.11.22 on 2019-08-06 21:16
>> +from __future__ import unicode_literals
>> +
>> +from django.db import migrations, models
>> +
>> +
>> +class Migration(migrations.Migration):
>> +
>> +    dependencies = [
>> +        ('patchwork', '0033_remove_patch_series_model'),
>> +    ]
>> +
>> +    operations = [
>> +        migrations.AddField(
>> +            model_name='project',
>> +            name='commit_url_format',
>> +            field=models.CharField(blank=True, help_text=b'SCM web 
>> URL for a particular commit. The string will be passed to 
>> str.format(), the commit SHA will be named "commit". Example format 
>> for cgit: 
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id={commit} 
>> or github: https://github.com/torvalds/linux/commit/{commit}', 
>> max_length=2000),
>> +        ),
>> +    ]
>> diff --git a/patchwork/models.py b/patchwork/models.py
>> index a7eee4d..fd2335e 100644
>> --- a/patchwork/models.py
>> +++ b/patchwork/models.py
>> @@ -77,6 +77,15 @@ from patchwork.hasher import hash_diff
>>       web_url = models.CharField(max_length=2000, blank=True)
>>       scm_url = models.CharField(max_length=2000, blank=True)
>>       webscm_url = models.CharField(max_length=2000, blank=True)
>> +    commit_url_format = models.CharField(
>> +        max_length=2000,
>> +        blank=True,
>> +        help_text='SCM web URL for a particular commit. The string 
>> will be '
>> +        'passed to str.format(), the commit SHA will be named 
>> "commit". '
>> +        'Example format for cgit: https://git.kernel.org/pub/scm/linux/'
>> +        'kernel/git/torvalds/linux.git/commit/?id={commit} or github: '
>> +        'https://github.com/torvalds/linux/commit/{commit}'
>> +    )
>>       # configuration options
>> diff --git a/patchwork/templates/patchwork/submission.html 
>> b/patchwork/templates/patchwork/submission.html
>> index b1ae542..ea673d1 100644
>> --- a/patchwork/templates/patchwork/submission.html
>> +++ b/patchwork/templates/patchwork/submission.html
>> @@ -45,7 +45,7 @@ function toggle_div(link_id, headers_id)
>>   {% if submission.commit_ref %}
>>    <tr>
>>     <th>Commit</th>
>> -  <td>{{ submission.commit_ref }}</td>
>> +  <td>{{ submission|patch_commit_display }}</td>
>>    </tr>
>>   {% endif %}
>>   {% if submission.delegate %}
>> diff --git a/patchwork/templatetags/patch.py 
>> b/patchwork/templatetags/patch.py
>> index 757f873..628725d 100644
>> --- a/patchwork/templatetags/patch.py
>> +++ b/patchwork/templatetags/patch.py
>> @@ -66,3 +66,15 @@ register = template.Library()
>>   @stringfilter
>>   def msgid(value):
>>       return escape(value.strip('<>'))
>> +
>> +
>> +@register.filter(name='patch_commit_display')
>> +def patch_commit_display(patch):
>> +    commit = escape(patch.commit_ref)
>> +    if not patch.project.commit_url_format:
>> +        return commit
>> +
>> +    # NB. This is safe because we escaped commit above and the format 
>> string
>> +    # can only be set by an administrator.
>> +    return mark_safe('<a href="%s">%s</a>' % (
>> +        patch.project.commit_url_format.format(commit=commit), commit))
>>
>
Michael Ellerman Aug. 7, 2019, 1:14 p.m. UTC | #3
Andrew Donnellan <ajd@linux.ibm.com> writes:
> On 7/8/19 9:22 am, Andrew Donnellan wrote:
>> On 6/8/19 10:20 pm, Michael Ellerman wrote:
>>> Add a new field to Project, commit_url_format, which specifies a
>>> format string that can be used to generate a link to a particular
>>> commit for a project.
>>>
>>> This is used in the display of a patch, to render the patch's commit
>>> as a clickable link back to the commit on the SCM website.
>>>
>>> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
>> 
>> Argh, I've actually got a series of my own pending to do exactly this, 
>> just had to tidy up the documentation before sending it :)
>> 
>> I'll take a look at this and compare later today.
>
> I correct myself, I have patches to add mailing list archive links, 
> which is slightly different!

Phew!

> My series includes a minor bump to the API versioning, which per 
> docs/development/releasing.rst is our policy when adding new fields. 
> I'll tidy that up and send it and perhaps you can rebase your API 
> changes on top of that?

Sure, just let me know.

cheers
Daniel Axtens Aug. 22, 2019, 1:55 a.m. UTC | #4
Michael Ellerman <mpe@ellerman.id.au> writes:

> Andrew Donnellan <ajd@linux.ibm.com> writes:
>> On 7/8/19 9:22 am, Andrew Donnellan wrote:
>>> On 6/8/19 10:20 pm, Michael Ellerman wrote:
>>>> Add a new field to Project, commit_url_format, which specifies a
>>>> format string that can be used to generate a link to a particular
>>>> commit for a project.
>>>>
>>>> This is used in the display of a patch, to render the patch's commit
>>>> as a clickable link back to the commit on the SCM website.
>>>>
>>>> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
>>> 
>>> Argh, I've actually got a series of my own pending to do exactly this, 
>>> just had to tidy up the documentation before sending it :)
>>> 
>>> I'll take a look at this and compare later today.
>>
>> I correct myself, I have patches to add mailing list archive links, 
>> which is slightly different!
>
> Phew!
>
>> My series includes a minor bump to the API versioning, which per 
>> docs/development/releasing.rst is our policy when adding new fields. 
>> I'll tidy that up and send it and perhaps you can rebase your API 
>> changes on top of that?
>
> Sure, just let me know.

It looks like you're going to do a v2 anyway to mesh with Andrew's
changes - please could you pop in update to the fixtures that
demonstrates/exercises this? 

I've had a look at the mark_safe bit. I don't love it - it allows
someone with priv-esc to admin to XSS everyone who visits a patch
page. Having said that I'm not entirely sure what the best way to handle
it is. Andrew you did a few follow-up patches for our XSS adventures -
do you have any thoughts?

Regards,
Daniel

>
> cheers
> _______________________________________________
> Patchwork mailing list
> Patchwork@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/patchwork
Andrew Donnellan Aug. 22, 2019, 3:58 a.m. UTC | #5
On 22/8/19 11:55 am, Daniel Axtens wrote:
> It looks like you're going to do a v2 anyway to mesh with Andrew's
> changes - please could you pop in update to the fixtures that
> demonstrates/exercises this?
> 
> I've had a look at the mark_safe bit. I don't love it - it allows
> someone with priv-esc to admin to XSS everyone who visits a patch
> page. Having said that I'm not entirely sure what the best way to handle
> it is. Andrew you did a few follow-up patches for our XSS adventures -
> do you have any thoughts?

I think you probably want to wrap the 
patch.project.commit_url_format.format(commit=commit) in an escape.
diff mbox series

Patch

diff --git a/docs/api/schemas/latest/patchwork.yaml b/docs/api/schemas/latest/patchwork.yaml
index 724b05e..c9e6c4f 100644
--- a/docs/api/schemas/latest/patchwork.yaml
+++ b/docs/api/schemas/latest/patchwork.yaml
@@ -1846,6 +1846,9 @@  openapi: '3.0.0'
           type: string
           format: uri
           maxLength: 2000
+        commit_url_format:
+          title: Web SCM URL format for a particular commit
+          type: string
         maintainers:
           type: array
           items:
@@ -2162,6 +2165,10 @@  openapi: '3.0.0'
           format: uri
           readOnly: true
           maxLength: 2000
+        commit_url_format:
+          title: Web SCM URL format for a particular commit
+          type: string
+          readOnly: true
     SeriesEmbedded:
       type: object
       properties:
@@ -2301,6 +2308,10 @@  openapi: '3.0.0'
           type: string
           format: uri
           readOnly: true
+        commit_url_format:
+          title: Web SCM URL format for a particular commit
+          type: string
+          readOnly: true
     ErrorUserUpdate:
       type: object
       properties:
diff --git a/docs/api/schemas/patchwork.j2 b/docs/api/schemas/patchwork.j2
index 5e2f5e4..c0676f2 100644
--- a/docs/api/schemas/patchwork.j2
+++ b/docs/api/schemas/patchwork.j2
@@ -1861,6 +1861,9 @@  openapi: '3.0.0'
           type: string
           format: uri
           maxLength: 2000
+        commit_url_format:
+          title: Web SCM URL format for a particular commit
+          type: string
         maintainers:
           type: array
           items:
@@ -2185,6 +2188,10 @@  openapi: '3.0.0'
           format: uri
           readOnly: true
           maxLength: 2000
+        commit_url_format:
+          title: Web SCM URL format for a particular commit
+          type: string
+          readOnly: true
     SeriesEmbedded:
       type: object
       properties:
@@ -2326,6 +2333,10 @@  openapi: '3.0.0'
           type: string
           format: uri
           readOnly: true
+        commit_url_format:
+          title: Web SCM URL format for a particular commit
+          type: string
+          readOnly: true
     ErrorUserUpdate:
       type: object
       properties:
diff --git a/docs/api/schemas/v1.0/patchwork.yaml b/docs/api/schemas/v1.0/patchwork.yaml
index 02f3a15..370dffe 100644
--- a/docs/api/schemas/v1.0/patchwork.yaml
+++ b/docs/api/schemas/v1.0/patchwork.yaml
@@ -1811,6 +1811,9 @@  openapi: '3.0.0'
           type: string
           format: uri
           maxLength: 2000
+        commit_url_format:
+          title: Web SCM URL format for a particular commit
+          type: string
         maintainers:
           type: array
           items:
@@ -2101,6 +2104,10 @@  openapi: '3.0.0'
           format: uri
           readOnly: true
           maxLength: 2000
+        commit_url_format:
+          title: Web SCM URL format for a particular commit
+          type: string
+          readOnly: true
     SeriesEmbedded:
       type: object
       properties:
@@ -2235,6 +2242,10 @@  openapi: '3.0.0'
           type: string
           format: uri
           readOnly: true
+        commit_url_format:
+          title: Web SCM URL format for a particular commit
+          type: string
+          readOnly: true
     ErrorUserUpdate:
       type: object
       properties:
diff --git a/docs/api/schemas/v1.1/patchwork.yaml b/docs/api/schemas/v1.1/patchwork.yaml
index 0c086ed..778d10f 100644
--- a/docs/api/schemas/v1.1/patchwork.yaml
+++ b/docs/api/schemas/v1.1/patchwork.yaml
@@ -1846,6 +1846,9 @@  openapi: '3.0.0'
           type: string
           format: uri
           maxLength: 2000
+        commit_url_format:
+          title: Web SCM URL format for a particular commit
+          type: string
         maintainers:
           type: array
           items:
@@ -2162,6 +2165,10 @@  openapi: '3.0.0'
           format: uri
           readOnly: true
           maxLength: 2000
+        commit_url_format:
+          title: Web SCM URL format for a particular commit
+          type: string
+          readOnly: true
     SeriesEmbedded:
       type: object
       properties:
@@ -2301,6 +2308,10 @@  openapi: '3.0.0'
           type: string
           format: uri
           readOnly: true
+        commit_url_format:
+          title: Web SCM URL format for a particular commit
+          type: string
+          readOnly: true
     ErrorUserUpdate:
       type: object
       properties:
diff --git a/patchwork/api/embedded.py b/patchwork/api/embedded.py
index 60fb9a4..305594a 100644
--- a/patchwork/api/embedded.py
+++ b/patchwork/api/embedded.py
@@ -158,7 +158,8 @@  from patchwork import models
         class Meta:
             model = models.Project
             fields = ('id', 'url', 'name', 'link_name', 'list_id',
-                      'list_email', 'web_url', 'scm_url', 'webscm_url')
+                      'list_email', 'web_url', 'scm_url', 'webscm_url',
+                      'commit_url_format')
             read_only_fields = fields
             extra_kwargs = {
                 'url': {'view_name': 'api-project-detail'},
diff --git a/patchwork/api/project.py b/patchwork/api/project.py
index d7bb1f2..408e9db 100644
--- a/patchwork/api/project.py
+++ b/patchwork/api/project.py
@@ -26,7 +26,7 @@  from patchwork.models import Project
         model = Project
         fields = ('id', 'url', 'name', 'link_name', 'list_id', 'list_email',
                   'web_url', 'scm_url', 'webscm_url', 'maintainers',
-                  'subject_match')
+                  'subject_match', 'commit_url_format')
         read_only_fields = ('name', 'link_name', 'list_id', 'list_email',
                             'maintainers', 'subject_match')
         versioned_fields = {
@@ -68,7 +68,7 @@  from patchwork.models import Project
     """List projects."""
 
     search_fields = ('link_name', 'list_id', 'list_email', 'web_url',
-                     'scm_url', 'webscm_url')
+                     'scm_url', 'webscm_url', 'commit_url_format')
     ordering_fields = ('id', 'name', 'link_name', 'list_id')
     ordering = 'id'
 
diff --git a/patchwork/migrations/0034_project_commit_url_format.py b/patchwork/migrations/0034_project_commit_url_format.py
new file mode 100644
index 0000000..4670674
--- /dev/null
+++ b/patchwork/migrations/0034_project_commit_url_format.py
@@ -0,0 +1,20 @@ 
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.22 on 2019-08-06 21:16
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('patchwork', '0033_remove_patch_series_model'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='project',
+            name='commit_url_format',
+            field=models.CharField(blank=True, help_text=b'SCM web URL for a particular commit. The string will be passed to str.format(), the commit SHA will be named "commit". Example format for cgit: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id={commit} or github: https://github.com/torvalds/linux/commit/{commit}', max_length=2000),
+        ),
+    ]
diff --git a/patchwork/models.py b/patchwork/models.py
index a7eee4d..fd2335e 100644
--- a/patchwork/models.py
+++ b/patchwork/models.py
@@ -77,6 +77,15 @@  from patchwork.hasher import hash_diff
     web_url = models.CharField(max_length=2000, blank=True)
     scm_url = models.CharField(max_length=2000, blank=True)
     webscm_url = models.CharField(max_length=2000, blank=True)
+    commit_url_format = models.CharField(
+        max_length=2000,
+        blank=True,
+        help_text='SCM web URL for a particular commit. The string will be '
+        'passed to str.format(), the commit SHA will be named "commit". '
+        'Example format for cgit: https://git.kernel.org/pub/scm/linux/'
+        'kernel/git/torvalds/linux.git/commit/?id={commit} or github: '
+        'https://github.com/torvalds/linux/commit/{commit}'
+    )
 
     # configuration options
 
diff --git a/patchwork/templates/patchwork/submission.html b/patchwork/templates/patchwork/submission.html
index b1ae542..ea673d1 100644
--- a/patchwork/templates/patchwork/submission.html
+++ b/patchwork/templates/patchwork/submission.html
@@ -45,7 +45,7 @@  function toggle_div(link_id, headers_id)
 {% if submission.commit_ref %}
  <tr>
   <th>Commit</th>
-  <td>{{ submission.commit_ref }}</td>
+  <td>{{ submission|patch_commit_display }}</td>
  </tr>
 {% endif %}
 {% if submission.delegate %}
diff --git a/patchwork/templatetags/patch.py b/patchwork/templatetags/patch.py
index 757f873..628725d 100644
--- a/patchwork/templatetags/patch.py
+++ b/patchwork/templatetags/patch.py
@@ -66,3 +66,15 @@  register = template.Library()
 @stringfilter
 def msgid(value):
     return escape(value.strip('<>'))
+
+
+@register.filter(name='patch_commit_display')
+def patch_commit_display(patch):
+    commit = escape(patch.commit_ref)
+    if not patch.project.commit_url_format:
+        return commit
+
+    # NB. This is safe because we escaped commit above and the format string
+    # can only be set by an administrator.
+    return mark_safe('<a href="%s">%s</a>' % (
+        patch.project.commit_url_format.format(commit=commit), commit))