File Coverage

blib/lib/Software/Security/Policy/Individual.pm
Criterion Covered Total %
statement 51 64 79.6
branch 19 34 55.8
condition 4 9 44.4
subroutine 21 25 84.0
pod 15 15 100.0
total 110 147 74.8


line stmt bran cond sub pod time code
1 2     2   682026 use strict;
  2         6  
  2         135  
2 2     2   14 use warnings;
  2         5  
  2         204  
3             package Software::Security::Policy::Individual;
4              
5             our $VERSION = '0.11'; # VERSION
6              
7 2     2   21 use parent 'Software::Security::Policy';
  2         4  
  2         23  
8             # ABSTRACT: The Individual Security Policy
9              
10 2     2   1334 use Data::Section -setup => { header_re => qr/\A__([^_]+)__\Z/ };
  2         45057  
  2         28  
11 2     2   3614 use Text::Template ();
  2         10543  
  2         2599  
12              
13 4     4 1 38 sub name { 'individual' }
14              
15              
16             sub new {
17 6     6 1 5456 my ($class, $arg) = @_;
18              
19 6 50       35 Carp::croak "no maintainer is specified" unless $arg->{maintainer};
20              
21 6         42 bless $arg => $class;
22             }
23              
24              
25             sub url { (defined $_[0]->{url} ? $_[0]->{url} :
26             (defined $_[0]->{git_url} ? $_[0]->{git_url} :
27 0 0   0 1 0 undef)) }
    0          
28              
29             sub git_url { (defined $_[0]->{git_url} ? $_[0]->{git_url} :
30             (defined $_[0]->{url} ? $_[0]->{url} :
31 24 100   24 1 114 undef)) }
    100          
32              
33              
34 16     16 1 57 sub perl_support_years { $_[0]->{perl_support_years} };
35              
36 16     16 1 71 sub minimum_perl_version { $_[0]->{minimum_perl_version} }
37              
38             sub timeframe {
39 16 100   16 1 1309 return $_[0]->{timeframe} if defined $_[0]->{timeframe};
40             return $_[0]->{timeframe_quantity} . ' ' . $_[0]->{timeframe_units}
41             if defined $_[0]->{timeframe_quantity} &&
42 8 100 66     53 defined $_[0]->{timeframe_units};
43 6         44 return '5 days';
44             }
45              
46 28     28 1 271 sub maintainer { $_[0]->{maintainer} }
47              
48             sub _dotless_maintainer {
49 0     0   0 my $maintainer = $_[0]->maintainer;
50 0         0 $maintainer =~ s/\.$//;
51 0         0 return $maintainer;
52             }
53              
54 32     32 1 138 sub report_url { $_[0]->{report_url} }
55              
56              
57 224 50 66 224 1 82028 sub program { $_[0]->{program} || $_[0]->{Program} || 'this program' }
58              
59              
60 0 0 0 0 1 0 sub Program { $_[0]->{Program} || $_[0]->{program} || 'This program' }
61              
62              
63 16     16 1 47 sub summary { shift->_fill_in('SUMMARY') }
64              
65              
66 16     16 1 1456 sub security_policy { shift->_fill_in('SECURITY-POLICY') }
67              
68              
69             sub fulltext {
70 16     16 1 10156 my ($self) = @_;
71 16         51 return join "\n", $self->summary, $self->security_policy;
72             }
73              
74              
75             sub version {
76 0     0 1 0 my ($self) = @_;
77 0 0       0 my $pkg = ref $self ? ref $self : $self;
78 0         0 $pkg =~ s/.+:://;
79 0         0 my (undef, @vparts) = split /_/, $pkg;
80              
81 0 0       0 return unless @vparts;
82 0         0 return join '.', @vparts;
83             }
84              
85             sub _fill_in {
86 32     32   115 my ($self, $which) = @_;
87              
88 32 50       110 Carp::confess "couldn't build $which section" unless
89             my $template = $self->section_data($which);
90              
91 32         22140 return Text::Template->fill_this_in(
92             $$template,
93             HASH => { self => \$self },
94             DELIMITERS => [ qw({{ }}) ],
95             );
96             }
97              
98             sub _perl_supported_version_section {
99 16     16   1224 my $self = shift;
100 16         39 my $program = $self->program;
101 16 50       77 if (my $minimum_perl_version = $self->minimum_perl_version) {
    100          
102 0         0 return <
103              
104             Note that the $program project only supports major versions of Perl since
105             $minimum_perl_version, even though $program will run on
106             older versions of Perl. If a security fix requires us to increase
107             the minimum version of Perl that is supported, then we may do so.
108             EOF
109             } elsif (my $perl_support_years = $self->perl_support_years) {
110             return <
111              
112             Note that the $program project only supports major versions of Perl
113             released in the past $perl_support_years years, even though $program will run on
114             older versions of Perl. If a security fix requires us to increase
115             the minimum version of Perl that is supported, then we may do so.
116             EOF
117 14         126 } else {
118 2         17 return '';
119             }
120             }
121             sub _latest_policy_location {
122 16     16   1442 my $self = shift;
123 16         57 my $git_url = $self->git_url;
124 16         58 my $program = $self->program;
125 16 100       47 if (defined $git_url) {
126 8         71 return <
127              
128             The latest version of the Security Policy can be found in the
129             [git repository for $program]($git_url).
130             EOF
131             } else {
132 8         74 return '';
133             }
134             }
135              
136             sub _how_to_report {
137 32     32   2816 my $self = shift;
138 32 100       91 if ( my $url = $self->report_url ) {
139 8 50       20 if ( $url eq $self->git_url . "/security/advisories" ) {
140 8         65 return "via the project\n[Security Advisories](${url})";
141             }
142             else {
143 0         0 return "using " . $url;
144             }
145             }
146             else {
147 24         65 return "by email to " . $self->maintainer;
148             }
149             }
150              
151              
152             1;
153              
154             =pod
155              
156             =encoding UTF-8
157              
158             =head1 NAME
159              
160             Software::Security::Policy::Individual - The Individual Security Policy
161              
162             =head1 VERSION
163              
164             version 0.11
165              
166             =head1 SYNOPSIS
167              
168             use strict;
169             use warnings;
170              
171             use Software::Security::Policy::Individual;
172              
173             my $policy = Software::Security::Policy::Individual->new({
174             maintainer => 'Timothy Legge ', # required
175             program => 'Software::Security::Policy',
176             timeframe => '7 days',
177             url => 'https://github.com/CPAN-Security/Software-Security-Policy/blob/main/SECURITY.md',
178             perl_support_years => '10',
179             });
180              
181             print $policy->fulltext, "\n";
182              
183             =head1 METHODS
184              
185             =over
186              
187             =item new
188              
189             my $policy = $subclass->new(\%arg);
190              
191             This method returns a new security policy object for the given
192             security policy class. Valid arguments are:
193              
194             =back
195              
196             =head2 ATTRIBUTES
197              
198             =over
199              
200             =item maintainer
201              
202             the current maintainer for the distibrution; B
203              
204             =item timeframe
205              
206             the time to expect acknowledgement of a security issue. Should
207             include the units such as '5 days or 2 weeks';
208              
209             Default: 5 days
210              
211             =item timeframe_quantity
212              
213             the amount of time to expect an acknowledgement of a security issue.
214             Only used if timeframe is undefined and timeframe_units is defined
215             (eg. '5')
216              
217             =item timeframe_units
218              
219             the units of time to expect an acknowledgement of a security issue.
220             Only used if timeframe is undefined and timeframe_quantity is defined
221             (eg. 'days')
222              
223             =item url
224              
225             a url where the most current security policy can be found.
226              
227             =item git_url
228              
229             a git url where the most current security policy can be found.
230              
231             =item report_url
232              
233             the URL where you can report security issues.
234              
235             =item perl_support_years
236              
237             the number of years for which past major versions of Perl would be
238             supported
239              
240             =item program
241              
242             the name of software for use in the middle of a sentence
243              
244             =item Program
245              
246             the name of software for use in the beginning of a sentence
247              
248             C and C arguments may be specified both, either one or none.
249             Each argument, if not specified, is defaulted to another one, or to properly
250             capitalized "this program", if both arguments are omitted.
251              
252             =back
253              
254             =head2 minimum_perl_version
255              
256             The minimum version of perl that is supported.
257              
258             =head2 perl_support_years
259              
260             Get the number of years for which past major versions of Perl would be
261             supported.
262              
263             =head2 timeframe
264              
265             Get the expected response time. Defaults to 5 days and uses
266             timeframe_quantity and timeframe_units if the timeframe attribute
267             us undefined.
268              
269             =head2 maintainer
270              
271             Get the maintainer that should be contacted for security issues.
272              
273             =head2 report_url
274              
275             Get the URL where you can report security issues.
276              
277             These methods are attribute readers.
278              
279             =head2 program
280              
281             Name of software for using in the middle of a sentence.
282              
283             The method returns value of C constructor argument (if it evaluates as true, i. e.
284             defined, non-empty, non-zero), or value of C constructor argument (if it is true), or
285             "this program" as the last resort.
286              
287             Default: 'this program'
288              
289             =head2 Program
290              
291             Name of software for using at the beginning of a sentence.
292              
293             The method returns value of C constructor argument (if it is true), or value of C
294             constructor argument (if it is true), or "This program" as the last resort.
295              
296             Default: 'This program'
297              
298             =head2 name
299              
300             This method returns the name of the policy, suitable for shoving in the middle
301             of a sentence, generally with a leading capitalized "The."
302              
303             =head2 url
304              
305             This method returns the URL at which a canonical text of the security policy can be
306             found, if one is available. If possible, this will point at plain text, but it
307             may point to an HTML resource.
308              
309             =head2 git_url
310              
311             This method returns the git URL at which a canonical text of the security policy can be
312             found, if one is available. If possible, this will point at plain text, but it
313             may point to an HTML resource.
314              
315             =head2 summary
316              
317             This method returns a snippet of text, usually a few lines, indicating the
318             maintainer as well as an indication of the policy under which the software
319             is maintained.
320              
321             =head2 security_policy
322              
323             This method returns the full text of the policy.
324              
325             =head2 fulltext
326              
327             This method returns the complete text of the policy.
328              
329             =head2 version
330              
331             This method returns the version of the policy. If the security
332             policy is not versioned, this method will return undefined.
333              
334             =head1 AUTHOR
335              
336             Timothy Legge
337              
338             =head1 COPYRIGHT AND LICENSE
339              
340             This software is copyright (c) 2025 by Timothy Legge .
341              
342             This is free software; you can redistribute it and/or modify it under
343             the same terms as the Perl 5 programming language system itself.
344              
345             =cut
346              
347             __DATA__