aboutsummaryrefslogtreecommitdiffstats
path: root/core/moduleapi.lua
Commit message (Collapse)AuthorAgeFilesLines
* moduleapi: Add luacheck annotation to suppress warning about unused selfMatthew Wild2023-04-011-1/+1
| | | | | This is a convenience function, and there is currently no module-specific code required to implement it. Not using 'self' is to be expected.
* moduleapi: Add module:once() to execute a function after module load/startupMatthew Wild2023-04-011-0/+5
| | | | | | | | | | It is a common pattern for modules to do something like check for prosody.start_time, and execute code immediately if it is present, or wait for the server-started event if it isn't yet. For example, this allows you to run code after all other modules/hosts have been loaded, that are going to be loaded. Such code can now be replaced with a simple call to this method.
* moduleapi: Add 'peek' to :may() and new :could() helper to suppress loggingMatthew Wild2023-03-261-7/+19
| | | | | | | | | | | | | The current method logs scary "access denied" messages on failure - this is generally very useful when debugging access control stuff, but in some cases the call is simply a check to see if someone *could* perform an action, even if they haven't requested it yet. One example is determining whether to show the user as an admin in disco. The 'peek' parameter, if true, will suppress such logging. The :could() method is just a simple helper that can make the calling code a bit more readable (suggested by Zash).
* moduleapi: may: Fail early if a local session has no role assignedMatthew Wild2023-03-251-3/+8
| | | | | | | We expect every session to explicitly have a role assigned. Falling back to any kind of "default" role (even the user's default role) in the absence of an explicit role could open up the possibility of accidental privilege escalation.
* core: Prefix module imports with prosody namespaceKim Alvefur2023-03-171-22/+22
|
* core.moduleapi: Record reverse dependenciesKim Alvefur2023-03-051-0/+4
| | | | | Useful to know why a module was auto-loaded without having to dig trough all other modules for the one that depends on it.
* core.moduleapi: Fix passing variable to loggingKim Alvefur2023-01-311-1/+1
|
* core.moduleapi: Check for local role-aware sessions before e.g. s2sKim Alvefur2022-08-291-9/+9
| | | | | The condition checked for s2sin but not s2sout, so would have ignored bidi-enabled s2sout sessions. Components as well.
* mod_authz_internal, and more: New iteration of role APIMatthew Wild2022-08-171-1/+2
| | | | | | | | | | | These changes to the API (hopefully the last) introduce a cleaner separation between the user's primary (default) role, and their secondary (optional) roles. To keep the code sane and reduce complexity, a data migration is needed for people using stored roles in 0.12. This can be performed with prosodyctl mod_authz_internal migrate <host>
* moduleapi: Stricter type check for actor in permission checkKim Alvefur2022-07-201-1/+1
| | | | | Non-table but truthy values would trigger "attempt to index a foo value" on the next line otherwise
* moduleapi: Remove redundant expansion of ':' prefix in permission namesKim Alvefur2022-07-201-1/+0
|
* moduleapi: Distribute permissions set from global modules to all hostsKim Alvefur2022-07-201-0/+8
| | | | | | Roles and permissions will always happen in the context of a host. Prevents error upon indexing since `hosts["*"] == nil`
* core.moduleapi: Expand permission name ':' prefix earlierKim Alvefur2022-06-151-3/+3
| | | | | | Ensures it applies to the context as string case Somehow this fixes everything
* core.moduleapi: Fixup method nameKim Alvefur2022-06-151-1/+1
| | | | | | `get_user_role()` did not exist anywhere else. MattJ said `get_user_default_role()` was indented
* Switch to a new role-based authorization framework, removing is_admin()Matthew Wild2022-06-151-0/+63
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We began moving away from simple "is this user an admin?" permission checks before 0.12, with the introduction of mod_authz_internal and the ability to dynamically change the roles of individual users. The approach in 0.12 still had various limitations however, and apart from the introduction of roles other than "admin" and the ability to pull that info from storage, not much actually changed. This new framework shakes things up a lot, though aims to maintain the same functionality and behaviour on the surface for a default Prosody configuration. That is, if you don't take advantage of any of the new features, you shouldn't notice any change. The biggest change visible to developers is that usermanager.is_admin() (and the auth provider is_admin() method) have been removed. Gone. Completely. Permission checks should now be performed using a new module API method: module:may(action_name, context) This method accepts an action name, followed by either a JID (string) or (preferably) a table containing 'origin'/'session' and 'stanza' fields (e.g. the standard object passed to most events). It will return true if the action should be permitted, or false/nil otherwise. Modules should no longer perform permission checks based on the role name. E.g. a lot of code previously checked if the user's role was prosody:admin before permitting some action. Since many roles might now exist with similar permissions, and the permissions of prosody:admin may be redefined dynamically, it is no longer suitable to use this method for permission checks. Use module:may(). If you start an action name with ':' (recommended) then the current module's name will automatically be used as a prefix. To define a new permission, use the new module API: module:default_permission(role_name, action_name) module:default_permissions(role_name, { action_name[, action_name...] }) This grants the specified role permission to execute the named action(s) by default. This may be overridden via other mechanisms external to your module. The built-in roles that developers should use are: - prosody:user (normal user) - prosody:admin (host admin) - prosody:operator (global admin) The new prosody:operator role is intended for server-wide actions (such as shutting down Prosody). Finally, all usage of is_admin() in modules has been fixed by this commit. Some of these changes were trickier than others, but no change is expected to break existing deployments. EXCEPT: mod_auth_ldap no longer supports the ldap_admin_filter option. It's very possible nobody is using this, but if someone is then we can later update it to pull roles from LDAP somehow.
* compat: Use table.pack (there since Lua 5.2) over our util.tableKim Alvefur2022-07-111-1/+1
| | | | | Added in d278a770eddc avoid having to deal with its absence in Lua 5.1. No longer needed when Lua 5.1 support is dropped.
* compat: Remove handling of Lua 5.1 location of 'unpack' functionKim Alvefur2022-07-111-1/+1
|
* core.moduleapi: Fix 'global' property via :context() - #1748Kim Alvefur2022-04-271-1/+1
| | | | | | | | | | The 'global' property should reflect whether the module API instance represents the global context or a VirtualHost or Component context. However the module:context() method did not override this, leading the property of the previous module shining trough, leading to bugs in code relying on the 'global' property. See also #1736
* modulemanager, moduleapi: Switch to new pluginloader interfaceMatthew Wild2022-02-041-2/+2
|
* moduleapi: Support stripping of multi-word from module namesMatthew Wild2021-12-221-1/+1
| | | | | | The goal is to allow module:provides("foo-bar") with a mod_foo_bar_ prefix being stripped. It will break any existing modules that use a prefix and have hyphens instead of underscores. No such modules are known.
* mod_cron: Add a 'weekly' job frequencyKim Alvefur2021-12-031-0/+5
|
* core.moduleapi: Add API for adding daily or hourly tasks via mod_cronKim Alvefur2021-11-211-0/+15
|
* mod_admin_shell: List collected metrics in module:infoKim Alvefur2021-11-241-0/+2
| | | | Lets you know what to look for with stats:show()
* core.moduleapi: Fix name of renamed API in log messageKim Alvefur2021-11-181-1/+1
| | | | | | | hook_stanza was renamed hook_tag in 2012 in 2087d42f1e77 Why do we still have hook_stanza? Why is this only a warning anyway?
* core.moduleapi: Ensure module:send_iq() handler priority over mod_iqKim Alvefur2021-09-241-2/+2
| | | | | | To prevent a situation where you for whatever reason use a full JID that is currently online and the response ends up routed there instead of the module:send_iq() handlers.
* core.moduleapi: Enable full JID origin queries with module:send_iq()Kim Alvefur2021-09-241-2/+11
| | | | | Since we don't currently have hooks that includes type and id here, we need to check those attributes in the handlers.
* core.moduleapi: Filter out unrelated direct replies to module:send_iqKim Alvefur2021-09-241-1/+4
| | | | | | | | | | | This is primarily something that happens with an internal query to mod_mam, which calls origin.send() several times with results, leading to the first such result being treated as the final response and resolving the promise. Now, these responses pass trough to the underlying origin.send(), where they can be caught. Tricky but not impossible. For remote queries, it's even trickier, you would likely need to bind a resource or similar.
* Statistics: Rewrite statistics backends to use OpenMetricsJonas Schäfer2021-04-181-19/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The metric subsystem of Prosody has had some shortcomings from the perspective of the current state-of-the-art in metric observability. The OpenMetrics standard [0] is a formalization of the data model (and serialization format) of the well-known and widely-used Prometheus [1] software stack. The previous stats subsystem of Prosody did not map well to that format (see e.g. [2] and [3]); the key reason is that it was trying to do too much math on its own ([2]) while lacking first-class support for "families" of metrics ([3]) and structured metric metadata (despite the `extra` argument to metrics, there was no standard way of representing common things like "tags" or "labels"). Even though OpenMetrics has grown from the Prometheus world of monitoring, it maps well to other popular monitoring stacks such as: - InfluxDB (labels can be mapped to tags and fields as necessary) - Carbon/Graphite (labels can be attached to the metric name with dot-separation) - StatsD (see graphite when assuming that graphite is used as backend, which is the default) The util.statsd module has been ported to use the OpenMetrics model as a proof of concept. An implementation which exposes the util.statistics backend data as Prometheus metrics is ready for publishing in prosody-modules (most likely as mod_openmetrics_prometheus to avoid breaking existing 0.11 deployments). At the same time, the previous measure()-based API had one major advantage: It is really simple and easy to use without requiring lots of knowledge about OpenMetrics or similar concepts. For that reason as well as compatibility with existing code, it is preserved and may even be extended in the future. However, code relying on the `stats-updated` event as well as `get_stats` from `statsmanager` will break because the data model has changed completely; in case of `stats-updated`, the code will simply not run (as the event was renamed in order to avoid conflicts); the `get_stats` function has been removed completely (so it will cause a traceback when it is attempted to be used). Note that the measure_*_event methods have been removed from the module API. I was unable to find any uses or documentation and thus deemed they should not be ported. Re-implementation is possible when necessary. [0]: https://openmetrics.io/ [1]: https://prometheus.io/ [2]: #959 [3]: #960
* core.moduleapi: Return resource path from module:get_directory() (API BC)Kim Alvefur2020-10-091-2/+2
| | | | | | | | | | | | | | | | | | | :get_directory has so far returned the base directory of the current module source code. This has worked well so far to load resources which tend to be included in the same directory, but with the plugin installer using LuaRocks, extra resources (e.g. templates and other assets) these are saved in a completely different directory. In be73df6765b9 core.modulemanager gained some code for finding that directory and saving it in module.resource_path but now the question is how this should be reflected in the API. A survey of community modules suggest the vast majority use the :get_directory method for locating templates and other assets, rather than the code (which would use module:require instead). Therefore this commit changes :get_directory to return the resource_path when available. This should work for most modules.
* core.moduleapi: Use resource path for :load_resource()Kim Alvefur2020-10-071-1/+1
|
* core.moduleapi: Allow passing a config table trough :measureKim Alvefur2019-01-041-2/+2
|
* moduleapi: Rename argument to silence luacheckKim Alvefur2020-04-011-2/+2
|
* moduleapi: Fix handling of replies to :send_iq from internal modulesKim Alvefur2020-03-221-1/+10
| | | | | Unclear exactly why, but replies to some queries to local modules would be discarded by stanza_router. This appears to fix it.
* core.moduleapi: Hook correct event type in some casesKim Alvefur2020-01-161-1/+2
| | | | | In rare cases, module.host can be a bare JID, in which case this test did the wrong thing.
* core.moduleapi: Rename local name for util.error for consistencyKim Alvefur2019-12-301-6/+6
| | | | It's called 'errors' everywhere else except here.
* core.moduleapi: Fix error context in :send_iq APIKim Alvefur2019-12-301-1/+1
| | | | | It got passed as argument to reject() instead of the util.error function and was lost.
* core.moduleapi: Restructure send_iq method for more atomic cleanupKim Alvefur2019-08-211-16/+23
| | | | | All cleanup in one spot instead of two, and at the end which fits with cleanup happening afterwards.
* core.moduleapi: Uppercase "IQ stanza" for consistencyKim Alvefur2019-08-211-1/+1
| | | | It's written like that elsewhere in the send_iq method
* moduleapi: Log suppressed status priority and message when not overridingMatthew Wild2019-03-261-1/+1
|
* moduleapi: Remove overly-verbose debug logging on module status changeMatthew Wild2019-03-261-1/+0
|
* moduleapi: New API for modules to set a statusMatthew Wild2019-03-191-0/+31
|
* core.moduleapi: Use convenience function for creating error object from stanzaKim Alvefur2018-12-301-3/+1
|
* core.moduleapi: Use util.error for :send_iq errorsKim Alvefur2018-12-301-5/+21
|
* core.moduleapi: Move util imports to topKim Alvefur2018-12-301-2/+4
|
* core.moduleapi: Add a promise-based API for tracking IQ stanzas (fixes #714)Kim Alvefur2018-12-281-0/+65
|
* moduleapi: Use pack from util.tableKim Alvefur2018-12-081-1/+1
|
* moduleapi: Prevent loading disabled module as dependency of enabled oneKim Alvefur2018-10-251-3/+3
| | | | Explicitly disabled module should stay disabled.
* core.moduleapi: Remove redundant conditionKim Alvefur2018-10-181-1/+1
|
* moduleapi: Remove multiple-parameters feature from module:shared()Matthew Wild2018-08-081-25/+24
| | | | | | Multiple paths are rarely used, and leads to less clear code than just calling module:shared() once per shared table. It also prevents us from extending the API with new parameters in the future.
* moduleapi: Use :send API from :broadcast for compactnessKim Alvefur2018-07-141-1/+1
|