Browse Source

Merge remote-tracking branch 'bwmarrin/develop' into develop

Chris Rhodes 9 years ago
parent
commit
e37b86d3e8
2 changed files with 194 additions and 26 deletions
  1. 101 8
      restapi.go
  2. 93 18
      structs.go

+ 101 - 8
restapi.go

@@ -104,11 +104,10 @@ func (s *Session) request(method, urlStr, contentType string, b []byte) (respons
 		fmt.Printf("API RESPONSE    BODY :: [%s]\n", response)
 	}
 
-	// See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
 	switch resp.StatusCode {
 
-	case 200: // OK
-	case 204: // No Content
+	case http.StatusOK:
+	case http.StatusNoContent:
 
 		// TODO check for 401 response, invalidate token if we get one.
 
@@ -328,6 +327,70 @@ func (s *Session) UserGuilds() (st []*Guild, err error) {
 	return
 }
 
+// UserChannelPermissions returns the permission of a user in a channel.
+// userID    : The ID of the user to calculate permissions for.
+// channelID : The ID of the channel to calculate permission for.
+func (s *Session) UserChannelPermissions(userID, channelID string) (apermissions int, err error) {
+
+	channel, err := s.Channel(channelID)
+	if err != nil {
+		return
+	}
+
+	guild, err := s.Guild(channel.GuildID)
+	if err != nil {
+		return
+	}
+
+	if userID == guild.OwnerID {
+		apermissions = PermissionAll
+		return
+	}
+
+	member, err := s.GuildMember(guild.ID, userID)
+	if err != nil {
+		return
+	}
+
+	for _, role := range guild.Roles {
+		for _, roleID := range member.Roles {
+			if role.ID == roleID {
+				apermissions |= role.Permissions
+				break
+			}
+		}
+	}
+
+	if apermissions & PermissionManageRoles > 0 {
+		apermissions |= PermissionAll
+	}
+
+	// Member overwrites can override role overrides, so do two passes
+	for _, overwrite := range channel.PermissionOverwrites {
+		for _, roleID := range member.Roles {
+			if overwrite.Type == "role" && roleID == overwrite.ID {
+				apermissions &= ^overwrite.Deny
+				apermissions |= overwrite.Allow
+				break
+			}
+		}
+	}
+
+	for _, overwrite := range channel.PermissionOverwrites {
+		if overwrite.Type == "member" && overwrite.ID == userID {
+			apermissions &= ^overwrite.Deny
+			apermissions |= overwrite.Allow
+			break
+		}
+	}
+
+	if apermissions & PermissionManageRoles > 0 {
+		apermissions |= PermissionAllChannel
+	}
+
+	return
+}
+
 // ------------------------------------------------------------------------------------------------
 // Functions specific to Discord Guilds
 // ------------------------------------------------------------------------------------------------
@@ -371,14 +434,44 @@ func (s *Session) GuildCreate(name string) (st *Guild, err error) {
 
 // GuildEdit edits a new Guild
 // guildID   : The ID of a Guild
-// name      : A name for the Guild (2-100 characters)
-func (s *Session) GuildEdit(guildID, name string) (st *Guild, err error) {
+// g 		 : A GuildParams struct with the values Name, Region and VerificationLevel defined.
+func (s *Session) GuildEdit(guildID string, g GuildParams) (st *Guild, err error) {
+
+	// Bounds checking for VerificationLevel, interval: [0, 3]
+	if g.VerificationLevel != nil {
+		val := *g.VerificationLevel
+		if val < 0 || val > 3 {
+			err = errors.New("VerificationLevel out of bounds, should be between 0 and 3")
+			return
+		}
+	}
+
+	//Bounds checking for regions
+	if g.Region != "" {
+		isValid := false
+		regions, _ := s.VoiceRegions()
+		for _, r := range regions {
+			if g.Region == r.ID {
+				isValid = true
+			}
+		}
+		if !isValid {
+			var valid []string
+			for _, r := range regions {
+				valid = append(valid, r.ID)
+			}
+			err = errors.New(fmt.Sprintf("Region not a valid region (%q)", valid))
+			return
+		}
+	}
 
 	data := struct {
-		Name string `json:"name"`
-	}{name}
+		Name              string             `json:"name,omitempty"`
+		Region            string             `json:"region,omitempty"`
+		VerificationLevel *VerificationLevel `json:"verification_level,omitempty"`
+	}{g.Name, g.Region, g.VerificationLevel}
 
-	body, err := s.Request("POST", GUILD(guildID), data)
+	body, err := s.Request("PATCH", GUILD(guildID), data)
 	if err != nil {
 		return
 	}

+ 93 - 18
structs.go

@@ -145,27 +145,46 @@ type Emoji struct {
 	RequireColons bool     `json:"require_colons"`
 }
 
+// Custom VerificationLevel typedef for int
+type VerificationLevel int
+
+// Constants for VerificationLevel levels from 0 to 3 inclusive
+const (
+	VerificationLevelNone VerificationLevel = iota
+	VerificationLevelLow
+	VerificationLevelMedium
+	VerificationLevelHigh
+)
+
 // A Guild holds all data related to a specific Discord Guild.  Guilds are also
 // sometimes referred to as Servers in the Discord client.
 type Guild struct {
-	ID             string        `json:"id"`
-	Name           string        `json:"name"`
-	Icon           string        `json:"icon"`
-	Region         string        `json:"region"`
-	AfkChannelID   string        `json:"afk_channel_id"`
-	EmbedChannelID string        `json:"embed_channel_id"`
-	OwnerID        string        `json:"owner_id"`
-	JoinedAt       string        `json:"joined_at"` // make this a timestamp
-	Splash         string        `json:"splash"`
-	AfkTimeout     int           `json:"afk_timeout"`
-	EmbedEnabled   bool          `json:"embed_enabled"`
-	Large          bool          `json:"large"` // ??
-	Roles          []*Role       `json:"roles"`
-	Emojis         []*Emoji      `json:"emojis"`
-	Members        []*Member     `json:"members"`
-	Presences      []*Presence   `json:"presences"`
-	Channels       []*Channel    `json:"channels"`
-	VoiceStates    []*VoiceState `json:"voice_states"`
+	ID                string            `json:"id"`
+	Name              string            `json:"name"`
+	Icon              string            `json:"icon"`
+	Region            string            `json:"region"`
+	AfkChannelID      string            `json:"afk_channel_id"`
+	EmbedChannelID    string            `json:"embed_channel_id"`
+	OwnerID           string            `json:"owner_id"`
+	JoinedAt          string            `json:"joined_at"` // make this a timestamp
+	Splash            string            `json:"splash"`
+	AfkTimeout        int               `json:"afk_timeout"`
+	VerificationLevel VerificationLevel `json:"verification_level"`
+	EmbedEnabled      bool              `json:"embed_enabled"`
+	Large             bool              `json:"large"` // ??
+	Roles             []*Role           `json:"roles"`
+	Emojis            []*Emoji          `json:"emojis"`
+	Members           []*Member         `json:"members"`
+	Presences         []*Presence       `json:"presences"`
+	Channels          []*Channel        `json:"channels"`
+	VoiceStates       []*VoiceState     `json:"voice_states"`
+}
+
+// A GuildParams stores all the data needed to update discord guild settings
+type GuildParams struct {
+	Name              string             `json:"name"`
+	Region            string             `json:"region"`
+	VerificationLevel *VerificationLevel `json:"verification_level"`
 }
 
 // A Role stores information about Discord guild member roles.
@@ -346,3 +365,59 @@ type State struct {
 	Ready
 	MaxMessageCount int
 }
+
+// Constants for the different bit offsets of text channel permissions
+const (
+	PermissionReadMessages = 1 << (iota + 10)
+	PermissionSendMessages
+	PermissionSendTTSMessages
+	PermissionManageMessages
+	PermissionEmbedLinks
+	PermissionAttachFiles
+	PermissionReadMessageHistory
+	PermissionMentionEveryone
+)
+
+// Constants for the different bit offsets of voice permissions
+const (
+	PermissionVoiceConnect = 1 << (iota + 20)
+	PermissionVoiceSpeak
+	PermissionVoiceMuteMembers
+	PermissionVoiceDeafenMembers
+	PermissionVoiceMoveMembers
+	PermissionVoiceUseVAD
+)
+
+// Constants for the different bit offsets of general permissions
+const (
+	PermissionCreateInstantInvite = 1 << iota
+	PermissionKickMembers
+	PermissionBanMembers
+	PermissionManageRoles
+	PermissionManageChannels
+	PermissionManageServer
+
+	PermissionAllText    = PermissionReadMessages |
+	                       PermissionSendMessages |
+	                       PermissionSendTTSMessages |
+	                       PermissionManageMessages |
+	                       PermissionEmbedLinks |
+	                       PermissionAttachFiles |
+	                       PermissionReadMessageHistory |
+	                       PermissionMentionEveryone
+	PermissionAllVoice   = PermissionVoiceConnect |
+	                       PermissionVoiceSpeak |
+	                       PermissionVoiceMuteMembers |
+	                       PermissionVoiceDeafenMembers |
+	                       PermissionVoiceMoveMembers |
+	                       PermissionVoiceUseVAD
+	PermissionAllChannel = PermissionAllText |
+	                       PermissionAllVoice |
+	                       PermissionCreateInstantInvite |
+	                       PermissionManageRoles |
+	                       PermissionManageChannels
+	PermissionAll        = PermissionAllChannel |
+	                       PermissionKickMembers |
+	                       PermissionBanMembers |
+	                       PermissionManageServer
+)