Browse Source

Add oauth2_application_me and guild integration related endpoints. (#161)

* Oauth and guild integrations.

* hash on USERS_ME_GUILDS_LIST and add owner check to Application.

* Fix failing tests

* Add code to oauth2 token get

* redirect_url => uri

* Consistency fix

* Update client.py

* Remove oauth specific endpoints from APIClient

* Remove access token for now

* Fix failing tests

* remove oversight

* Update oauth.py

* Remove secret from config
staging/v1.0.0
Luke 5 years ago
committed by Andrei Zbikowski
parent
commit
425a2f9bc4
  1. 52
      disco/api/client.py
  2. 10
      disco/api/http.py
  3. 19
      disco/types/guild.py
  4. 85
      disco/types/oauth.py

52
disco/api/client.py

@ -11,7 +11,11 @@ from disco.util.logging import LoggingClass
from disco.util.sanitize import S
from disco.types.user import User
from disco.types.message import Message
from disco.types.guild import Guild, GuildMember, GuildBan, GuildEmbed, PruneCount, Role, GuildEmoji, AuditLogEntry
from disco.types.oauth import Application, Connection
from disco.types.guild import (
Guild, GuildMember, GuildBan, GuildEmbed, PruneCount, Role, GuildEmoji,
AuditLogEntry, Integration,
)
from disco.types.channel import Channel
from disco.types.invite import Invite
from disco.types.voice import VoiceRegion
@ -101,6 +105,10 @@ class APIClient(LoggingClass):
data = self.http(Routes.GATEWAY_BOT_GET).json()
return data
def oauth2_applications_me_get(self):
r = self.http(Routes.OAUTH2_APPLICATIONS_ME)
return Application.create(self.client, r.json())
def channels_get(self, channel):
r = self.http(Routes.CHANNELS_GET, dict(channel=channel))
return Channel.create(self.client, r.json())
@ -512,6 +520,37 @@ class APIClient(LoggingClass):
r = self.http(Routes.GUILDS_INVITES_LIST, dict(guild=guild))
return Invite.create_map(self.client, r.json())
def guilds_integrations_list(self, guild):
r = self.http(Routes.GUILDS_INTEGRATIONS_LIST, dict(guild=guild))
return Integration.create_map(self.client, r.json())
def guilds_integrations_create(self, guild, type, id):
r = self.http(Routes.GUILDS_INTEGRATIONS_CREATE, dict(guild=guild), json={"type": type, "id": id})
return Integration.create(r.json())
def guilds_integrations_modify(
self,
guild,
integration,
expire_behavior=None,
expire_grace_period=None,
enable_emoticons=None):
self.http(
Routes.GUILDS_INTEGRATIONS_MODIFY,
dict(guild=guild, integration=integration),
json=optional(
expire_behavior=expire_behavior,
expire_grace_period=expire_grace_period,
enable_emoticons=enable_emoticons,
))
def guilds_integrations_delete(self, guild, integration):
self.http(Routes.GUILDS_INTEGRATIONS_DELETE, dict(guild=guild, integration=integration))
def guilds_integrations_sync(self, guild, integration):
self.http(Routes.GUILDS_INTEGRATIONS_SYNC, dict(guild=guild, integration=integration))
def guilds_vanity_url_get(self, guild):
r = self.http(Routes.GUILDS_VANITY_URL_GET, dict(guild=guild))
return Invite.create(self.client, r.json())
@ -581,12 +620,17 @@ class APIClient(LoggingClass):
return User.create(self.client, r.json())
def users_me_get(self):
return User.create(self.client, self.http(Routes.USERS_ME_GET).json())
r = self.http(Routes.USERS_ME_GET)
return User.create(self.client, r.json())
def users_me_patch(self, payload):
r = self.http(Routes.USERS_ME_PATCH, json=payload)
return User.create(self.client, r.json())
def users_me_guilds_list(self):
r = self.http(Routes.USERS_ME_GUILDS_LIST)
return Guild.create_hash(self.client, 'id', r.json())
def users_me_guilds_delete(self, guild):
self.http(Routes.USERS_ME_GUILDS_DELETE, dict(guild=guild))
@ -596,6 +640,10 @@ class APIClient(LoggingClass):
})
return Channel.create(self.client, r.json())
def users_me_connections_list(self):
r = self.http(Routes.USERS_ME_CONNECTIONS_LIST)
return Connection.create_map(self.client, r.json())
def invites_get(self, invite):
r = self.http(Routes.INVITES_GET, dict(invite=invite))
return Invite.create(self.client, r.json())

10
disco/api/http.py

@ -34,6 +34,12 @@ class Routes(object):
GATEWAY_GET = (HTTPMethod.GET, '/gateway')
GATEWAY_BOT_GET = (HTTPMethod.GET, '/gateway/bot')
# OAUTH2
OAUTH2 = '/oauth2'
OAUTH2_TOKEN = (HTTPMethod.POST, OAUTH2 + '/token')
OAUTH2_TOKEN_REVOKE = (HTTPMethod.POST, OAUTH2 + '/token/revoke')
OAUTH2_APPLICATIONS_ME = (HTTPMethod.GET, OAUTH2 + '/applications/@me')
# Channels
CHANNELS = '/channels/{channel}'
CHANNELS_GET = (HTTPMethod.GET, CHANNELS)
@ -178,7 +184,9 @@ class APIException(Exception):
self.msg = '{} ({} - {})'.format(data['message'], self.code, self.errors)
elif len(data) == 1:
key, value = list(data.items())[0]
self.msg = 'Request Failed: {}: {}'.format(key, ', '.join(value))
if not isinstance(value, str):
value = ', '.join(value)
self.msg = 'Request Failed: {}: {}'.format(key, value)
except ValueError:
pass

19
disco/types/guild.py

@ -608,6 +608,25 @@ class Guild(SlottedModel, Permissible):
return self.client.api.guilds_auditlogs_list(self.id, *args, **kwargs)
class IntegrationAccount(SlottedModel):
id = Field(text)
name = Field(text)
class Integration(SlottedModel):
id = Field(snowflake)
name = Field(text)
type = Field(text)
enabled = Field(bool)
syncing = Field(bool)
role_id = Field(snowflake)
expire_behavior = Field(int)
expire_grace_period = Field(int)
user = Field(User)
account = Field(IntegrationAccount)
synced_at = Field(datetime)
class AuditLogActionTypes(object):
GUILD_UPDATE = 1
CHANNEL_CREATE = 10

85
disco/types/oauth.py

@ -0,0 +1,85 @@
from disco.types.base import SlottedModel, Field, ListField, snowflake, text, enum
from disco.types.guild import Integration
from disco.types.user import User
from disco.util.snowflake import to_snowflake
class TeamMembershipState(object):
INVITED = 1
ACCEPTED = 2
class TeamMember(SlottedModel):
membership_state = Field(enum(TeamMembershipState))
permissions = Field(text)
team_id = Field(snowflake)
user = Field(User)
class Team(SlottedModel):
icon = Field(text)
id = Field(snowflake)
members = ListField(TeamMember)
owner_user_id = Field(snowflake)
class Application(SlottedModel):
id = Field(snowflake)
name = Field(text)
icon = Field(text)
description = Field(text)
rpc_origins = ListField(text)
bot_public = Field(bool)
bot_require_code_grant = Field(bool)
owner = Field(User)
summary = Field(text)
verify_key = Field(text)
team = Field(Team)
guild_id = Field(snowflake)
primary_sku_id = Field(snowflake)
slug = Field(text)
cover_image = Field(text)
def user_is_owner(self, user):
user_id = to_snowflake(user)
if user_id == self.owner.id:
return True
return any(user_id == member.user.id for member in self.team.members)
def get_icon_url(self, fmt='webp', size=1024):
if not self.icon:
return ''
return 'https://cdn.discordapp.com/app-icons/{}/{}.{}?size={}'.format(self.id, self.icon, fmt, size)
def get_cover_image_url(self, fmt='webp', size=1024):
if not self.cover_image:
return ''
return 'https://cdn.discordapp.com/app-icons/{}/{}.{}?size={}'.format(self.id, self.cover_image, fmt, size)
@property
def icon_url(self):
return self.get_icon_url()
@property
def cover_image_url(self):
return self.get_cover_image_url()
class ConnectionVisibility(object):
NOBODY = 0
EVERYONE = 1
class Connection(SlottedModel):
id = Field(text)
name = Field(text)
type = Field(text)
revoked = Field(bool)
integrations = ListField(Integration)
verified = Field(bool)
friend_sync = Field(bool)
show_activity = Field(bool)
visibility = Field(enum(ConnectionVisibility))
Loading…
Cancel
Save