aboutsummaryrefslogtreecommitdiffstats
path: root/lib/des.h
blob: 92fbfd2265b6b9fcdd6bf48e8104dc11fbf9be2f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
 *  FIPS-46-3 compliant 3DES implementation
 *
 *  Copyright (C) 2001-2003  Christophe Devine
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef _DES_H
#define _DES_H

#include <stdint.h>

typedef struct
{
    uint32_t esk[32];     /* DES encryption subkeys */
    uint32_t dsk[32];     /* DES decryption subkeys */
}
des_context;

typedef struct
{
    uint32_t esk[96];     /* Triple-DES encryption subkeys */
    uint32_t dsk[96];     /* Triple-DES decryption subkeys */
}
des3_context;

int  des_set_key( des_context *ctx, uint8_t key[8] );
void des_encrypt( des_context *ctx, uint8_t input[8], uint8_t output[8] );
void des_decrypt( des_context *ctx, uint8_t input[8], uint8_t output[8] );

int  des3_set_2keys( des3_context *ctx, const uint8_t key1[8], const uint8_t key2[8] );
int  des3_set_3keys( des3_context *ctx, const uint8_t key1[8], const uint8_t key2[8],
                                        const uint8_t key3[8] );

void des3_encrypt( des3_context *ctx, uint8_t input[8], uint8_t output[8] );
void des3_decrypt( des3_context *ctx, uint8_t input[8], uint8_t output[8] );

#endif /* des.h */
.nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
use strict;
use warnings;
use Test::More;
use utf8;

use FixMyStreet::TestMech;
use FixMyStreet::App;
use Data::Dumper;

my $mech = FixMyStreet::TestMech->new;

my $BROMLEY_ID = 2482;
my $body = $mech->create_body_ok( $BROMLEY_ID, 'Bromley Council' );

my $dt = DateTime->now;

my $user =
  FixMyStreet::App->model('DB::User')
  ->find_or_create( { email => 'test-moderation@example.com', name => 'Test User' } );
$user->user_body_permissions->delete_all;
$user->discard_changes;

sub create_report {
    FixMyStreet::App->model('DB::Problem')->create(
    {
        postcode           => 'BR1 3SB',
        bodies_str         => $body->id,
        areas              => ",$BROMLEY_ID,",
        category           => 'Other',
        title              => 'Good bad good',
        detail             => 'Good bad bad bad good bad',
        used_map           => 't',
        name               => 'Test User',
        anonymous          => 'f',
        state              => 'confirmed',
        confirmed          => $dt->ymd . ' ' . $dt->hms,
        lang               => 'en-gb',
        service            => '',
        cobrand            => 'default',
        cobrand_data       => '',
        send_questionnaire => 't',
        latitude           => '51.4129',
        longitude          => '0.007831',
        user_id            => $user->id,
        photo              => $mech->get_photo_data,
    });
}
my $report = create_report();
my $report2 = create_report();

my $REPORT_URL = '/report/' . $report->id ;

subtest 'Auth' => sub {

    subtest 'Unaffiliated user cannot see moderation' => sub {
        $mech->get_ok($REPORT_URL);
        $mech->content_lacks('Moderat');

        $mech->log_in_ok( $user->email );

        $mech->get_ok($REPORT_URL);
        $mech->content_lacks('Moderat');

        $user->update({ from_body => $body->id });

        $mech->get_ok($REPORT_URL);
        $mech->content_lacks('Moderat');

        $mech->get_ok('/contact?m=1&id=' . $report->id);
        $mech->content_lacks('Good bad bad bad');
    };

    subtest 'Affiliated and permissioned user can see moderation' => sub {
        # login and from_body are done in previous test.
        $user->user_body_permissions->create({
            body => $body,
            permission_type => 'moderate',
        });

        $mech->get_ok($REPORT_URL);
        $mech->content_contains('Moderat');
    };
};

my %problem_prepopulated = (
    problem_show_name => 1,
    problem_show_photo => 1,
    problem_title => 'Good bad good',
    problem_detail => 'Good bad bad bad good bad',
);

subtest 'Problem moderation' => sub {

    subtest 'Post modify title and text' => sub {
        $mech->post_ok('/moderate/report/' . $report->id, {
            %problem_prepopulated,
            problem_title  => 'Good good',
            problem_detail => 'Good good improved',
        });
        $mech->base_like( qr{\Q$REPORT_URL\E} );

        $report->discard_changes;
        is $report->title, 'Good [...] good';
        is $report->detail, 'Good [...] good [...]improved';
    };

    subtest 'Revert title and text' => sub {
        $mech->post_ok('/moderate/report/' . $report->id, {
            %problem_prepopulated,
            problem_revert_title  => 1,
            problem_revert_detail => 1,
        });
        $mech->base_like( qr{\Q$REPORT_URL\E} );

        $report->discard_changes;
        is $report->title, 'Good bad good';
        is $report->detail, 'Good bad bad bad good bad';
    };

    subtest 'Make anonymous' => sub {
        $mech->content_lacks('Reported anonymously');

        $mech->post_ok('/moderate/report/' . $report->id, {
            %problem_prepopulated,
            problem_show_name => 0,
        });
        $mech->base_like( qr{\Q$REPORT_URL\E} );

        $mech->content_contains('Reported anonymously');

        $mech->post_ok('/moderate/report/' . $report->id, {
            %problem_prepopulated,
            problem_show_name => 1,
        });
        $mech->base_like( qr{\Q$REPORT_URL\E} );

        $mech->content_lacks('Reported anonymously');
    };

    subtest 'Hide photo' => sub {
        $mech->content_contains('Photo of this report');

        $mech->post_ok('/moderate/report/' . $report->id, {
            %problem_prepopulated,
            problem_show_photo => 0,
        });
        $mech->base_like( qr{\Q$REPORT_URL\E} );

        $mech->content_lacks('Photo of this report');

        $mech->post_ok('/moderate/report/' . $report->id, {
            %problem_prepopulated,
            problem_show_photo => 1,
        });
        $mech->base_like( qr{\Q$REPORT_URL\E} );

        $mech->content_contains('Photo of this report');
    };

    subtest 'Hide report' => sub {
        $mech->clear_emails_ok;

        my $resp = $mech->post('/moderate/report/' . $report->id, {
            %problem_prepopulated,
            problem_hide => 1,
        });
        $mech->base_unlike( qr{/report/}, 'redirected to front page' );

        $report->discard_changes;
        is $report->state, 'hidden', 'Is hidden';

        my $email = $mech->get_email;
        my ($url) = $email->body =~ m{(http://\S+)};
        ok $url, "extracted complain url '$url'";

        $mech->get_ok($url);
        $mech->content_contains('Good bad bad bad');

        # reset
        $report->update({ state => 'confirmed' });
    };
};

$mech->content_lacks('Posted anonymously', 'sanity check');

subtest 'Problem 2' => sub {
    my $REPORT2_URL = '/report/' . $report2->id ;
    $mech->post_ok('/moderate/report/' . $report2->id, {
        %problem_prepopulated,
        problem_title  => 'Good good',
        problem_detail => 'Good good improved',
    });
    $mech->base_like( qr{\Q$REPORT2_URL\E} );

    $report2->discard_changes;
    is $report2->title, 'Good [...] good';
    is $report2->detail, 'Good [...] good [...]improved';

    $mech->post_ok('/moderate/report/' . $report2->id, {
        %problem_prepopulated,
        problem_revert_title  => 1,
        problem_revert_detail => 1,
    });
    $mech->base_like( qr{\Q$REPORT2_URL\E} );

    $report2->discard_changes;
    is $report2->title, 'Good bad good';
    is $report2->detail, 'Good bad bad bad good bad';
};

sub create_update {
    $report->comments->create({
        user      => $user,
        name      => 'Test User',
        anonymous => 'f',
        photo     => $mech->get_photo_data,
        text      => 'update good good bad good',
        state     => 'confirmed',
        mark_fixed => 0,
    });
}
my %update_prepopulated = (
    update_show_name => 1,
    update_show_photo => 1,
    update_detail => 'update good good bad good',
);

my $update = create_update();

subtest 'updates' => sub {

    my $MODERATE_UPDATE_URL = sprintf '/moderate/report/%d/update/%d', $report->id, $update->id;

    subtest 'Update modify text' => sub {
        $mech->post_ok( $MODERATE_UPDATE_URL, {
            %update_prepopulated,
            update_detail => 'update good good good',
        }) or die $mech->content;
        $mech->base_like( qr{\Q$REPORT_URL\E} );

        $update->discard_changes;
        is $update->text, 'update good good [...] good',
    };

    subtest 'Revert text' => sub {
        $mech->post_ok( $MODERATE_UPDATE_URL, {
            %update_prepopulated,
            update_revert_detail  => 1,
        });
        $mech->base_like( qr{\Q$REPORT_URL\E} );

        $update->discard_changes;
        $update->discard_changes;
        is $update->text, 'update good good bad good',
    };

    subtest 'Make anonymous' => sub {
        $mech->content_lacks('Posted anonymously')
            or die sprintf '%d (%d)', $update->id, $report->comments->count;

        $mech->post_ok( $MODERATE_UPDATE_URL, {
            %update_prepopulated,
            update_show_name => 0,
        });
        $mech->base_like( qr{\Q$REPORT_URL\E} );

        $mech->content_contains('Posted anonymously');

        $mech->post_ok( $MODERATE_UPDATE_URL, {
            %update_prepopulated,
            update_show_name => 1,
        });
        $mech->base_like( qr{\Q$REPORT_URL\E} );

        $mech->content_lacks('Posted anonymously');
    };

    subtest 'Hide photo' => sub {
        $report->update({ photo => undef }); # hide the main photo so we can just look for text in comment

        $mech->get_ok($REPORT_URL);

        $mech->content_contains('Photo of this report')
            or die $mech->content;

        $mech->post_ok( $MODERATE_UPDATE_URL, {
            %update_prepopulated,
            update_show_photo => 0,
        });
        $mech->base_like( qr{\Q$REPORT_URL\E} );

        $mech->content_lacks('Photo of this report');

        $mech->post_ok( $MODERATE_UPDATE_URL, {
            %update_prepopulated,
            update_show_photo => 1,
        });
        $mech->base_like( qr{\Q$REPORT_URL\E} );

        $mech->content_contains('Photo of this report');
    };

    subtest 'Hide comment' => sub {
        $mech->content_contains('update good good bad good');

        $mech->post_ok( $MODERATE_UPDATE_URL, {
            %update_prepopulated,
            update_hide => 1,
        });
        $mech->content_lacks('update good good bad good');
    };

    $update->moderation_original_data->delete;
};

my $update2 = create_update();

subtest 'Update 2' => sub {
    my $MODERATE_UPDATE2_URL = sprintf '/moderate/report/%d/update/%d', $report->id, $update2->id;
    $mech->post_ok( $MODERATE_UPDATE2_URL, {
        %update_prepopulated,
        update_detail => 'update good good good',
    }) or die $mech->content;

    $update2->discard_changes;
    is $update2->text, 'update good good [...] good',
};

$update->delete;
$update2->delete;
$report->moderation_original_data->delete;
$report->delete;
$report2->delete;

done_testing();