diff --git a/lib/PiTube.pm b/lib/PiTube.pm
index 1af164fb76898ff6bf6e2cb12b71aa031c6c4eaf..b981697e02005b5bc4addac56bc77d6fb955e8c0 100644
--- a/lib/PiTube.pm
+++ b/lib/PiTube.pm
@@ -21,6 +21,7 @@ sub startup {
 
     my $home = Mojo::Home->new()->detect;
 
+    # migrace schematu
     my $pg = Mojo::Pg->new
         ->dsn($cfg->{database}{dsn})
         ->username($cfg->{database}{user})
@@ -31,39 +32,31 @@ sub startup {
 
     # Spojeni s databazi
     my $schema = PiTube::Schema->connect($cfg->{database});
-
     $self->helper( schema => sub { return $schema; } );
 
     $self->plugin('authentication', {
         autoload_user => 1,
         load_user => sub {
             my $c = shift;
-            return $c->schema->resultset('User')->find({
-                uuid => $c->session->{oauth}{sub}
-            });
+            return $c->session->{user};
         },
         validate_user => sub {
             my $c = shift;
-            return undef if ! $c->session->{oauth};
-            return $c->session->{oauth}{sub};
+            return undef if ! $c->session->{user};
+            return $c->session->{user}{id};
         },
     });
 
     $self->plugin('Authorization' => {
         is_role     => sub {
             my ($c, $role, $extradata) = @_;
-            return 0 if ! $c->session->{oauth};
 
-            my $client = 'pitube';
-            if ( $role =~ s/\@(.+)$// ) {
-                $client = $1;
-            }
-            return 0 if ! $c->session->{oauth}{resource_access}{$client};
+            return 0 if ! $c->session->{user};
+            my %user_roles = map { $_ => 1 } @{ $c->session->{user}{roles} };
 
-            my %client_roles = map { $_ => 1 }
-                @{ $c->session->{oauth}{resource_access}{$client}{roles} };
+            $role .= '@' . $cfg->{oauth2}{client_id} if $role !~ /\@/;
 
-            return exists $client_roles{$role} ? 1 : 0;
+            return exists $user_roles{$role} ? 1 : 0;
         },
         user_privs  => sub {},
         has_priv    => sub {},
diff --git a/lib/PiTube/Controller/OAuth2.pm b/lib/PiTube/Controller/OAuth2.pm
index 79b100a33debfd2bb769ca895fefe28061fb68d0..c680a82c5ad2ef8bd48264d010817a9aef14de3b 100644
--- a/lib/PiTube/Controller/OAuth2.pm
+++ b/lib/PiTube/Controller/OAuth2.pm
@@ -12,18 +12,26 @@ sub callback {
     $c->session->{refresh_token}  = $token->refresh_token;
     my $claims  = $c->oauth_claims( $token->access_token );
 
-    my $user = $c->schema->resultset('User')->update_or_create({
+    $c->session->{user} = {
         uuid     => $claims->{sub},
         name     => $claims->{name},
         username => $claims->{preferred_username},
-    },
-    { key => 'uuid', }
+    };
+
+    my $user = $c->schema->resultset('User')->update_or_create(
+        $c->session->{user},
+        { key => 'uuid', }
     );
-    $user->set_token;
+    $user->set_token();
 
-    $c->session->{oauth}  = $claims;
-    $c->authenticate();
+    $c->session->{user}{id}    = $user->id;
+    $c->session->{user}{token} = $user->token;
+    $c->session->{user}{roles} = $c->oauth_roles($claims);
+    $c->session->{user}{acl} = $c->schema->resultset('ACL')->user_acl(
+        $c->session->{user}
+    );
 
+    $c->authenticate();
     $c->redirect_to('/');
 }
 
@@ -31,7 +39,7 @@ sub do_logout { # nesmi se jmenovat logout - rekurze
     my $c = shift;
 
     $c->logout;
-    delete $c->session->{oauth};
+    delete $c->session->{user};
     $c->redirect_to('/');
 }
 
diff --git a/lib/PiTube/Controller/Stream.pm b/lib/PiTube/Controller/Stream.pm
index 8cf043f3a457ba50738f2a9419c91a0ceae658e7..5af18c211cbc7bf3b9bd45edd097f26c4d8fc8a6 100644
--- a/lib/PiTube/Controller/Stream.pm
+++ b/lib/PiTube/Controller/Stream.pm
@@ -26,6 +26,11 @@ sub list {
 sub player {
     my $c = shift;
 
+    # vzdy aktualizovat
+    $c->session->{user}{acl} = $c->schema->resultset('ACL')->user_acl(
+        $c->session->{user}
+    );
+
     # stream
     my $stream = $c->schema->resultset('Stream_view')->find({
         key => $c->stash->{key}
@@ -38,7 +43,7 @@ sub player {
 
     $c->stash->{stream} = $stream;
 
-    if ( ! $stream->is_granted($c) ) {
+    if ( ! $c->session->{user}{acl}{ $stream->name } ) {
         $c->render('stream/403');
         return;
     }
@@ -54,7 +59,7 @@ sub hls {
         return;
     }
 
-    my ($type, $file) = ($4, $c->req->url);
+    my ($key, $type, $file) = ($1, $4, $c->req->url);
 
     if ( ! -f $file ) {
         $c->render( status => 404, text => '' );
@@ -62,10 +67,7 @@ sub hls {
     }
 
     if ( $type eq 'ts' ) { # manifesty necheckujeme
-        my $stream = $c->schema->resultset('Stream')->find({ key => $1 });
-        $c->render( status => 404, text => '' ), return if ! $stream;
-
-        if ( ! $stream->is_granted($c) ) {
+        if ( ! $c->session->{user}{acl}{ $key } ) {
             $c->render( status => 403, text => '');
             return;
         }
diff --git a/lib/PiTube/Helpers/OAuth2.pm b/lib/PiTube/Helpers/OAuth2.pm
index d895f8f76c596d0e5748c06e2ab75d7719fcc63d..cca75a61fa3d0ac9d20dade9bcc28d601719aa55 100644
--- a/lib/PiTube/Helpers/OAuth2.pm
+++ b/lib/PiTube/Helpers/OAuth2.pm
@@ -66,6 +66,24 @@ sub register {
 
     });
 
+    $self->helper( oauth_roles => sub {
+        my $c      = shift;
+        my $claims = shift;
+
+        my @roles = ();
+
+        CLIENT:
+        foreach my $client ( keys %{ $claims->{resource_access} } ) {
+            ROLE:
+            foreach my $role ( @{ $claims->{resource_access}{$client}{roles} } ) {
+                push @roles, $role . '@' . $client;
+            }
+        }
+
+        return \@roles;
+
+    });
+
 }
 
 1;
diff --git a/lib/PiTube/Schema/Result/ACL.pm b/lib/PiTube/Schema/Result/ACL.pm
index 17708ee149bd5ed93dfa7e2944775c90aecf6427..7c62c3b6f7a701162087212d1fe8a8923bacb96b 100644
--- a/lib/PiTube/Schema/Result/ACL.pm
+++ b/lib/PiTube/Schema/Result/ACL.pm
@@ -25,5 +25,11 @@ __PACKAGE__->add_columns(
 
 __PACKAGE__->set_primary_key('id');
 
-1;
+__PACKAGE__->belongs_to(
+    stream => 'PiTube::Schema::Result::Stream',
+    {
+        'foreign.id' => 'self.stream_id',
+    },
+);
 
+1;
diff --git a/lib/PiTube/Schema/Result/Stream.pm b/lib/PiTube/Schema/Result/Stream.pm
index 3a9cfee6a0c599b2a20abab80c738645ba109477..5936a5366ccad1003aece67db1c8edab6f6e94ec 100644
--- a/lib/PiTube/Schema/Result/Stream.pm
+++ b/lib/PiTube/Schema/Result/Stream.pm
@@ -40,31 +40,4 @@ __PACKAGE__->has_many(
     },
 );
 
-sub is_granted {
-    my $self = shift;
-    my $c    = shift;
-
-    return 1 if $self->is_public;
-
-    my $granted = 0;
-
-    ACL:
-    foreach my $acl ( $self->acls ) {
-
-        if ( $acl->class eq 'all' ) {
-            $granted = 1;
-        }
-        elsif ( $acl->class eq 'role') {
-            $granted = 1 if $c->is( $acl->value );
-        }
-        elsif ( $acl->class eq 'user' ) {
-            $granted = 1 if $acl->value eq $c->current_user->uuid;
-        }
-        last ACL if $granted;
-    }
-
-    return $granted;
-
-}
-
 1;
diff --git a/templates/stream/403.html.ep b/templates/stream/403.html.ep
index 69c6705abb6cc522b114025e081d302457ad0502..42dba1bcb5068c57e198c3b23639c6859e7f9de8 100644
--- a/templates/stream/403.html.ep
+++ b/templates/stream/403.html.ep
@@ -5,6 +5,6 @@ Nemáte oprávnění ke sledování streamu <strong>"<%= $c->stash->{stream}->na
 </p>
 % if ( $c->is('publisher')) {
 <p>
-stream rtp url:  <%= $c->config->{rtmp}{base_url} %>/<%= $c->stash->{stream}->key %>?token=<%= $c->current_user->token %>
+stream rtp url:  <%= $c->config->{rtmp}{base_url} %>/<%= $c->stash->{stream}->key %>?token=<%= $c->current_user->{token} %>
 </p>
 % }