Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
biboumi
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
88
Issues
88
List
Boards
Labels
Service Desk
Milestones
Merge Requests
7
Merge Requests
7
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
louiz’
biboumi
Commits
e840704b
Commit
e840704b
authored
Jan 04, 2014
by
louiz’
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Convert received modes into roles and affiliations
parent
baf03a7e
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
181 additions
and
8 deletions
+181
-8
doc/biboumi.md
doc/biboumi.md
+8
-4
src/bridge/bridge.cpp
src/bridge/bridge.cpp
+32
-0
src/bridge/bridge.hpp
src/bridge/bridge.hpp
+4
-0
src/irc/irc_channel.cpp
src/irc/irc_channel.cpp
+1
-1
src/irc/irc_channel.hpp
src/irc/irc_channel.hpp
+1
-1
src/irc/irc_client.cpp
src/irc/irc_client.cpp
+74
-1
src/irc/irc_client.hpp
src/irc/irc_client.hpp
+6
-1
src/irc/irc_user.cpp
src/irc/irc_user.cpp
+20
-0
src/irc/irc_user.hpp
src/irc/irc_user.hpp
+4
-0
src/xmpp/xmpp_component.cpp
src/xmpp/xmpp_component.cpp
+22
-0
src/xmpp/xmpp_component.hpp
src/xmpp/xmpp_component.hpp
+9
-0
No files found.
doc/biboumi.md
View file @
e840704b
...
@@ -184,17 +184,21 @@ notified of this XMPP event as well. For example if a mode “+o toto” is
...
@@ -184,17 +184,21 @@ notified of this XMPP event as well. For example if a mode “+o toto” is
received, then toto’s role will be changed to moderator. The mapping
received, then toto’s role will be changed to moderator. The mapping
between IRC modes and XMPP features is as follow:
between IRC modes and XMPP features is as follow:
`+a`
Sets the participant’s role to
`moderator`
and its affiliation to
`owner`
.
`+o`
`+o`
Sets the participant’s role to
`moderator`
.
Sets the participant’s role to
`moderator`
and its affiliation to
`admin`
.
`+
a
`
`+
h
`
Sets the participant’s role to
`
admin
`
.
Sets the participant’s role to
`
moderator`
and its affiliation to
`member
`
.
`+v`
`+v`
Sets the participant’s affiliation to
`member`
.
Sets the participant’s
role to
`participant`
and its
affiliation to
`member`
.
SECURITY
SECURITY
--------
--------
...
...
src/bridge/bridge.cpp
View file @
e840704b
...
@@ -225,3 +225,35 @@ void Bridge::send_nickname_conflict_error(const Iid& iid, const std::string& nic
...
@@ -225,3 +225,35 @@ void Bridge::send_nickname_conflict_error(const Iid& iid, const std::string& nic
{
{
this
->
xmpp
->
send_nickname_conflict_error
(
iid
.
chan
+
"%"
+
iid
.
server
,
nickname
,
this
->
user_jid
);
this
->
xmpp
->
send_nickname_conflict_error
(
iid
.
chan
+
"%"
+
iid
.
server
,
nickname
,
this
->
user_jid
);
}
}
void
Bridge
::
send_affiliation_role_change
(
const
Iid
&
iid
,
const
std
::
string
&
target
,
const
char
mode
)
{
std
::
string
role
;
std
::
string
affiliation
;
if
(
mode
==
0
)
{
role
=
"participant"
;
affiliation
=
"none"
;
}
else
if
(
mode
==
'a'
)
{
role
=
"moderator"
;
affiliation
=
"owner"
;
}
else
if
(
mode
==
'o'
)
{
role
=
"moderator"
;
affiliation
=
"admin"
;
}
else
if
(
mode
==
'h'
)
{
role
=
"moderator"
;
affiliation
=
"member"
;
}
else
if
(
mode
==
'v'
)
{
role
=
"participant"
;
affiliation
=
"member"
;
}
this
->
xmpp
->
send_affiliation_role_change
(
iid
.
chan
+
"%"
+
iid
.
server
,
target
,
affiliation
,
role
,
this
->
user_jid
);
}
src/bridge/bridge.hpp
View file @
e840704b
...
@@ -87,6 +87,10 @@ public:
...
@@ -87,6 +87,10 @@ public:
void
send_nick_change
(
Iid
&&
iid
,
const
std
::
string
&
old_nick
,
const
std
::
string
&
new_nick
,
const
bool
self
);
void
send_nick_change
(
Iid
&&
iid
,
const
std
::
string
&
old_nick
,
const
std
::
string
&
new_nick
,
const
bool
self
);
void
kick_muc_user
(
Iid
&&
iid
,
const
std
::
string
&
target
,
const
std
::
string
&
reason
,
const
std
::
string
&
author
);
void
kick_muc_user
(
Iid
&&
iid
,
const
std
::
string
&
target
,
const
std
::
string
&
reason
,
const
std
::
string
&
author
);
void
send_nickname_conflict_error
(
const
Iid
&
iid
,
const
std
::
string
&
nickname
);
void
send_nickname_conflict_error
(
const
Iid
&
iid
,
const
std
::
string
&
nickname
);
/**
* Send a role/affiliation change, matching the change of mode for that user
*/
void
send_affiliation_role_change
(
const
Iid
&
iid
,
const
std
::
string
&
target
,
const
char
mode
);
/**
/**
* Misc
* Misc
...
...
src/irc/irc_channel.cpp
View file @
e840704b
...
@@ -24,7 +24,7 @@ IrcUser* IrcChannel::get_self() const
...
@@ -24,7 +24,7 @@ IrcUser* IrcChannel::get_self() const
return
this
->
self
.
get
();
return
this
->
self
.
get
();
}
}
IrcUser
*
IrcChannel
::
find_user
(
const
std
::
string
&
name
)
IrcUser
*
IrcChannel
::
find_user
(
const
std
::
string
&
name
)
const
{
{
IrcUser
user
(
name
);
IrcUser
user
(
name
);
for
(
const
auto
&
u
:
this
->
users
)
for
(
const
auto
&
u
:
this
->
users
)
...
...
src/irc/irc_channel.hpp
View file @
e840704b
...
@@ -22,7 +22,7 @@ public:
...
@@ -22,7 +22,7 @@ public:
IrcUser
*
get_self
()
const
;
IrcUser
*
get_self
()
const
;
IrcUser
*
add_user
(
const
std
::
string
&
name
,
IrcUser
*
add_user
(
const
std
::
string
&
name
,
const
std
::
map
<
char
,
char
>
prefix_to_mode
);
const
std
::
map
<
char
,
char
>
prefix_to_mode
);
IrcUser
*
find_user
(
const
std
::
string
&
name
);
IrcUser
*
find_user
(
const
std
::
string
&
name
)
const
;
void
remove_user
(
const
IrcUser
*
user
);
void
remove_user
(
const
IrcUser
*
user
);
private:
private:
...
...
src/irc/irc_client.cpp
View file @
e840704b
...
@@ -218,7 +218,10 @@ void IrcClient::on_isupport_message(const IrcMessage& message)
...
@@ -218,7 +218,10 @@ void IrcClient::on_isupport_message(const IrcMessage& message)
j
++
;
j
++
;
j
++
;
j
++
;
while
(
j
<
token
.
size
()
&&
token
[
i
]
!=
')'
)
while
(
j
<
token
.
size
()
&&
token
[
i
]
!=
')'
)
this
->
prefix_to_mode
[
token
[
j
++
]]
=
token
[
i
++
];
{
this
->
sorted_user_modes
.
push_back
(
token
[
i
]);
this
->
prefix_to_mode
[
token
[
j
++
]]
=
token
[
i
++
];
}
}
}
}
}
}
}
...
@@ -508,6 +511,76 @@ void IrcClient::on_channel_mode(const IrcMessage& message)
...
@@ -508,6 +511,76 @@ void IrcClient::on_channel_mode(const IrcMessage& message)
this
->
bridge
->
send_message
(
iid
,
""
,
std
::
string
(
"Mode "
)
+
iid
.
chan
+
this
->
bridge
->
send_message
(
iid
,
""
,
std
::
string
(
"Mode "
)
+
iid
.
chan
+
" ["
+
mode_arguments
+
"] by "
+
user
.
nick
,
" ["
+
mode_arguments
+
"] by "
+
user
.
nick
,
true
);
true
);
const
IrcChannel
*
channel
=
this
->
get_channel
(
iid
.
chan
);
if
(
!
channel
)
return
;
// parse the received modes, we need to handle things like "+m-oo coucou toutou"
const
std
::
string
modes
=
message
.
arguments
[
1
];
// a list of modified IrcUsers. When we applied all modes, we check the
// modes that now applies to each of them, and send a notification for
// each one. This is to disallow sending two notifications or more when a
// single MODE command changes two or more modes on the same participant
std
::
set
<
const
IrcUser
*>
modified_users
;
// If it is true, the modes are added, if it’s false they are
// removed. When we encounter the '+' char, the value is changed to true,
// and with '-' it is changed to false.
bool
add
=
true
;
bool
use_arg
;
size_t
arg_pos
=
2
;
for
(
const
char
c
:
modes
)
{
if
(
c
==
'+'
)
add
=
true
;
else
if
(
c
==
'-'
)
add
=
false
;
else
{
// lookup the mode symbol in the 4 chanmodes lists, depending on
// the list where it is found, it takes an argument or not
size_t
type
;
for
(
type
=
0
;
type
<
4
;
++
type
)
if
(
this
->
chanmodes
[
type
].
find
(
c
)
!=
std
::
string
::
npos
)
break
;
if
(
type
==
4
)
// if mode was not found
{
// That mode can also be of type B if it is present in the
// prefix_to_mode map
for
(
const
std
::
pair
<
char
,
char
>&
pair
:
this
->
prefix_to_mode
)
if
(
pair
.
second
==
c
)
{
type
=
1
;
break
;
}
}
// modes of type A, B or C (but only with add == true)
if
(
type
==
0
||
type
==
1
||
(
type
==
2
&&
add
==
true
))
use_arg
=
true
;
else
// modes of type C (but only with add == false), D, or unknown
use_arg
=
false
;
if
(
use_arg
==
true
&&
message
.
arguments
.
size
()
>
arg_pos
)
{
const
std
::
string
target
=
message
.
arguments
[
arg_pos
++
];
IrcUser
*
user
=
channel
->
find_user
(
target
);
if
(
!
user
)
{
log_warning
(
"Trying to set mode for non-existing user '"
<<
target
<<
"' in channel"
<<
iid
.
chan
);
return
;
}
if
(
add
)
user
->
add_mode
(
c
);
else
user
->
remove_mode
(
c
);
modified_users
.
insert
(
user
);
}
}
}
for
(
const
IrcUser
*
u
:
modified_users
)
{
char
most_significant_mode
=
u
->
get_most_significant_mode
(
this
->
sorted_user_modes
);
this
->
bridge
->
send_affiliation_role_change
(
iid
,
u
->
nick
,
most_significant_mode
);
}
}
}
void
IrcClient
::
on_user_mode
(
const
IrcMessage
&
message
)
void
IrcClient
::
on_user_mode
(
const
IrcMessage
&
message
)
...
...
src/irc/irc_client.hpp
View file @
e840704b
...
@@ -229,9 +229,14 @@ private:
...
@@ -229,9 +229,14 @@ private:
/**
/**
* See http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt section 3.14
* See http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt section 3.14
* The example given would be transformed into
* The example given would be transformed into
* modes_to_prefix = {{'
a', '&'}, {'b', '*
'}}
* modes_to_prefix = {{'
&', 'a'}, {'*', 'b
'}}
*/
*/
std
::
map
<
char
,
char
>
prefix_to_mode
;
std
::
map
<
char
,
char
>
prefix_to_mode
;
/**
* Available user modes, sorted from most significant to least significant
* (for example 'ahov' is a common order).
*/
std
::
vector
<
char
>
sorted_user_modes
;
IrcClient
(
const
IrcClient
&
)
=
delete
;
IrcClient
(
const
IrcClient
&
)
=
delete
;
IrcClient
(
IrcClient
&&
)
=
delete
;
IrcClient
(
IrcClient
&&
)
=
delete
;
...
...
src/irc/irc_user.cpp
View file @
e840704b
...
@@ -25,3 +25,23 @@ IrcUser::IrcUser(const std::string& name):
...
@@ -25,3 +25,23 @@ IrcUser::IrcUser(const std::string& name):
IrcUser
(
name
,
{})
IrcUser
(
name
,
{})
{
{
}
}
void
IrcUser
::
add_mode
(
const
char
mode
)
{
this
->
modes
.
insert
(
mode
);
}
void
IrcUser
::
remove_mode
(
const
char
mode
)
{
this
->
modes
.
erase
(
mode
);
}
char
IrcUser
::
get_most_significant_mode
(
const
std
::
vector
<
char
>&
modes
)
const
{
for
(
const
char
mode
:
modes
)
{
if
(
this
->
modes
.
find
(
mode
)
!=
this
->
modes
.
end
())
return
mode
;
}
return
0
;
}
src/irc/irc_user.hpp
View file @
e840704b
#ifndef IRC_USER_INCLUDED
#ifndef IRC_USER_INCLUDED
# define IRC_USER_INCLUDED
# define IRC_USER_INCLUDED
#include <vector>
#include <string>
#include <string>
#include <map>
#include <map>
#include <set>
#include <set>
...
@@ -14,6 +15,9 @@ public:
...
@@ -14,6 +15,9 @@ public:
explicit
IrcUser
(
const
std
::
string
&
name
,
explicit
IrcUser
(
const
std
::
string
&
name
,
const
std
::
map
<
char
,
char
>&
prefix_to_mode
);
const
std
::
map
<
char
,
char
>&
prefix_to_mode
);
explicit
IrcUser
(
const
std
::
string
&
name
);
explicit
IrcUser
(
const
std
::
string
&
name
);
void
add_mode
(
const
char
mode
);
void
remove_mode
(
const
char
mode
);
char
get_most_significant_mode
(
const
std
::
vector
<
char
>&
sorted_user_modes
)
const
;
std
::
string
nick
;
std
::
string
nick
;
std
::
string
host
;
std
::
string
host
;
std
::
set
<
char
>
modes
;
std
::
set
<
char
>
modes
;
...
...
src/xmpp/xmpp_component.cpp
View file @
e840704b
...
@@ -484,3 +484,25 @@ void XmppComponent::send_nickname_conflict_error(const std::string& muc_name,
...
@@ -484,3 +484,25 @@ void XmppComponent::send_nickname_conflict_error(const std::string& muc_name,
presence
.
close
();
presence
.
close
();
this
->
send_stanza
(
presence
);
this
->
send_stanza
(
presence
);
}
}
void
XmppComponent
::
send_affiliation_role_change
(
const
std
::
string
&
muc_name
,
const
std
::
string
&
target
,
const
std
::
string
&
affiliation
,
const
std
::
string
&
role
,
const
std
::
string
&
jid_to
)
{
Stanza
presence
(
"presence"
);
presence
[
"from"
]
=
muc_name
+
"@"
+
this
->
served_hostname
+
"/"
+
target
;
presence
[
"to"
]
=
jid_to
;
XmlNode
x
(
"x"
);
x
[
"xmlns"
]
=
MUC_USER_NS
;
XmlNode
item
(
"item"
);
item
[
"affiliation"
]
=
affiliation
;
item
[
"role"
]
=
role
;
item
.
close
();
x
.
add_child
(
std
::
move
(
item
));
x
.
close
();
presence
.
add_child
(
std
::
move
(
x
));
presence
.
close
();
this
->
send_stanza
(
presence
);
}
src/xmpp/xmpp_component.hpp
View file @
e840704b
...
@@ -112,6 +112,15 @@ public:
...
@@ -112,6 +112,15 @@ public:
void
send_nickname_conflict_error
(
const
std
::
string
&
muc_name
,
void
send_nickname_conflict_error
(
const
std
::
string
&
muc_name
,
const
std
::
string
&
nickname
,
const
std
::
string
&
nickname
,
const
std
::
string
&
jid_to
);
const
std
::
string
&
jid_to
);
/**
* Send a presence from the MUC indicating a change in the role and/or
* affiliation of a participant
*/
void
send_affiliation_role_change
(
const
std
::
string
&
muc_name
,
const
std
::
string
&
target
,
const
std
::
string
&
affiliation
,
const
std
::
string
&
role
,
const
std
::
string
&
jid_to
);
/**
/**
* Handle the various stanza types
* Handle the various stanza types
*/
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment