User ID can be encrypted

This commit is contained in:
zhaoYangguang 2020-12-04 20:53:40 +08:00
parent 6bd6b9208e
commit bc1988b4a9
4 changed files with 12 additions and 170 deletions

View File

@ -7,7 +7,6 @@ import (
"github.com/kelaresg/matrix-skype/database" "github.com/kelaresg/matrix-skype/database"
skypeExt "github.com/kelaresg/matrix-skype/skype-ext" skypeExt "github.com/kelaresg/matrix-skype/skype-ext"
"math" "math"
"time"
"sort" "sort"
"strconv" "strconv"
@ -1162,6 +1161,7 @@ func (handler *CommandHandler) CommandCreate(ce *CommandEvent) {
} }
members, err := ce.Bot.JoinedMembers(ce.RoomID) members, err := ce.Bot.JoinedMembers(ce.RoomID)
handler.log.Debugln("Create Group-1", members)
if err != nil { if err != nil {
ce.Reply("Failed to get room members: %v", err) ce.Reply("Failed to get room members: %v", err)
return return
@ -1203,24 +1203,15 @@ func (handler *CommandHandler) CommandCreate(ce *CommandEvent) {
HistoryDisclosed: "true", HistoryDisclosed: "true",
Topic: roomNameEvent.Name, Topic: roomNameEvent.Name,
} }
handler.log.Debugln("Create Group", roomNameEvent.Name, "with", selfMembers) handler.log.Debugln("Create Group", roomNameEvent.Name, "with", selfMembers, participants)
err = ce.User.Conn.HandleGroupCreate(selfMembers) err = ce.User.Conn.HandleGroupCreate(selfMembers)
if err != nil { if err != nil {
ce.Reply("Failed to create group: %v", err) ce.Reply("Failed to create group: %v", err)
return return
} }
participantMembers := skype.Members{} participantMembers := skype.Members{}
for _, participant := range participants { for _, participant := range participants {
participantArr := strings.Split(participant, "@") memberId := strings.Replace(participant, skypeExt.NewUserSuffix, "", 1)
memberId := id.Dec(participantArr[0])
cond1 := "8-live-"
cond2 := "8-"
if strings.HasPrefix(memberId, cond1) {
memberId = strings.Replace(memberId, cond1, "8:live:", 1)
} else if strings.HasPrefix(memberId, cond2){
memberId = strings.Replace(memberId, cond2, "8:", 1)
}
participantMembers.Members = append(participantMembers.Members, skype.Member{ participantMembers.Members = append(participantMembers.Members, skype.Member{
Id: memberId, Id: memberId,
Role: "Admin", Role: "Admin",

View File

@ -18,6 +18,7 @@ package config
import ( import (
"io/ioutil" "io/ioutil"
"maunium.net/go/mautrix/patch"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
@ -98,6 +99,10 @@ func (config *Config) MakeAppService() (*appservice.AppService, error) {
as.HomeserverURL = config.Homeserver.Address as.HomeserverURL = config.Homeserver.Address
as.Host.Hostname = config.AppService.Hostname as.Host.Hostname = config.AppService.Hostname
as.Host.Port = config.AppService.Port as.Host.Port = config.AppService.Port
patch.ThirdPartyIdEncrypt = true
patch.AsBotName = config.AppService.Bot.Username
patch.AsUserPrefix = "skype&"
patch.XorKey = "hudsds1y"
var err error var err error
as.Registration, err = config.GetRegistration() as.Registration, err = config.GetRegistration()
return as, err return as, err

View File

@ -641,10 +641,10 @@ func (portal *Portal) SyncSkype(user *User, chat skype.Conversation) {
} else { } else {
fmt.Println("SyncSkype ensureUserInvited", portal.MXID) fmt.Println("SyncSkype ensureUserInvited", portal.MXID)
portal.ensureUserInvited(user) portal.ensureUserInvited(user)
rep, err := portal.MainIntent().SetPowerLevel(portal.MXID, user.MXID, 95) //rep, err := portal.MainIntent().SetPowerLevel(portal.MXID, user.MXID, 95)
if err != nil { //if err != nil {
portal.log.Warnfln("SyncSkype: SetPowerLevel err: ", err, rep) // portal.log.Warnfln("SyncSkype: SetPowerLevel err: ", err, rep)
} //}
//if portal.IsPrivateChat() { //if portal.IsPrivateChat() {
// preUserIds,_ := portal.GetMatrixUsers() // preUserIds,_ := portal.GetMatrixUsers()

View File

@ -1,154 +0,0 @@
package skypeExt
import (
"bytes"
"encoding/hex"
"fmt"
"strings"
)
// UserID represents a Matrix user ID.
// https://matrix.org/docs/spec/appendices#user-identifiers
type UserID string
func NewUserID(localpart, homeserver string) UserID {
return UserID(fmt.Sprintf("@%s:%s", localpart, homeserver))
}
func NewEncodedUserID(localpart, homeserver string) UserID {
return NewUserID(EncodeUserLocalpart(localpart), homeserver)
}
// Parse parses the user ID into the localpart and server name.
// See http://matrix.org/docs/spec/intro.html#user-identifiers
func (userID UserID) Parse() (localpart, homeserver string, err error) {
if len(userID) == 0 || userID[0] != '@' || !strings.ContainsRune(string(userID), ':') {
err = fmt.Errorf("%s is not a valid user id", userID)
return
}
parts := strings.SplitN(string(userID), ":", 2)
localpart, homeserver = strings.TrimPrefix(parts[0], "@"), parts[1]
return
}
func (userID UserID) ParseAndDecode() (localpart, homeserver string, err error) {
localpart, homeserver, err = userID.Parse()
if err == nil {
localpart, err = DecodeUserLocalpart(localpart)
}
return
}
func (userID UserID) String() string {
return string(userID)
}
const lowerhex = "0123456789abcdef"
// encode the given byte using quoted-printable encoding (e.g "=2f")
// and writes it to the buffer
// See https://golang.org/src/mime/quotedprintable/writer.go
func encode(buf *bytes.Buffer, b byte) {
buf.WriteByte('=')
buf.WriteByte(lowerhex[b>>4])
buf.WriteByte(lowerhex[b&0x0f])
}
// escape the given alpha character and writes it to the buffer
func escape(buf *bytes.Buffer, b byte) {
buf.WriteByte('_')
if b == '_' {
buf.WriteByte('_') // another _
} else {
buf.WriteByte(b + 0x20) // ASCII shift A-Z to a-z
}
}
func shouldEncode(b byte) bool {
return b != '-' && b != '.' && b != '_' && !(b >= '0' && b <= '9') && !(b >= 'a' && b <= 'z') && !(b >= 'A' && b <= 'Z')
}
func shouldEscape(b byte) bool {
return (b >= 'A' && b <= 'Z') || b == '_'
}
func isValidByte(b byte) bool {
return isValidEscapedChar(b) || (b >= '0' && b <= '9') || b == '.' || b == '=' || b == '-'
}
func isValidEscapedChar(b byte) bool {
return b == '_' || (b >= 'a' && b <= 'z')
}
// EncodeUserLocalpart encodes the given string into Matrix-compliant user ID localpart form.
// See http://matrix.org/docs/spec/intro.html#mapping-from-other-character-sets
//
// This returns a string with only the characters "a-z0-9._=-". The uppercase range A-Z
// are encoded using leading underscores ("_"). Characters outside the aforementioned ranges
// (including literal underscores ("_") and equals ("=")) are encoded as UTF8 code points (NOT NCRs)
// and converted to lower-case hex with a leading "=". For example:
// Alph@Bet_50up => _alph=40_bet=5f50up
func EncodeUserLocalpart(str string) string {
strBytes := []byte(str)
var outputBuffer bytes.Buffer
for _, b := range strBytes {
if shouldEncode(b) {
encode(&outputBuffer, b)
} else if shouldEscape(b) {
escape(&outputBuffer, b)
} else {
outputBuffer.WriteByte(b)
}
}
return outputBuffer.String()
}
// DecodeUserLocalpart decodes the given string back into the original input string.
// Returns an error if the given string is not a valid user ID localpart encoding.
// See http://matrix.org/docs/spec/intro.html#mapping-from-other-character-sets
//
// This decodes quoted-printable bytes back into UTF8, and unescapes casing. For
// example:
// _alph=40_bet=5f50up => Alph@Bet_50up
// Returns an error if the input string contains characters outside the
// range "a-z0-9._=-", has an invalid quote-printable byte (e.g. not hex), or has
// an invalid _ escaped byte (e.g. "_5").
func DecodeUserLocalpart(str string) (string, error) {
strBytes := []byte(str)
var outputBuffer bytes.Buffer
for i := 0; i < len(strBytes); i++ {
b := strBytes[i]
if !isValidByte(b) {
return "", fmt.Errorf("Byte pos %d: Invalid byte", i)
}
if b == '_' { // next byte is a-z and should be upper-case or is another _ and should be a literal _
if i+1 >= len(strBytes) {
return "", fmt.Errorf("Byte pos %d: expected _[a-z_] encoding but ran out of string", i)
}
if !isValidEscapedChar(strBytes[i+1]) { // invalid escaping
return "", fmt.Errorf("Byte pos %d: expected _[a-z_] encoding", i)
}
if strBytes[i+1] == '_' {
outputBuffer.WriteByte('_')
} else {
outputBuffer.WriteByte(strBytes[i+1] - 0x20) // ASCII shift a-z to A-Z
}
i++ // skip next byte since we just handled it
} else if b == '=' { // next 2 bytes are hex and should be buffered ready to be read as utf8
if i+2 >= len(strBytes) {
return "", fmt.Errorf("Byte pos: %d: expected quote-printable encoding but ran out of string", i)
}
dst := make([]byte, 1)
_, err := hex.Decode(dst, strBytes[i+1:i+3])
if err != nil {
return "", err
}
outputBuffer.WriteByte(dst[0])
i += 2 // skip next 2 bytes since we just handled it
} else { // pass through
outputBuffer.WriteByte(b)
}
}
return outputBuffer.String(), nil
}