Skip to content

Instantly share code, notes, and snippets.

@Edoxile
Created March 8, 2013 09:50
Show Gist options
  • Save Edoxile/5115401 to your computer and use it in GitHub Desktop.
Save Edoxile/5115401 to your computer and use it in GitHub Desktop.
New API for Saphira
#!/usr/bin/env perl
use warnings;
use strict;
use Config::IniFiles;
package Saphira::IRC::Bot;
my $version = '2.0.0';
1;
package Saphira::API::Wrapper;
use DBI;
sub new {
my $class = shift;
my $self = bless {
mysql_host => shift,
mysql_username => shift,
mysql_password => shift,
mysql_database => shift,
servers => {}
}, $class;
$self->{dbd} = DBI->connect(
sprintf(
'DBI:mysql:%s;host=%s',
$self->{mysql_database},
$self->{mysql_host}
),
$self->{mysql_username},
$self->{mysql_password},
{ 'mysql_enable_utf8' => 1 }
);
if ( not $self->{dbd} ) {
print '[E] MySQL connect error: ' . $DBI::errstr . "\n";
return undef;
}
$self->{dbd}->do('SET NAMES utf8');
if ( $self->init() ) {
return $self;
}
else {
return undef;
}
}
sub init {
my $self = @_;
$ps = $self->{dbd}->prepare(
'select
*
from
servers'
);
$ps->execute();
if ( $ps->err ) {
print '[E] MySQL select error: ' . $ps->errstr . "\n";
return 0;
}
while ( $result = $ps->fetchrow_hashref() ) {
$self->{servers}->{ $result->{id} } = new Saphira::API::Server(
$result->{id}, $result->{servername},
$result->{address}, $result->{port},
$result->{secure}, $result->{username},
$result->{password}, $result->{nickservpassword},
$self
);
}
}
sub getServer {
my ( $self, $id ) = @_;
return $self->{servers}->{$id};
}
sub removeServer {
my ( $self, $id ) = @_;
return unless not $self->{servers}->{$id}->isActive();
delete $self->{servers}->{$id};
}
1;
package Saphira::API::DBExt;
use DBI;
our $__queries = {};
sub new {
my $class = shift;
my $self = bless { wrapper => shift }, $class;
return $self;
}
sub handleQuery {
my ( $self, $queryType ) = @_;
return unless defined $__queries{$queryType}->{query};
return unless defined $__queries{$queryType}->{fields};
return unless $__queries{$queryType}->{fields} gt 0;
my $ps =
$self->{wrapper}->{dbd}->prepare( $__queries{$queryType}->{query} );
my $n = 1;
foreach $field ( @{ $__queries->{fields} } ) {
$ps->bind_param( $n, $self->{$field} );
$n++;
}
$ps->execute();
return $ps;
}
1;
package Saphira::API::Server;
use base 'Saphira::API::DBExt';
sub new {
my $class = shift;
my $self = bless {
id => shift,
servername => shift,
address => shift,
port => shift,
secure => shift,
username => shift,
password => shift,
nickpassword => shift,
wrapper => shift,
channels => {}
}, $class;
$self->init();
return $self;
}
sub getServerName {
my $self = @_;
return $self->{servername};
}
sub getServerAddress {
my $self = @_;
return $self->{address};
}
sub getServerPort {
my $self = @_;
return $self->{port};
}
sub useSecureConnection {
my $self = @_;
return $self->{secure};
}
sub getChannel {
my ( $self, $channelName ) = @_;
my $key = $self->getChannelId($channelName);
return unless defined $key;
return $self->{channels}->{$key};
}
sub getWrapper {
my $self = @_;
return $self->{wrapper};
}
sub setPassword {
my ( $self, $password ) = @_;
$self->{password} = $password;
$self->_update();
}
sub _getServerId {
my $self = @_;
return $self->{id};
}
sub _getChannelId {
my ( $self, $channelName ) = @_;
foreach $key ( keys %{ $self->{channels} } ) {
if ( $self->{channels}->{$key}->{name} eq $channelName ) {
return $key;
}
}
return undef;
}
1;
package Saphira::API::Channel;
use base 'Saphira::API::DBExt';
our $__queries = {
insert => {
query => 'insert into channels (
server, name, log, password
) values (
?, ?, ?, ?
)',
fields => ( 'server', 'name', 'logging', 'password' )
},
update => {
query => 'update channels set
server = ?,
log = ?,
password = ?
where id = ?',
fields => ( 'server', 'logging', 'password', 'id' )
}
}
sub new {
my $class = shift;
my $self = bless {
server => shift,
id => shift,
name => shift,
password => shift,
state => -1,
persistent => 0,
logging => 0,
users => {}
}, $class;
$self->init();
return $self;
}
sub getServer {
my $self = @_;
return $self->{server};
}
sub getId {
my $self = @_;
return $self->{id};
}
sub getName {
my $self = @_;
return $self->{name};
}
sub getUsers {
my $self = @_;
return @{ values $self->{users} };
}
sub addUser {
my ( $self, $user ) = @_;
return unless not defined $self->{users}->{ $user->getUsername() };
$self->{users}->{ $user->getUsername() } = $user;
return 1;
}
sub removeUser {
my ( $self, $username ) = @_;
return unless defined $self->{users}->{$username};
$self->{users}->{$username} = undef;
return 1;
}
sub getModes {
my $self = @_;
#TODO: finish
}
sub setModes {
my ( $self, $newModes ) = @_;
#TODO: finish
}
sub getTitle {
my $self = @_;
#TODO: finish
}
sub setTitle {
my ( $self, $newTitle ) = @_;
#TODO: finish
}
sub isPersistent {
my $self = @_;
return $self->{persistent};
}
sub setPersistency {
my ( $self, $persistency ) = @_;
$persistency = int($persistency);
$persistency = ( $persistency > 0 ) ? 1 : 0;
return unless $self->{persistent} ne $persistency;
if ( $persistency and $self->{state} eq 0 ) {
$self->_enalbe();
}
else if ( $persistency and $self->{state} eq -1 ) {
$self->_insert();
}
else {
$self->_disable();
}
}
sub _insert {
my $self = @_;
$self->{state} = 1;
}
sub _disable {
my $self = @_;
$self->{state} = 0;
}
sub _enable {
my $self = @_;
$self->{state} = 1;
}
1;
package Saphira::API::User;
use base 'Saphira::API::DBExt';
use Digest::SHA 'sha512_hex';
our $__queries = {
insert => {
query => 'insert into users (
server, name, log, password
) values (
?, ?, ?, ?
)',
fields => ( 'server', 'name', 'logging', 'password' )
},
update_pass => {
query => 'update users set
password = ?
where
id = ?',
fields => ( 'password', 'id' )
},
update_lastlogin => {
query => 'update users set
lastlogin = now()
where id = ?',
fields => ('id')
},
select_permissions => {
query => 'select
channelid, level
from
permissios
where
userid = ?',
fields => ('id')
}
}
sub new {
my $class = shift;
my $self = bless {
wrapper => shift,
server => shift,
id => shift,
username => shift,
identity => shift,
host => shift,
lastlogin => shift,
permissions => {}
}, $class;
$self->init();
return $self;
}
sub getUser {
my $self = @_;
return $self->{name};
}
sub getIdentity {
my $self = @_;
return $self->{identity};
}
sub getHost {
my $self = @_;
return $self->{host};
}
sub getPermission {
my ( $self, $chan ) = @_;
my $chanId = undef;
if ( $chan ~= /^\d+$/ ) {
$chanId = int($chan);
}
else if ( $chan ~= /^#\w+$/ ) {
$chanId = $self->{server}->getChannel($chan);
}
else if ( ref $chan eq 'Saphira::API::Channel' ) {
$chanId = $chan->getId();
}
return unless defined $chanId;
return unless defined $self->{permissions}->{$chanId};
return $self->{permissions}->{$chanId};
}
sub setPermission {
my ( $self, $chan, $permissionLevel ) = @_;
my ( $self, $chan ) = @_;
my $chanId = undef;
if ( $chan ~= /^\d+$/ ) {
$chanId = int($chan);
}
else if ( $chan ~= /^#\w+$/ ) {
$chanId = $self->{server}->getChannel($chan);
}
else if ( ref $chan eq 'Saphira::API::Channel' ) {
$chanId = $chan->getId();
}
return 0 unless defined $chanId;
$self->{permissions}->{$chanId} = int($permissionLevel);
$self->_storePermission( $self->{id}, $chanId, $permissionLevel );
return 1;
}
sub _reloadPermissions {
my $self = @_;
$ps = $self->handleQuery('select_permissions');
while ( $fields = $ps->fetchrow_hashref() ) {
$self->{permissions}->{ $fields->{chanid} } = int $fields->{level};
}
}
sub _storePermission {
my ( $self, $userId, $chanId, $level ) = @_;
my $ps = $self->{wrapper}->{dbh}->prepare(
'insert into permissions(
userid,
channelid,
level
)
values(
?,
?,
?
)
on duplicate key update level=?'
);
$ps->execute( $userId, $chanId, $level, $level );
if ( $ps->err ) {
print "[E] Error accessing the MySQL database...\n\t$ps->errstr)";
}
else {
#TODO!
}
}
sub setUsername {
my ( $self, $new ) = @_;
$self->{user} = $new;
}
sub getLastLogin {
my $self = @_;
return $self->{lastlogin};
}
sub login {
my ( $wrapper, $server, $username, $identity, $host, $password ) = @_;
$password = sha512_hex($password);
my $ps = $wrapper->{dbd}->prepare(
'select
lastlogin, id
from
users
where
username = ? AND password = ?'
);
my $result = $ps->execute( $username, $password );
if ( $ps->err ) {
print "[E] Error accessing the MySQL database...\n\t$ps->errstr)";
}
else {
my $result = $ps->fetchrow_hashref();
return 0 unless defined $result;
$wrapper->post( $result->{lastlogin}, "Some more shit here" );
my $user =
new Saphira::API::User( $wrapper, $server, $result->{id}, $username,
$identity, $host, $result->{lastlogin} );
#TODO: Search for permissions and put them in the object
$server->addUser($user);
return $user;
}
}
sub logout {
my $self = @_;
return $self->{server}->removeUser($self);
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment