File Coverage

blib/lib/TiddlyWeb/Resting/DefaultRester.pm
Criterion Covered Total %
statement 12 66 18.1
branch 0 32 0.0
condition 0 17 0.0
subroutine 4 9 44.4
pod 1 1 100.0
total 17 125 13.6


line stmt bran cond sub pod time code
1             package TiddlyWeb::Resting::DefaultRester;
2 1     1   1358 use strict;
  1         2  
  1         43  
3 1     1   6 use warnings;
  1         2  
  1         34  
4 1     1   6 use TiddlyWeb::Resting;
  1         1  
  1         64  
5 1     1   1132 use Sys::Hostname qw/hostname/;
  1         1664  
  1         1222  
6              
7             =head1 NAME
8              
9             TiddlyWeb::Resting::DefaultRester - load a rester from a config file.
10              
11             =cut
12              
13             our $VERSION = '0.02';
14              
15             =head1 SYNOPSIS
16              
17             Load server, workspace and username from a file, so you don't need to
18             specify that for every program using TiddlyWeb::Resting.
19              
20             use TiddlyWeb::Resting::DefaultRester;
21              
22             my $rester = TiddlyWeb::Resting::DefaultRester->new;
23             print $rester->get_page('Foo');
24              
25             =head1 FUNCTIONS
26              
27             =head2 new
28              
29             Create a new Default Rester by using values from ~/.wikeditrc.
30              
31             =head3 Options:
32              
33             =over 4
34              
35             =item rester-config
36              
37             File to use as the config file. Defaults to $ENV{HOME}/.wikeditrc.
38              
39             =item class
40              
41             Specifies the rester class to use. Defaults to L.
42              
43             =item *
44              
45             All other args are passed through to the rester class's new().
46              
47             =back
48              
49             =head3 Rester Config File
50              
51             The config file is expected to be in the following format:
52              
53             server = your-server
54             workspace = some-workspace
55             username = your-user
56             password = your-password
57              
58             Your password will become crypted the first time it is loaded if Crypt::CBC
59             is installed.
60              
61             Alternately, you can use this format:
62              
63             server = your-server
64             workspace = some-workspace
65             user_cookie = an-NLW-user-cookie
66              
67             =cut
68              
69             my $home = $ENV{HOME} || "~";
70             our $CONFIG_FILE = "$home/.wikeditrc";
71              
72             sub new {
73 0     0 1   my $class = shift;
74 0           my %args = (@_);
75 0           for my $k (keys %args) {
76 0 0         delete $args{$k} unless defined $args{$k};
77             }
78              
79 0   0       my $config_file = delete $args{'rester-config'} || $CONFIG_FILE;
80 0           my %opts = (
81             _load_config($config_file),
82             %args,
83             );
84 0   0       my $rest_class = delete $opts{class} || 'TiddlyWeb::Resting';
85 0           eval "require $rest_class";
86 0 0         die if $@;
87 0           return $rest_class->new(%opts);
88             }
89              
90             sub _load_config {
91 0     0     my $file = shift;
92 0           my $second_try = shift;
93              
94 0 0         unless (-e $file) {
95 0 0         open(my $fh, ">$file") or die "Can't open $file: $!";
96 0           print $fh <
97             server = http://tiddlyweb.peermore.com/wiki
98             workspace = docs
99             username =
100             password =
101             EOT
102 0 0         close $fh or die "Couldn't write basic config to $file: $!";
103 0           warn "Created an initial wiki config file in $file.\n";
104             }
105              
106 0           my %opts;
107 0 0         open(my $fh, $file) or die "Can't open $file: $!";
108 0           while(<$fh>) {
109 0 0         if (/^(\w+)\s*=\s*(\S+)\s*$/) {
110 0           my ($key, $val) = (lc($1), $2);
111 0 0         $val =~ s#/$## if $key eq 'server';
112 0           $opts{$key} = $val;
113             }
114             }
115              
116 0           my $pw = $opts{password};
117 0 0 0       if (!$second_try and -w $file and $pw and $pw !~ /^CRYPTED_/) {
      0        
      0        
118 0 0         _change_password($file, $opts{password})
119             or return _load_config($file, 'i already tried once');
120             }
121              
122 0 0 0       if ($opts{password} and $opts{password} =~ m/^CRYPTED_(.+)/) {
123 0           eval 'require Crypt::CBC';
124 0 0         if ($@) {
125 0           delete $opts{password};
126             }
127             else {
128 0           my $new_pw = _decrypt($1);
129 0           $opts{password} = $new_pw;
130             }
131             }
132 0           return %opts;
133             }
134              
135             sub _change_password {
136 0     0     my $file = shift;
137 0           eval 'require Crypt::CBC';
138 0 0         return 0 if $@;
139              
140 0           my $old_pw = shift;
141              
142 0           my $new_pw = 'CRYPTED_' . _encrypt($old_pw);
143              
144 0           local $/ = undef;
145 0 0         open(my $fh, $file) or die "Can't open $file: $!";
146 0           my $contents = <$fh>;
147 0           $contents =~ s/password\s*=\s*\Q$old_pw\E/password = $new_pw/m;
148 0           close $fh;
149 0 0         open(my $wfh, ">$file") or die "Can't open $file for writing: $!";
150 0           print $wfh $contents;
151 0 0         close $wfh or die "Can't write $file: $!";
152 0           return 1;
153             }
154              
155             sub _encrypt {
156 0     0     my $from = shift;
157 0           my $crypt = Crypt::CBC->new(
158             -key => hostname(),
159             -salt => 1,
160             -header => 'salt',
161             );
162 0           return $crypt->encrypt_hex($from);
163             }
164              
165             sub _decrypt {
166 0     0     my $from = shift;
167 0           my $crypt = Crypt::CBC->new(
168             -key => hostname(),
169             -salt => 1,
170             -header => 'salt',
171             );
172 0           return $crypt->decrypt_hex($from);
173             }
174              
175             =head1 AUTHOR
176              
177             Luke Closs, C<< >>
178              
179             =head1 BUGS
180              
181             Please report any bugs or feature requests to
182             C, or through the web interface at
183             L.
184             I will be notified, and then you'll automatically be notified of progress on
185             your bug as I make changes.
186              
187             =head1 SUPPORT
188              
189             You can find documentation for this module with the perldoc command.
190              
191             perldoc Socialtext::Resting::DefaultRester
192              
193             You can also look for information at:
194              
195             =over 4
196              
197             =item * AnnoCPAN: Annotated CPAN documentation
198              
199             L
200              
201             =item * CPAN Ratings
202              
203             L
204              
205             =item * RT: CPAN's request tracker
206              
207             L
208              
209             =item * Search CPAN
210              
211             L
212              
213             =back
214              
215             =head1 ACKNOWLEDGEMENTS
216              
217             =head1 COPYRIGHT & LICENSE
218              
219             Copyright 2006 Luke Closs, all rights reserved.
220              
221             This program is free software; you can redistribute it and/or modify it
222             under the same terms as Perl itself.
223              
224             =cut
225              
226             1;