root/trunk/lib/DJabberd/Connection/ClientIn.pm @ 54

Revision 54, 3.2 kB (checked in by bradfitz, 4 years ago)

Start of good roster support.

We (Brad & Artur) added:

-- new class "Roster" (to present a list of roster items)
-- new class "RosterItem" for a JID/groups/subscription status
-- added RosterStorage.pm base class, like Auth.pm, which registers

itself in the hook chain and simplies some details.

-- made the RosterGet hook take a Roster object as a callback parameter so:
-- there's a clear line between XML and data structures in hook code,

so plugins do no XML

-- an SQLite rosterstorage plugin
-- a RosterStorage::Dummy plugin as an example
-- markup to second RFC

Much more to do, but it's starting to work....

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1package DJabberd::Connection::ClientIn;
2use strict;
3use base 'DJabberd::Connection';
4
5use fields (
6            'requested_roster',  # bool: if user has requested their roster,
7            );
8
9sub set_requested_roster {
10    my ($self, $val) = @_;
11    $self->{requested_roster} = $val;
12}
13
14sub requested_roster {
15    my $self = shift;
16    return $self->{requested_roster};
17}
18
19sub on_stream_start {
20    my DJabberd::Connection $self = shift;
21    my $ss = shift;
22    # FIXME: bitch if we're starting a stream when we already have one, and we aren't
23    # expeting a new stream to start (like after SSL or SASL)
24    $self->start_stream_back($ss,
25                             namespace  => 'jabber:client');
26}
27
28sub is_server { 0 }
29
30sub on_stanza_received {
31    my ($self, $node) = @_;
32
33    my %class = (
34                 "{jabber:client}iq"       => 'DJabberd::IQ',
35                 "{jabber:client}message"  => 'DJabberd::Message',
36                 "{jabber:client}presence" => 'DJabberd::Presence',
37                 );
38    my $class = $class{$node->element} or
39        return $self->stream_error("unsupported-stanza-type");
40
41    # same variable as $node, but down(specific)-classed.
42    my $stanza = $class->new($node);
43
44    $self->run_hook_chain(phase => "filter_incoming_client",
45                          args  => [ $stanza ],
46                          methods => {
47                              reject => sub { },  # just stops the chain
48                          },
49                          fallback => sub {
50                              $self->filter_incoming_client_builtin($stanza);
51                          });
52}
53
54sub is_authenticated_jid {
55    my ($self, $jid) = @_;
56    return $jid->eq($self->bound_jid);
57}
58
59sub filter_incoming_client_builtin {
60    my ($self, $stanza) = @_;
61
62    # <invalid-from/> -- the JID or hostname provided in a 'from'
63    # address does not match an authorized JID or validated domain
64    # negotiated between servers via SASL or dialback, or between a
65    #  client and a server via authentication and resource binding.
66    #{=clientin-invalid-from}
67    my $from = $stanza->from_jid;
68
69    if ($from && ! $self->is_authenticated_jid($from)) {
70        # make sure it is from them, if they care to tell us who they are.
71        # (otherwise further processing should assume it's them anyway)
72        return $self->stream_error('invalid-from');
73    }
74
75    # if no from, we set our own
76    if (! $from) {
77        my $bj = $self->bound_jid;
78        $stanza->set_from($bj->as_string) if $bj;
79    }
80
81    $self->run_hook_chain(phase => "switch_incoming_client",
82                          args  => [ $stanza ],
83                          methods => {
84                              process => sub { $stanza->process($self) },
85                              deliver => sub { $stanza->deliver($self) },
86                          },
87                          fallback => sub {
88                              $self->switch_incoming_client_builtin($stanza);
89                          });
90}
91
92sub switch_incoming_client_builtin {
93    my ($self, $stanza) = @_;
94
95    my $to = $stanza->to_jid;
96    if (!$to
97        || ($to && $self->vhost->uses_jid($to)) ) {
98        $stanza->process($self);
99        return;
100    }
101
102    $stanza->deliver($self);
103}
104
1051;
Note: See TracBrowser for help on using the browser.