source: trunk/LATMOS-Accounts-Web/lib/LATMOS/Accounts/Web/Model/AttrForms.pm @ 1225

Last change on this file since 1225 was 1225, checked in by nanardon, 11 years ago

Add ssh fp support

This patch add support for SSH finger print DNS support. Nethost have now an
sshfp attribute to hold fingerprint. The fingerprint are added into DNS zones

This patch also make 'checkzone' test optional and not enable by default.

File size: 17.4 KB
Line 
1package LATMOS::Accounts::Web::Model::AttrForms;
2
3use strict;
4use warnings;
5use base 'Catalyst::Model';
6use LATMOS::Accounts::Log;
7use HTML::Prototype;
8
9=head1 NAME
10
11LATMOS::Accounts::Web::Model::AttrForms - Catalyst Model
12
13=head1 DESCRIPTION
14
15Catalyst Model.
16
17=cut
18
19my $forms = {
20    usersys => {
21        name => 'SystÚme',
22        attrs => [ qw(
23            sn givenName description
24            uid uidNumber gidNumber gecos homeDirectory loginShell
25            mail initials nickname
26            expire
27            locked
28            create
29            date
30        ) ],
31    },
32    user => {
33        name => 'Statut',
34        attrs => [ qw(
35            sn givenName description
36            company
37            department
38            manager
39            managerContact
40            contratType
41            expire
42            snNative
43            givenNameNative
44            wWWHomePage
45            halReference
46            create
47            date
48        ) ],
49    },
50    useraddress => {
51        name => 'Adresse',
52        attrs => [ qw(
53            initials
54            mail
55        ) ],
56    },
57    usermy => {
58        name => 'My',
59        attrs => [ qw(
60            snNative
61            givenNameNative
62            wWWHomePage
63            halReference
64        ) ],
65    },
66    site => {
67        name => 'Site',
68        attrs => [ qw(
69            description
70            siteNick
71            streetAddress
72            postOfficeBox
73            postalCode
74            l
75            st
76            co
77            facsimileTelephoneNumber
78            create
79            date
80        ) ],
81    },
82    address => {
83        name => 'Adresse',
84        attrs => [ qw(
85            isMainAddress
86            telephoneNumber
87            streetAddress
88            postOfficeBox
89            postalCode
90            l
91            st
92            physicalDeliveryOfficeName
93            site
94            co
95            unexported
96            description
97        ) ],
98    },
99    group => {
100        name => 'SystÚme',
101        attrs => [ qw(
102            gidNumber description
103            managedBy
104            managedAlsoBy
105            autoMemberFilter
106            sutype
107            create
108            date
109        ) ],
110    },
111    nethost => {
112        name => 'Ordinateur',
113        attrs => [ qw(
114            name
115            description
116            serialNumber
117            owner
118            user
119            ip
120            macaddr
121            puppetClass
122            noInheritPuppet
123            noDynamic
124            cname
125            otherName
126            reverse
127            create
128            date
129            unexported
130            sshfp
131        ) ],
132    },
133    netzone => {
134        name => 'Zone réseau',
135        attrs => [ qw(
136            name
137            description
138            type
139            net
140            netExclude
141            puppetClass
142            outputD
143            templateD
144            site
145            allow_dyn
146            dynFrom
147            domain
148            ipCount
149            freeIPCount
150            create
151            date
152            dnsRevision
153            lastUpdate
154            unexported
155        ) ],
156    },
157    aliases => {
158        name => 'Alias mail',
159        attrs => [ qw(
160            forward
161            expire
162            finalpoint
163            parents
164            created
165            date
166            unexported
167        )],
168    },
169};
170
171sub escape {
172    my ($self, $text) = @_;
173    $text ||= '';
174    for ($text) {
175        s/&/&/g;
176        s/</&lt;/g;
177        s/>/&gt;/g;
178        s/"/&quot;/g;
179    }
180    $text;
181}
182
183sub new {
184    my ($class) = @_;
185    bless({}, $class);
186}
187
188# call either OBJ or type + base
189
190sub ACCEPT_CONTEXT {
191    my ($self, $c, $form, $object, $base) = @_;
192    my $new = {};
193    $new->{c} = $c;
194    $new->{form} = $form;
195    $new->{object} = $object if (ref $object);
196    $new->{base} = $base || (ref $object ? $object->base : undef) or return $self;
197    $new->{otype} = ref $object ? $object->type : $object;
198    bless($new, __PACKAGE__);
199}
200
201sub base {
202    my ( $self ) = @_;
203    $self->{base}
204}
205
206sub otype {
207    my ($self) = @_;
208    $self->{otype};
209}
210
211sub label {
212    my ($self) = @_;
213    $forms->{$self->{form}}->{name} || ''
214}
215
216sub attributes {
217    my ($self, $for) = @_;
218    grep { $_ }
219    grep { $self->base->attribute($self->otype, $_) }
220    @{ $forms->{$self->{form}}->{attrs} };
221}
222
223sub attr_label {
224    my ($self, $attr, $label, $hint) = @_;
225    $label ||= '';
226    $hint ||= '';
227    LATMOS::Accounts::Web->config->{attrs} ||= {};
228    my $attribute = $self->base->attribute($self->otype, $attr);
229    my $htmlname = $self->escape($self->attr_field_name($attr));
230    if (my $attr_config = LATMOS::Accounts::Web->config->{attrs}{$attr}) {
231        $label ||= $attr_config->{label} || '';
232        #utf8::is_utf8($label) && utf8::encode($label);
233        $hint ||= $attr_config->{hint} || '';
234        #utf8::is_utf8($hint) && utf8::encode($hint);
235    }
236    return sprintf('<label %sfor="%s">%s</label>',
237        ($hint ? sprintf('title="%s"', $self->escape($hint)) : ''),
238        $self->escape($htmlname),
239        $self->escape($label || $attr),
240    );
241}
242
243sub attr_hint {
244    my ($self, $attr) = @_;
245    LATMOS::Accounts::Web->config->{attrs} ||= {};
246    if (my $attr_config = LATMOS::Accounts::Web->config->{attrs}{$attr}) {
247        return $attr_config->{hint} || '';
248    }
249    return;
250}
251
252sub attr_raw_value {
253    my ($self, $attribute) = @_;
254    my @val = grep { $_ } 
255        ($self->{c}->req->param($attribute->name))
256        || ($self->{object}
257            ? ($self->{object}->get_attributes($attribute->name))
258            : ());
259
260    if (@val) {
261        return @val;
262    } else {
263        return (grep { $_ } ($attribute->default_value))
264    }
265}
266
267sub attr_field_name {
268    my ($self, $attr) = @_;
269    my $id = $self->{object}
270        ? ($self->{object}->id || '')
271        : '';
272    $id .= '_' if ($id);
273    $id =~ s/\./_/g;
274    $id =~ s/-/_/g;
275    $id . $attr;
276}
277
278sub attr_item {
279    my ($self, $attribute, $value, $htmlid) = @_;
280
281    my $html = $self->_attr_item($attribute, $value, $htmlid);
282   
283    if ($attribute->uniq) {
284        $html .= qq|<span class="inputvalidate" id="${htmlid}_uniq"></span>|;
285    }
286    if (my $ref = $attribute->reference) {
287        my $uri_part = $self->_uri_part($ref);
288        if ($self->base->attribute($ref, 'displayName')) {
289            my $text = '';
290            if ($value &&
291                (my $obj = $self->base->get_object($ref, $value))) {
292                $text = $obj->get_attributes('displayName');
293            }
294            $html .= sprintf(
295                qq|<span id="${htmlid}_ref" style="margin-left: 1em">$text</span>|,
296                $self->escape($text),
297            );
298        } elsif($value && $uri_part) {
299            $html .= sprintf(
300                '<a href="%s"><img class="attr" src="%s" title="%s"></a>',
301                $self->{c}->uri_for('/', $uri_part, $value),
302                $self->{c}->uri_for('/static', 'images', 'arrow-right.png'),
303                $value,
304            );
305        }
306    }
307
308    $html
309}
310
311sub _attr_item {
312    my ($self, $attribute, $value, $htmlid) = @_;
313
314    my $htmlname = $self->escape($self->attr_field_name($attribute->name));
315    $htmlid ||= $htmlname;
316
317    for ($attribute->form_type) {
318            /^textarea$/i and do {
319                return sprintf(
320                    '<textarea id="%s" name="%s" cols="40">%s</textarea>',
321                    $self->escape($htmlid),
322                    $self->escape($htmlname),
323                    $self->escape($value || ''),
324                );
325                last;
326            };
327
328            /^label$/i and do {
329                $value or last;
330                my $html_field = $self->escape($value);
331                $html_field =~ s/\n/<br>/g;
332                $html_field .= sprintf('<input type="hidden" name="%s" value="%s">',
333                    $self->escape($htmlname), ($value || ''));
334                return $html_field;
335                last;
336            };
337
338            /^date$/i and do {
339                my ($date, $time) = split(/ /, $value || '');
340                if ($date && $date =~ /^(\d+)-(\d+)-(\d+)$/) {
341                    $date = "$3/$2/$1";
342                }
343                my $html = "\n" . q{<SCRIPT LANGUAGE="JavaScript" ID="js13">
344                var cal13 = new CalendarPopup();
345                </SCRIPT>} . "\n";
346                $html .= sprintf(
347                    '<input type="text" id="%s" name="%s" value="%s" size="12">',
348                    $self->escape($htmlid),
349                    $self->escape($htmlname),
350                    $self->escape($date)
351                );
352                $html .= q{<DIV ID="testdiv1" STYLE="position:absolute;visibility:hidden;background-color:white;layer-background-color:white;"></DIV>};
353                $html .= qq|
354                <A HREF="#"
355                    onClick="cal13.select(document.getElementById('$htmlid'),'${htmlid}_anc','dd/MM/yyyy');return false;"
356                    TITLE="Date"
357                    NAME="${htmlid}_anc" ID="${htmlid}_anc">
358                    <img class="attr" src="| . $self->{c}->uri_for(qw(/static images view-calendar-day.png))
359                    . qq{" style="ref"></A>
360                    } . "\n";
361                return $html;
362                last;
363            };
364
365            /^checkbox/i and do {
366                my $options = $1 || '';
367                my $html = sprintf('<input type="checkbox" id="%s" name="%s"%s>',
368                    $htmlid,
369                    $self->escape($htmlname),
370                    $value ? '  checked="yes"' : ''
371                ); 
372                $html .= sprintf('<input type="hidden" name="%s">',
373                    $self->escape($htmlname));
374                if ($attribute->form_option('rawvalue')) {
375                    $html .= $value
376                        ? ' ' . $value
377                        : ''; 
378                }
379                return $html;
380                last;
381            };
382
383            /^LIST/i and do {
384                my $select = sprintf('<select id="%s" name="%s">',
385                    $self->escape($htmlid),
386                    $self->escape($htmlname)) . "\n";
387                $select .= '<option value="">--</option>' . "\n"
388                    unless($attribute->mandatory);
389                $value ||= '';
390                my $initial_observed = '';
391                my @valslist;
392                foreach my $val (sort $attribute->can_values) {
393                    push(@valslist, {
394                        val => $val,
395                        disp => $attribute->display($val || ''),
396                    });
397                }
398                foreach (sort { $a->{disp} cmp $b->{disp} } @valslist) {
399                    $select .= sprintf(
400                        '    <option value="%s"%s>%s</option>',
401                        $self->escape($_->{val} || ''),
402                        $value eq $_->{val} ? ' selected="selected"' : '',
403                        $self->escape($_->{disp} || ''),
404                    );
405                    $select .= "\n";
406                }
407                $select .= "</select>\n";
408
409                return $select;
410                last;
411            };
412
413            /^text/i and do {
414                return sprintf(
415                    '<input type="text" id="%s" name="%s" value="%s" size="%d">',
416                    $self->escape($htmlid),
417                    $self->escape($htmlname),
418                    $self->escape($value),
419                    $attribute->form_option('length') || 30,
420                );
421                last;
422            };
423        }
424    return '';
425}
426
427sub _uri_part {
428    my ($self, $ref) = @_;
429    my $uri_part = {
430        user => 'users',
431        group => 'groups',
432        nethost => 'nethosts',
433        netzone => 'netzones',
434        site => 'sites',
435        aliasess => 'aliases',
436    }->{$ref};
437}
438
439sub attr_js {
440    my ($self, $attribute, $value, $htmlid) = @_;
441
442    my (@js);
443
444    if (my $ref = $attribute->reference) {
445        my $uri_part = $self->_uri_part($ref);
446        if ($self->base->attribute($ref, 'displayName')) {
447            push(@js, 
448                $self->{c}->prototype->observe_field( $htmlid,
449                    {
450                        update => "${htmlid}_ref",
451                        url => $self->{c}->uri_for('/ajax', 'rawattr', $ref),
452                        frequency => 1,
453                        with   => "'attr=displayName&id=' + element.options[element.selectedIndex].text",
454                    }
455                )
456            ) if ($attribute->form_type =~ /list/i);
457        }
458    }
459
460    if ($attribute->uniq) {
461        push(@js,
462            $self->{c}->prototype->observe_field( $htmlid,
463                {
464                    update => "${htmlid}_uniq",
465                    url => $self->{c}->uri_for('/ajax', 'objattrexist',
466                        $self->otype, $attribute->name),
467                    frequency => 1,
468                    with => "'val='+element.value" .
469                    ($self->{object} ?
470                        "+'&exclude=" . ($self->{object}->id || '') . "'" 
471                        : ''),
472                }
473            )
474        );
475    }
476
477    return(join("\n", @js));
478}
479
480sub attr_field {
481    my ($self, $attr, $type) = @_;
482
483    my $attribute;
484    if ($type) {
485        if (ref $type) {
486            $attribute = $self->base->attribute(
487                $self->otype,
488                { %$type, name => $attr },
489            );
490        } else {
491            $attribute =  $self->base->attribute(
492                $self->otype,
493                { formtype => $type , name => $attr },
494            );
495        }
496    } else {
497        if ($self->{object}) {
498            $attribute = $self->{object}->attribute($attr);
499        } else {
500            $attribute = $self->base->attribute(
501                $self->otype, $attr,
502                { formtype => $type }
503            );
504        }
505    }
506    $attribute ||= $self->base->attribute($self->otype, { name => $attr });
507
508
509    my $htmlname = $self->escape($self->attr_field_name($attr));
510
511    my @html_fields;
512
513    # Force Array context:
514    my @attr_raw_value = ();
515
516    if ($attribute->multiple) {
517        @attr_raw_value = grep { $_ } $self->attr_raw_value($attribute);
518    } else {
519        my ($val) = $self->attr_raw_value($attribute);
520        @attr_raw_value = ($val || '');
521    }
522
523    foreach my $attr_raw_value (@attr_raw_value) {
524
525        my $html_id = $htmlname .
526            (scalar(@html_fields) ? scalar(@html_fields) : '');
527        push(@html_fields,
528            join("\n",
529                $self->attr_item(
530                    $attribute, $attr_raw_value, $html_id
531                ),
532                $self->attr_js(
533                    $attribute, $attr_raw_value, $html_id
534                )
535            )
536        );
537    }
538
539    if ($attribute->{multiple} && !$attribute->readonly) {
540        my $html_id = $htmlname . '_m_SUBID';
541
542        my $attr = $self->attr_item($attribute, '', $html_id);
543        # JS: string are on the line only
544        $attr =~ s/\n//mg;
545        $attr =~ s/'/\'/g;
546
547        my $js = $self->attr_js($attribute, '', 'NANAR');
548        $js =~ s!'NANAR([_\w]*)'!('$html_id$1'.replace(/SUBID/g, cn))!gm;
549        $js =~ s!<script[^>]+>!!gm;
550        $js =~ s!</script>!!gm;
551        $js =~ s!-->!!gm;
552        $js =~ s/<!--//gm;
553
554        my $addempty = sprintf('<div id="%s"></div>', "${htmlname}_div_0");
555        $addempty .= "\n";
556        $addempty .= sprintf(qq#
557            <script type="text/javascript">
558            var cn_${htmlname} = 0;
559            function add_${htmlname} () {
560            cn_${htmlname}++;
561            // It work only using temporary variable
562            var cn = cn_${htmlname};
563            document.getElementById('${htmlname}_div_' + (cn - 1)).innerHTML +=
564                '$attr'.replace(/SUBID/g, cn );
565            document.getElementById('${htmlname}_div_' + (cn - 1)).innerHTML +=
566                '<div id="${htmlname}_div_'+ cn +'" style="display:block"></div>';
567            %s
568            }
569            </script>
570            #, $js
571        );
572
573        $addempty .= "\n";
574        $addempty .=
575            qq|<button type="button" style="display:block" onclick="add_${htmlname}()">+</button>|,
576
577        push(@html_fields, $addempty);
578    }
579
580    return join("<br>\n", @html_fields);
581}
582
583sub submit {
584    my ($self) = @_;
585    return sprintf(
586        '<input type="submit" name="%s" value="Enregistrer">',
587        $self->escape($self->label),
588    );
589}
590
591sub write_attributes {
592    my ($self) = @_;
593    my @attrs;
594    foreach ($self->attributes) {
595        my $attr = ($self->{object}
596            ? $self->{object}->attribute($_)
597            : $self->base->attribute($self->otype, $_)) or next;
598        $attr->readonly and next;
599        push(@attrs, $_);
600    }
601    @attrs;
602}
603
604sub set_attrs {
605    my ($self, $attrs) = @_;
606    $self->{c}->req->param($self->label) || $attrs or return;
607    my $prefix = $self->attr_field_name('');
608    my %fields;
609    foreach ($attrs ? @{ $attrs } : $self->write_attributes) {
610        my $attr = ($self->{object}
611            ? $self->{object}->attribute($_)
612            : $self->base->attribute($self->otype, $_)) or next;
613        if ($attr->{multiple}) {
614            $fields{$_} = [ grep { $_ } $self->{c}->req->param("$prefix$_") ];
615        } else {
616            $fields{$_} = $self->{c}->req->param("$prefix$_");
617        }
618    }
619    $self->{object}->set_c_fields(%fields) or do {
620        $self->{c}->stash->{page}{error} =
621            LATMOS::Accounts::Log::lastmessage(LA_ERR);
622        $self->{object}->base->rollback;
623        return;
624    };
625    $self->{object}->base->commit;
626}
627
628=head1 AUTHOR
629
630Thauvin Olivier
631
632=head1 LICENSE
633
634This library is free software, you can redistribute it and/or modify
635it under the same terms as Perl itself.
636
637=cut
638
6391;
Note: See TracBrowser for help on using the repository browser.