Coverage Summary for Class: TwitchScope (io.github.captnblubber.twitchkt.auth)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| TwitchScope |
100%
(2/2)
|
100%
(2/2)
|
100%
(96/96)
|
100%
(689/689)
|
| TwitchScope$Companion |
100%
(2/2)
|
100%
(6/6)
|
100%
(2/2)
|
100%
(40/40)
|
| Total |
100%
(4/4)
|
100%
(8/8)
|
100%
(98/98)
|
100%
(729/729)
|
package io.github.captnblubber.twitchkt.auth
/**
* Twitch OAuth2 scopes.
*
* Twitch uses a hierarchical scope model where `manage` scopes implicitly grant the
* corresponding `read` permission. For example, a token with `channel:manage:polls`
* satisfies endpoints that require `channel:read:polls`. This hierarchy is encoded via
* [implies] — the set of scopes that this scope implicitly grants.
*
* See: [Twitch OAuth Scopes](https://dev.twitch.tv/docs/authentication/scopes/)
*/
enum class TwitchScope(
val value: String,
) {
// Analytics
ANALYTICS_READ_EXTENSIONS("analytics:read:extensions"),
ANALYTICS_READ_GAMES("analytics:read:games"),
// Bits
BITS_READ("bits:read"),
// Channel
CHANNEL_BOT("channel:bot"),
CHANNEL_MANAGE_ADS("channel:manage:ads"),
CHANNEL_READ_ADS("channel:read:ads"),
CHANNEL_MANAGE_BROADCAST("channel:manage:broadcast"),
CHANNEL_READ_CHARITY("channel:read:charity"),
CHANNEL_EDIT_COMMERCIAL("channel:edit:commercial"),
CHANNEL_READ_EDITORS("channel:read:editors"),
CHANNEL_MANAGE_EXTENSIONS("channel:manage:extensions"),
CHANNEL_READ_GOALS("channel:read:goals"),
CHANNEL_READ_GUEST_STAR("channel:read:guest_star"),
CHANNEL_MANAGE_GUEST_STAR("channel:manage:guest_star"),
CHANNEL_READ_HYPE_TRAIN("channel:read:hype_train"),
CHANNEL_MANAGE_MODERATORS("channel:manage:moderators"),
CHANNEL_READ_POLLS("channel:read:polls"),
CHANNEL_MANAGE_POLLS("channel:manage:polls"),
CHANNEL_READ_PREDICTIONS("channel:read:predictions"),
CHANNEL_MANAGE_PREDICTIONS("channel:manage:predictions"),
CHANNEL_MANAGE_RAIDS("channel:manage:raids"),
CHANNEL_READ_REDEMPTIONS("channel:read:redemptions"),
CHANNEL_MANAGE_REDEMPTIONS("channel:manage:redemptions"),
CHANNEL_MANAGE_SCHEDULE("channel:manage:schedule"),
CHANNEL_READ_STREAM_KEY("channel:read:stream_key"),
CHANNEL_READ_SUBSCRIPTIONS("channel:read:subscriptions"),
CHANNEL_MANAGE_VIDEOS("channel:manage:videos"),
CHANNEL_READ_VIPS("channel:read:vips"),
CHANNEL_MANAGE_VIPS("channel:manage:vips"),
CHANNEL_MODERATE("channel:moderate"),
// Chat
CHAT_EDIT("chat:edit"),
CHAT_READ("chat:read"),
// Clips
CLIPS_EDIT("clips:edit"),
CHANNEL_MANAGE_CLIPS("channel:manage:clips"),
EDITOR_MANAGE_CLIPS("editor:manage:clips"),
// Moderation
MODERATION_READ("moderation:read"),
MODERATOR_MANAGE_ANNOUNCEMENTS("moderator:manage:announcements"),
MODERATOR_MANAGE_AUTOMOD("moderator:manage:automod"),
MODERATOR_READ_AUTOMOD_SETTINGS("moderator:read:automod_settings"),
MODERATOR_MANAGE_AUTOMOD_SETTINGS("moderator:manage:automod_settings"),
MODERATOR_MANAGE_BANNED_USERS("moderator:manage:banned_users"),
MODERATOR_READ_BLOCKED_TERMS("moderator:read:blocked_terms"),
MODERATOR_MANAGE_BLOCKED_TERMS("moderator:manage:blocked_terms"),
MODERATOR_MANAGE_CHAT_MESSAGES("moderator:manage:chat_messages"),
MODERATOR_READ_CHAT_SETTINGS("moderator:read:chat_settings"),
MODERATOR_MANAGE_CHAT_SETTINGS("moderator:manage:chat_settings"),
MODERATOR_READ_CHATTERS("moderator:read:chatters"),
MODERATOR_READ_FOLLOWERS("moderator:read:followers"),
MODERATOR_READ_GUEST_STAR("moderator:read:guest_star"),
MODERATOR_MANAGE_GUEST_STAR("moderator:manage:guest_star"),
MODERATOR_READ_SHIELD_MODE("moderator:read:shield_mode"),
MODERATOR_MANAGE_SHIELD_MODE("moderator:manage:shield_mode"),
MODERATOR_READ_SHOUTOUTS("moderator:read:shoutouts"),
MODERATOR_MANAGE_SHOUTOUTS("moderator:manage:shoutouts"),
MODERATOR_READ_UNBAN_REQUESTS("moderator:read:unban_requests"),
MODERATOR_MANAGE_UNBAN_REQUESTS("moderator:manage:unban_requests"),
MODERATOR_READ_WARNINGS("moderator:read:warnings"),
MODERATOR_MANAGE_WARNINGS("moderator:manage:warnings"),
MODERATOR_MANAGE_SUSPICIOUS_USERS("moderator:manage:suspicious_users"),
// User
USER_BOT("user:bot"),
USER_EDIT("user:edit"),
USER_EDIT_BROADCAST("user:edit:broadcast"),
USER_READ_BLOCKED_USERS("user:read:blocked_users"),
USER_MANAGE_BLOCKED_USERS("user:manage:blocked_users"),
USER_READ_BROADCAST("user:read:broadcast"),
USER_READ_CHAT("user:read:chat"),
USER_MANAGE_CHAT_COLOR("user:manage:chat_color"),
USER_READ_EMAIL("user:read:email"),
USER_READ_EMOTES("user:read:emotes"),
USER_READ_FOLLOWS("user:read:follows"),
USER_READ_MODERATED_CHANNELS("user:read:moderated_channels"),
USER_READ_SUBSCRIPTIONS("user:read:subscriptions"),
USER_READ_WHISPERS("user:read:whispers"),
USER_MANAGE_WHISPERS("user:manage:whispers"),
USER_WRITE_CHAT("user:write:chat"),
;
/**
* Scopes that this scope implicitly grants. A `manage` scope implies the corresponding
* `read` scope. For example, `channel:manage:polls` implies `channel:read:polls`.
*
* Special case: `channel:manage:moderators` implies `moderation:read` as documented
* by the Twitch API.
*/
val implies: Set<TwitchScope> by lazy { SCOPE_HIERARCHY[this] ?: emptySet() }
companion object {
fun fromValue(value: String): TwitchScope? = entries.find { it.value == value }
/**
* Checks whether the [granted] scopes satisfy the [required] scope, taking into
* account the scope hierarchy (manage implies read).
*/
fun isSatisfied(
required: TwitchScope,
granted: Set<TwitchScope>,
): Boolean = required in granted || granted.any { required in it.implies }
private val SCOPE_HIERARCHY: Map<TwitchScope, Set<TwitchScope>> =
mapOf(
// channel:manage:* implies channel:read:*
CHANNEL_MANAGE_ADS to setOf(CHANNEL_READ_ADS),
CHANNEL_MANAGE_GUEST_STAR to setOf(CHANNEL_READ_GUEST_STAR),
CHANNEL_MANAGE_POLLS to setOf(CHANNEL_READ_POLLS),
CHANNEL_MANAGE_PREDICTIONS to setOf(CHANNEL_READ_PREDICTIONS),
CHANNEL_MANAGE_REDEMPTIONS to setOf(CHANNEL_READ_REDEMPTIONS),
CHANNEL_MANAGE_VIPS to setOf(CHANNEL_READ_VIPS),
// channel:manage:moderators implies moderation:read (Twitch special case)
CHANNEL_MANAGE_MODERATORS to setOf(MODERATION_READ),
// moderator:manage:* implies moderator:read:*
MODERATOR_MANAGE_AUTOMOD_SETTINGS to setOf(MODERATOR_READ_AUTOMOD_SETTINGS),
MODERATOR_MANAGE_BLOCKED_TERMS to setOf(MODERATOR_READ_BLOCKED_TERMS),
MODERATOR_MANAGE_CHAT_SETTINGS to setOf(MODERATOR_READ_CHAT_SETTINGS),
MODERATOR_MANAGE_GUEST_STAR to setOf(MODERATOR_READ_GUEST_STAR),
MODERATOR_MANAGE_SHIELD_MODE to setOf(MODERATOR_READ_SHIELD_MODE),
MODERATOR_MANAGE_SHOUTOUTS to setOf(MODERATOR_READ_SHOUTOUTS),
MODERATOR_MANAGE_UNBAN_REQUESTS to setOf(MODERATOR_READ_UNBAN_REQUESTS),
MODERATOR_MANAGE_WARNINGS to setOf(MODERATOR_READ_WARNINGS),
// user:manage:* implies user:read:*
USER_MANAGE_BLOCKED_USERS to setOf(USER_READ_BLOCKED_USERS),
USER_MANAGE_WHISPERS to setOf(USER_READ_WHISPERS),
)
}
}