diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py
index b271bd9dbd47d191c1bafd81a757b56767d75781..5da8e5fa6390ea28acd373d98f610e6335360396 100644
--- a/addons/website_slides/controllers/main.py
+++ b/addons/website_slides/controllers/main.py
@@ -293,16 +293,29 @@ class WebsiteSlides(http.Controller):
                 values['category_id'] = post['category_id'][0]
 
         # handle exception during creation of slide and sent error notification to the client
-        # otherwise client slide create dialog box continue processing even server fail to create a slide.
+        # otherwise client slide create dialog box continue processing even server fail to create a slide
         try:
-            slide_id = request.env['slide.slide'].create(values)
+            channel = request.env['slide.channel'].browse(values['channel_id'])
+            can_upload = channel.can_upload
+            can_publish = channel.can_publish
+        except (UserError, AccessError) as e:
+            _logger.error(e)
+            return {'error': e.name}
+        else:
+            if not can_upload:
+                return {'error': _('You cannot upload on this channel.')}
+
+        try:
+            values['user_id'] = request.env.uid
+            values['website_published'] = values.get('website_published', False) and can_publish
+            slide = request.env['slide.slide'].sudo().create(values)
         except (UserError, AccessError) as e:
             _logger.error(e)
             return {'error': e.name}
         except Exception as e:
             _logger.error(e)
             return {'error': _('Internal server error, please try again later or contact administrator.\nHere is the error message: %s') % e}
-        return {'url': "/slides/slide/%s" % (slide_id.id)}
+        return {'url': "/slides/slide/%s" % (slide.id)}
 
     @http.route(['/slides/tag/search_read'], type='json', auth='user', methods=['POST'], website=True)
     def slide_tag_search_read(self, fields, domain):
diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py
index 15d9d7a6fe646ddabf458d3d3451a3dd5c76cd2d..300cb84f1f32a191d4879399ab177c764e8559e4 100644
--- a/addons/website_slides/models/slide_channel.py
+++ b/addons/website_slides/models/slide_channel.py
@@ -106,6 +106,7 @@ class Channel(models.Model):
         string='Upload Groups', help="Groups allowed to upload presentations in this channel. If void, every user can upload.")
     # not stored access fields, depending on each user
     can_upload = fields.Boolean('Can Upload', compute='_compute_access')
+    can_publish = fields.Boolean('Can Publish', compute='_compute_access')
 
     @api.depends('custom_slide_id', 'promote_strategy', 'slide_ids.likes',
                  'slide_ids.total_views', "slide_ids.date_published")
@@ -164,6 +165,7 @@ class Channel(models.Model):
     @api.depends('visibility', 'partner_ids', 'upload_group_ids')
     def _compute_access(self):
         self.can_upload = not self.env.user.share and (not self.upload_group_ids or bool(self.upload_group_ids & self.env.user.groups_id))
+        self.can_publish = self.can_upload and self.env.user.has_group('website.group_website_publisher')
 
     @api.multi
     @api.depends('name')
diff --git a/addons/website_slides/models/slide_slide.py b/addons/website_slides/models/slide_slide.py
index ac74567e66bd8d168dd569b54ac35f49d6d101e6..12adf7125fb973d25dfc83d6609e15e080c79c6e 100644
--- a/addons/website_slides/models/slide_slide.py
+++ b/addons/website_slides/models/slide_slide.py
@@ -92,6 +92,7 @@ class Slide(models.Model):
     # description
     name = fields.Char('Title', required=True, translate=True)
     active = fields.Boolean(default=True)
+    user_id = fields.Many2one('res.users', string='Uploaded by', default=lambda self: self.env.uid)
     description = fields.Text('Description', translate=True)
     channel_id = fields.Many2one('slide.channel', string="Channel", required=True)
     category_id = fields.Many2one('slide.category', string="Category", domain="[('channel_id', '=', channel_id)]")
@@ -218,6 +219,12 @@ class Slide(models.Model):
 
     @api.model
     def create(self, values):
+        # Do not publish slide if user has not publisher rights
+        channel = self.env['slide.channel'].browse(values['channel_id'])
+        if not channel.can_publish:
+            values['website_published'] = False
+            values['date_published'] = False
+
         if not values.get('index_content'):
             values['index_content'] = values.get('description')
         if values.get('slide_type') == 'infographic' and not values.get('image'):
@@ -228,15 +235,18 @@ class Slide(models.Model):
             doc_data = self._parse_document_url(values['url']).get('values', dict())
             for key, value in doc_data.items():
                 values.setdefault(key, value)
-        # Do not publish slide if user has not publisher rights
-        if not self.user_has_groups('website.group_website_publisher'):
-            values['website_published'] = False
+
         slide = super(Slide, self).create(values)
-        slide._post_publication()
+
+        if slide.website_published:
+            slide._post_publication()
         return slide
 
     @api.multi
     def write(self, values):
+        if values.get('website_published') and any(not slide.channel_id.can_publish for slide in self):
+            values.pop('website_published')
+
         if values.get('url') and values['url'] != self.url:
             doc_data = self._parse_document_url(values['url']).get('values', dict())
             for key, value in doc_data.items():
diff --git a/addons/website_slides/static/src/js/slides_upload.js b/addons/website_slides/static/src/js/slides_upload.js
index 5db2c3c5326e8c4ed9ae6818e70c7a2770a6fd64..30dc8c9547a078547b9680a370c756825d1bf6e7 100644
--- a/addons/website_slides/static/src/js/slides_upload.js
+++ b/addons/website_slides/static/src/js/slides_upload.js
@@ -24,11 +24,14 @@ var SlideDialog = Widget.extend({
     /**
      * @override
      * @param {Object} el
-     * @param {number} channel_id
+     * @param {Object} data holding channelId and optionally upload and publish control parameters
      */
-    init: function (el, channelID) {
-        this._super(el, channelID);
-        this.channel_id = parseInt(channelID, 10);
+    init: function (el, data) {
+        this._super(el, data);
+        this.channelId = parseInt(data.channelId, 10);
+        this.canUpload = data.canUpload === 'True';
+        this.canPublish = data.canPublish === 'True';
+        console.log(this.channelId, this.canUpload, this.canPublish);
         this.file = {};
         this.index_content = '';
     },
@@ -56,7 +59,7 @@ var SlideDialog = Widget.extend({
         return this._rpc({
             model: 'slide.slide',
             method: 'search_count',
-            args: [[['channel_id', '=', self.channel_id], ['name', '=', fileName]]],
+            args: [[['channel_id', '=', self.channelId], ['name', '=', fileName]]],
         });
     },
     /**
@@ -156,7 +159,7 @@ var SlideDialog = Widget.extend({
                     route: '/slides/category/search_read',
                     params: {
                         fields: ['name'],
-                        domain: [['channel_id', '=', self.channel_id]],
+                        domain: [['channel_id', '=', self.channelId]],
                     }
                 });
             }));
@@ -224,7 +227,7 @@ var SlideDialog = Widget.extend({
     _getValue: function () {
         var canvas = this.$('#data_canvas')[0],
             values = {
-                'channel_id': this.channel_id || '',
+                'channel_id': this.channelId || '',
                 'name': this.$('#name').val(),
                 'url': this.$('#url').val(),
                 'description': this.$('#description').val(),
@@ -418,7 +421,7 @@ var SlideDialog = Widget.extend({
         var self = this,
             value = {
                 'url': $(ev.target).val(),
-                'channel_id': self.channel_id
+                'channel_id': self.channelId
             };
         this.$('.alert-warning').remove();
         this.is_valid_url = false;
@@ -454,7 +457,7 @@ sAnimations.registry.websiteSlidesUpload = sAnimations.Class.extend({
     start: function () {
         // Automatically open the upload dialog if requested from query string
         if ($.deparam.querystring().enable_slide_upload !== undefined) {
-            this._openDialog(this.$el.attr('channel_id'));
+            this._openDialog(this.$el);
         }
         return this._super.apply(this, arguments);
     },
@@ -463,8 +466,9 @@ sAnimations.registry.websiteSlidesUpload = sAnimations.Class.extend({
     // Private
     //--------------------------------------------------------------------------
 
-    _openDialog: function (channelID) {
-        new SlideDialog(this, channelID).appendTo(document.body);
+    _openDialog: function ($element) {
+        var data = $element.data();
+        new SlideDialog(this, data).appendTo(document.body);
     },
 
     //--------------------------------------------------------------------------
@@ -476,7 +480,7 @@ sAnimations.registry.websiteSlidesUpload = sAnimations.Class.extend({
      * @param {Event} ev
      */
     _onUploadClick: function (ev) {
-        this._openDialog($(ev.currentTarget).attr('channel_id'));
+        this._openDialog($(ev.currentTarget));
     },
 });
 });
diff --git a/addons/website_slides/static/src/xml/website_slides.xml b/addons/website_slides/static/src/xml/website_slides.xml
index 5d9f8366a0cac7dee9f5470ca538da9e09f32e75..4283291b9566acc6fe439d56a86809bd2c6105d7 100644
--- a/addons/website_slides/static/src/xml/website_slides.xml
+++ b/addons/website_slides/static/src/xml/website_slides.xml
@@ -67,8 +67,9 @@
                     </main>
                     <footer class="modal-footer">
                         <button type="button" class="btn btn-secondary" data-dismiss="modal">Discard</button>
-                        <button type="button" data-loading-text="Loading..." class="btn btn-primary save">Save as Draft</button>
-                        <button type="button" data-loading-text="Loading..." data-published="true" class="btn btn-primary save">Save and Publish</button>
+                        <button type="button" data-loading-text="Loading..." t-if="widget.canUpload &amp;&amp; widget.canPublish" class="btn btn-primary save">Save as Draft</button>
+                        <button type="button" data-loading-text="Loading..." t-if="widget.canUpload &amp;&amp; ! widget.canPublish" class="btn btn-primary save">Submit</button>
+                        <button type="button" data-loading-text="Loading..." t-if="widget.canUpload &amp;&amp; widget.canPublish" data-published="true" class="btn btn-primary save">Publish</button>
                     </footer>
                 </div>
             </div>
diff --git a/addons/website_slides/views/website_slides_templates.xml b/addons/website_slides/views/website_slides_templates.xml
index 42458fb47d86b89efc39edf5587344293debafd6..d7446b5dc632ac15320484578dbe0511ddef1cfe 100644
--- a/addons/website_slides/views/website_slides_templates.xml
+++ b/addons/website_slides/views/website_slides_templates.xml
@@ -108,9 +108,12 @@
                         <t t-if="category">
                             / <a t-attf-href="/slides/#{slug(channel)}/category/#{slug(category)}" t-esc="category.name"/>
                         </t>
-                        <!-- Public user has not right to create/write on slide -->
                         <t t-if="channel.can_upload">
-                            <a role="button" class="btn btn-primary oe_slide_js_upload" title="Upload Presentation" t-attf-channel_id="#{channel.id}" aria-label="Upload Presentation" href="#">
+                            <a role="button" class="btn btn-primary oe_slide_js_upload" title="Upload Presentation"
+                                aria-label="Upload Presentation" href="#"
+                                t-att-data-channel-id="channel.id"
+                                t-att-data-can-upload="channel.can_upload"
+                                t-att-data-can-publish="channel.can_publish">
                                 <i class="fa fa-cloud-upload"></i> Upload
                             </a>
                         </t>
@@ -286,7 +289,7 @@
                                 </p>
                                 <p>
                                     <!-- Public user has not right to create/write on slide-->
-                                    <a role="button" t-if="channel.can_upload" class="btn btn-primary oe_slide_js_upload" t-attf-channel_id="#{channel.id}" aria-label="Upload Presentation" title="Upload Presentation" href="#">
+                                    <a role="button" t-if="channel.can_upload" class="btn btn-primary oe_slide_js_upload" t-attf-channel-id="#{channel.id}" aria-label="Upload Presentation" title="Upload Presentation" href="#">
                                         <i class="fa fa-cloud-upload"></i> Upload
                                     </a>
                                 </p>