1package App::Acmeman::Domain; 2 3use strict; 4use warnings; 5use Carp; 6use Clone; 7 8require Exporter; 9our @ISA = qw(Exporter); 10our @EXPORT_OK = qw(CERT_FILE KEY_FILE CA_FILE); 11our %EXPORT_TAGS = ( files => [ qw(CERT_FILE KEY_FILE CA_FILE) ] ); 12 13use constant { 14 CERT_FILE => 0, 15 KEY_FILE => 1, 16 CA_FILE => 2 17}; 18 19sub uniq { 20 my %h; 21 map { 22 if (exists($h{$_})) { 23 () 24 } else { 25 $h{$_} = 1; 26 $_ 27 } 28 } @_; 29} 30 31sub new { 32 my ($class, %args) = @_; 33 34 my $self = bless { }, $class; 35 my $v; 36 37 if ($v = delete $args{cn}) { 38 $self->{_cn} = lc $v; 39 } 40 if ($v = delete $args{alt}) { 41 if (ref($v) eq 'ARRAY') { 42 $self->{_alt} = [ uniq(map { lc } @$v) ]; 43 } else { 44 $self->{_alt} = [ lc $v ]; 45 } 46 } 47 if ($v = delete $args{type}) { 48 $self->{_cert_type} = $v; 49 } 50 if (($v = delete $args{certificate_file}) 51 || ($v = delete $args{'certificate-file'})) { 52 $self->{_file}[CERT_FILE] = $v; 53 } 54 if (($v = delete $args{ca_file}) 55 || ($v = delete $args{'ca-file'})) { 56 $self->{_file}[CA_FILE] = $v; 57 } 58 if (($v = delete $args{key_file}) 59 || ($v = delete $args{'key-file'})) { 60 $self->{_file}[KEY_FILE] = $v; 61 } 62 63 $v = delete($args{argument}) || '$domain'; 64 $v =~ s{\$}{\\\$}; 65 $self->{_argument} = qr($v); 66 67 $self->{_postrenew} = delete $args{'postrenew'}; 68 69 croak "unrecognized arguments" if keys %args; 70 return $self; 71} 72 73sub names { 74 my $self = shift; 75 if (wantarray) { 76 return ($self->cn, $self->alt); 77 } else { 78 return $self->alt() + 1; 79 } 80} 81 82sub contains { 83 my $self = shift; 84 my $val = lc shift; 85 return grep { $_ eq $val } $self->names; 86} 87 88sub _domain_cmp { 89 my ($a,$b) = @_; 90 91 carp "righthand-side argument should be a App::Acmeman::Domain" 92 unless $b->isa('App::Acmeman::Domain'); 93 return $a->{_cn} cmp $b->{_cn}; 94} 95 96sub _domain_plus { 97 my ($a, $b) = @_; 98 99 carp "righthand-side argument should be a App::Acmeman::Domain" 100 unless $b->isa('App::Acmeman::Domain'); 101 102 $a = Clone::clone($a); 103 push @{$a->{_alt}}, $b->cn 104 unless $a->contains($b->cn); 105 @{$a->{_alt}} = uniq($a->alt, $b->alt); 106 return $a; 107} 108 109use overload 110 cmp => \&_domain_cmp, 111 '+' => \&_domain_plus, 112 '""' => sub { $_[0]->cn }; 113 114sub cn { 115 my $self = shift; 116 return $self->{_cn}; 117} 118 119sub alt { 120 my $self = shift; 121 if (wantarray) { 122 return exists($self->{_alt}) ? (@{$self->{_alt}}) : (); 123 } else { 124 return exists($self->{_alt}) ? (0+@{$self->{_alt}}) : 0; 125 } 126} 127 128sub file { 129 my ($self, $type) = @_; 130 return undef unless exists($self->{_file}[$type]); 131 my $res = $self->{_file}[$type]; 132 $res =~ s{$self->{_argument}}{$self->cn}ge; 133 return $res; 134} 135 136sub certificate_file { 137 my $self = shift; 138 return $self->file(CERT_FILE); 139} 140 141sub postrenew { 142 my $self = shift; 143 return $self->{_postrenew} 144} 145 1461; 147 148