TIP: You can type at any time to perform a new search.

Security findings

Repository
OCA/social · module folder · Try on Runboat
Module version
1.0.0
Category
Social Network
Folder size
1.14 MB
License
AGPL-3
Application
No
Auto-installable
No
Website
https://github.com/OCA/social
Last tracking update
2026-09-16 17:07:12
Authors
Odoo Community Association (OCA), Binhex
Maintainers
Odoo Community Association (OCA), Binhex
Committers
Weblate, OCA-git-bot, Edilio Escalona Almira
Odoo dependencies
OCA/social:
odoo/odoo:
- utm
- web
- bus
Python dependencies
None
System dependencies
None
Required by
None
Description
This module publishes on the LinkedIn company pages an Odoo user
administrates, and keeps the daily figures of those pages.

Everything it asks LinkedIn for costs a fixed number of calls per account or
per publication, so what it costs does not change whether a page published
once or ten thousand times. Reading back what the page already published ---
importing the publications, their comments and their reactions --- grows with
that history and lives in *Social Media LinkedIn Sync*, which installs on its
own as soon as *Social Media Sync* is present.

Main features:
- Integration of the LinkedIn company pages (organizations) the user
  administrates; personal profiles are not supported.
- Post creation, with images or a video: LinkedIn publishes either the images
  or the video, never both.
- Daily statistics of the page: the figures LinkedIn reports by day are
  written as a time series, with reports and native graph and pivot views over
  them. It costs a fixed number of calls per account, decided by the width of
  the window asked for and not by what the page published: one call for the
  refresh of the last days, a handful for the whole period LinkedIn reports,
  because the figures asked for are those of the whole organization and the
  URNs of the publications never enter the query.
- What LinkedIn will not publish, shown on the post while it is written. The
  message is checked against **3000 characters**, and the medias against **20
  images** of at most **10 MB** each in JPG, PNG or GIF, and **one video** of
  at most **500 MB** in MP4. A post carrying a video is published without its
  images, so with a video none of the image rules apply and the post is warned
  that only the video goes out. The same checks refuse the publication if the
  post reaches it anyway, through an import or an RPC call.


Statistics account
-------------------
1. The eye icon: Total number of views, which may include multiple views by the same user.
2. The hand icon: the interactions (clicks, likes, comments and shares) the
   page accumulated over the days of the series.
3. The star icon: the engagement of the account, its interactions over its
   impressions, shown as a percentage. The engagement LinkedIn reports by day
   is kept on each row of the time series and read in the graph and pivot
   views; it is never averaged into the card.

   ![STATISTICS_ACCOUNT](../static/img/readme/STATISTICS_ACCOUNT.png)

Code Analysis info_outline

Views touched (2)
XML IDNameModelTypeStatus
social_account_view_form_inherit social.account.view.form.inherit.linkedin social.account form Inherits social_media_base.social_account_view_form
wizard_social_account_view_form_inherit wizard.social.account.view.form.inherit.linkedin wizard.social.account form Inherits social_media_base.wizard_social_account_view_form
HTTP endpoints (1)
Route(s)HandlerAuthTypeMethodsFlags
/linkedin/callback SocialMediaLinkedin.social_linkedin user http ALL
Models touched (5)

New fields (5)
  • linkedin_account_id Char
    compute='_compute_linkedin_account_id' store=True
  • linkedin_client_id Char
    groups='base.group_system' string='Client ID'
  • linkedin_granted_scopes Char
    groups='base.group_system' help='Scopes LinkedIn granted to the token of this account, comma separated. The next authorization asks for the scopes the installed modules need plus the ones listed here, so a scope of a product enabled on the LinkedIn application afterwards can be added by hand. The change takes effect only once the account is authorized again with Update account and Update keys, since refreshing the token alone keeps the scopes the current token was granted. A scope that the products of the application do not grant makes LinkedIn refuse the whole authorization.' string='Granted Scopes'
  • linkedin_secret Char
    groups='base.group_system' string='Client Secret'
  • refresh_token_expires_in Date
    string='Expire Refresh Token'
Public methods (3)
  • action_rebuild_statistics_history(self)
    Ask LinkedIn again for the daily figures of the whole period. The backfill runs once and is skipped from then on, so this is the way back for an account whose history was never read: the call of the association failed, or the series was truncated before the range was asked for in as many calls as it takes. It rebuilds the graph of the account and imports no publication. The rows are added up onto the account right after writing them, so the card shows what was just read instead of what the last pass left.
  • action_update_account(self)
    Open the update wizard, proposing the Client ID when allowed. ``linkedin_client_id`` is restricted to ``base.group_system``, and the context of an action is serialized to the browser, so the value is only proposed to the users that may read the field. The others simply type it again in the wizard, where it is editable and required.
  • validate_access_token(self)
    Renew the token of this account when its dates say it is due. A token is treated as expired a few days ahead of its date: the check runs before every publication and on the schedule of the updates cron, and a token renewed at the last moment is one that a post planned for the weekend would not find.

New fields (1)
  • media_type Selection
    ondelete={'linkedin': 'cascade'} selection_add=[('linkedin', 'LinkedIn')]
Public methods (1)
  • action_open_account(self)
    Open the wizard associating a LinkedIn account. No ``ensure_one`` here: every connector overrides this method and chains to the next one, so an empty recordset has to travel down to the hook of the base module instead of being refused on the way. Reading ``media_type`` already refuses a recordset of several media. :rtype: dict

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (2)
  • linkedin_client Char
    string='Client ID'
  • linkedin_secret Char
    string='Client Secret'
Public methods (0)

No public methods.

Status
Open migration PR — not merged yet for this version
CI status
checks failing
Open since
308 days ago
Last activity
72 days ago
Repository
OCA/social
Pull request
[18.0][MIG] social_media_linkedin: Migration to 18.0 (#1770)
Status
Open migration PR — not merged yet for this version
CI status
checks failing
Open since
268 days ago
Last activity
72 days ago
Repository
OCA/social
Pull request
[19.0][MIG] social_media_linkedin: Migration to 19.0 (#1790)