Ltix.MembershipsService (Ltix v0.2.0)

Copy Markdown View Source

Query context membership (roster) from a platform using the Names and Roles Provisioning Service (NRPS) v2.0.

Given a successful LTI 1.3 launch that includes the memberships endpoint claim, retrieve the list of users enrolled in the course or resource link.

From a launch context

{:ok, client} = Ltix.MembershipsService.authenticate(launch_context)
{:ok, roster} = Ltix.MembershipsService.list_members(client)

Enum.each(roster, fn member ->
  IO.puts("#{member.name}: #{inspect(member.roles)}")
end)

From a registration

alias Ltix.LaunchClaims.MembershipsEndpoint

{:ok, client} = Ltix.MembershipsService.authenticate(registration,
  endpoint: MembershipsEndpoint.new!("https://lms.example.com/memberships")
)

{:ok, roster} = Ltix.MembershipsService.list_members(client, role: :learner)

Streaming large rosters

{:ok, stream} = Ltix.MembershipsService.stream_members(client)

stream
|> Stream.filter(&(&1.status == :active))
|> Enum.each(&process_member/1)

Summary

Functions

Acquire an OAuth token for the memberships service.

Fetch all members from the memberships endpoint.

Same as list_members/2 but raises on error.

Fetch members as a lazy stream.

Functions

authenticate(context_or_registerable, opts \\ [])

@spec authenticate(Ltix.LaunchContext.t() | Ltix.Registerable.t(), keyword()) ::
  {:ok, Ltix.OAuth.Client.t()} | {:error, Exception.t()}

Acquire an OAuth token for the memberships service.

Accepts a %LaunchContext{} or any struct implementing Ltix.Registerable (including Ltix.Registration). With a launch context, the endpoint is extracted from the launch claims. With a registration, pass the endpoint via the :endpoint option.

From a launch context

{:ok, client} = Ltix.MembershipsService.authenticate(launch_context)

From a registration

{:ok, client} = Ltix.MembershipsService.authenticate(registration,
  endpoint: MembershipsEndpoint.new!("https://lms.example.com/memberships")
)

Options (launch context)

  • :req_options (keyword/0) - Options passed through to Req.request/2. The default value is [].

  • :local_network_access (nil | :none | :local | :loopback) - Addresses platform requests may connect to besides public ones. :local adds private network addresses, and :loopback adds those and this machine. Defaults to config :ltix, :local_network_access, then :none.

  • :storage_adapter (module/0) - Module implementing Ltix.StorageAdapter, which signs token requests. Defaults to the application configuration.

  • :storage_adapter_options (keyword/0) - Options passed to the storage adapter's signing callbacks. The default value is [].

  • :require_all_scopes (boolean/0) - Return a ScopeMismatch error unless every scope the endpoints need was granted. The default value is false.

Options (registration)

  • :endpoint (struct of type Ltix.LaunchClaims.MembershipsEndpoint) - Required. MembershipsEndpoint struct for the service endpoint.

  • :deployment (term/0) - The deployment the token is for, as a struct implementing Ltix.Deployable or a deployment ID. Token requests include it.

  • :req_options (keyword/0) - Options passed through to Req.request/2. The default value is [].

  • :local_network_access (nil | :none | :local | :loopback) - Addresses platform requests may connect to besides public ones. :local adds private network addresses, and :loopback adds those and this machine. Defaults to config :ltix, :local_network_access, then :none.

  • :storage_adapter (module/0) - Module implementing Ltix.StorageAdapter, which signs token requests. Defaults to the application configuration.

  • :storage_adapter_options (keyword/0) - Options passed to the storage adapter's signing callbacks. The default value is [].

  • :require_all_scopes (boolean/0) - Return a ScopeMismatch error unless every scope the endpoints need was granted. The default value is false.

authenticate!(context_or_registerable, opts \\ [])

Same as authenticate/2 but raises on error.

list_members(client, opts \\ [])

@spec list_members(Ltix.OAuth.Client.t(), keyword()) ::
  {:ok, Ltix.MembershipsService.MembershipContainer.t()}
  | {:error, Exception.t()}

Fetch all members from the memberships endpoint.

Follows all rel="next" pagination links and returns a complete %MembershipContainer{}. The container implements Enumerable, so you can pipe it directly into Enum or Stream functions.

Options

  • :endpoint (struct of type Ltix.LaunchClaims.MembershipsEndpoint) - Override the endpoint stored on the client.

  • :role (atom/0 | String.t/0 | struct of type Ltix.LaunchClaims.Role) - Filter by role. Accepts a role atom (e.g., :learner), URI string, %Role{} struct, or short name string (e.g., "Learner").

  • :resource_link_id (String.t/0) - Query resource link membership.

  • :per_page (integer/0) - Page size hint. The platform may return more or fewer than requested.

  • :max_members (integer/0 | :infinity) - Safety limit for eager fetch. Returns a CollectionTooLarge error if exceeded. Set to :infinity to disable. The default value is 10000.

list_members!(client, opts \\ [])

Same as list_members/2 but raises on error.

stream_members(client, opts \\ [])

@spec stream_members(Ltix.OAuth.Client.t(), keyword()) ::
  {:ok, Enumerable.t()} | {:error, Exception.t()}

Fetch members as a lazy stream.

Returns {:ok, stream} where each element is a %Member{}. Use this for large rosters where you want to process members incrementally or stop early. list_members/2 returns the whole roster. Later page failures and member parsing errors raise during enumeration.

Streams take no :max_members limit because they fetch one page at a time. Use Stream.take/2 to stop after a number of members.

Options

stream_members!(client, opts \\ [])

@spec stream_members!(Ltix.OAuth.Client.t(), keyword()) :: Enumerable.t()

Same as stream_members/2 but raises on error.