diff --git a/cmd/Open-IM-SDK-Core b/cmd/Open-IM-SDK-Core index 1667b0f4e..5e8d3f536 160000 --- a/cmd/Open-IM-SDK-Core +++ b/cmd/Open-IM-SDK-Core @@ -1 +1 @@ -Subproject commit 1667b0f4e205fc4ed7c690ab55b662087d61c277 +Subproject commit 5e8d3f5366700f00db7db2905da27189b9353630 diff --git a/cmd/open_im_api/main.go b/cmd/open_im_api/main.go index 96832597d..66e2880b1 100644 --- a/cmd/open_im_api/main.go +++ b/cmd/open_im_api/main.go @@ -17,13 +17,15 @@ import ( "Open_IM/pkg/utils" "flag" "fmt" + //_ "github.com/razeencheng/demo-go/swaggo-gin/docs" - swaggerFiles "github.com/swaggo/files" - ginSwagger "github.com/swaggo/gin-swagger" "io" "os" "strconv" + swaggerFiles "github.com/swaggo/files" + ginSwagger "github.com/swaggo/gin-swagger" + "github.com/gin-gonic/gin" //"syscall" "Open_IM/pkg/common/constant" @@ -132,6 +134,7 @@ func main() { thirdGroup.POST("/get_rtc_invitation_info", apiThird.GetRTCInvitationInfo) thirdGroup.POST("/get_rtc_invitation_start_app", apiThird.GetRTCInvitationInfoStartApp) thirdGroup.POST("/fcm_update_token", apiThird.FcmUpdateToken) + thirdGroup.POST("/aws_storage_credential", apiThird.AwsStorageCredential) } //Message chatGroup := r.Group("/msg") diff --git a/config/config.yaml b/config/config.yaml index 680747d01..c7a470eb2 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -129,6 +129,15 @@ credential: #腾讯cos,发送图片、视频、文件时需要,请自行申 finalHost: "http://bucket1.oss-cn-beijing.aliyuncs.com" stsDurationSeconds: 3600 OssRoleArn: "acs:ram::xxx:role/xxx" + aws: + accessKeyID: ******************** #AssumeRole用户关联的accessKeyID + accessKeySecret: **************************************** #AssumeRole用户关联的accessKeySecrect + region: ap-southeast-1 #分区 + bucket: ouyang #桶 + finalHost: ouyang.s3.ap-southeast-1.amazonaws.com #对外Host + roleArn: arn:aws:iam::192209831083:role/AWS_S3_FOR_OUYANG #RoleArn + externalId: AssumeRoleExtend #角色扩展Id + roleSessionName: Required-AWS-ID-OPENIM #角色SESSION名称 dtm: serverURL: 127.0.0.1:10007 diff --git a/go.mod b/go.mod index 568aee953..2b933bf4c 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,10 @@ require ( github.com/alibabacloud-go/sts-20150401 v1.1.0 github.com/alibabacloud-go/tea v1.1.17 github.com/antonfisher/nested-logrus-formatter v1.3.0 + github.com/aws/aws-sdk-go-v2 v1.16.7 + github.com/aws/aws-sdk-go-v2/config v1.15.14 + github.com/aws/aws-sdk-go-v2/credentials v1.12.9 + github.com/aws/aws-sdk-go-v2/service/sts v1.16.9 github.com/bwmarrin/snowflake v0.3.0 github.com/dtm-labs/rockscache v0.0.11 github.com/fatih/structs v1.1.0 diff --git a/go.sum b/go.sum index 16b96bd44..49fc3f000 100644 --- a/go.sum +++ b/go.sum @@ -99,6 +99,28 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/antonfisher/nested-logrus-formatter v1.3.0 h1:8zixYquU1Odk+vzAaAQPAdRh1ZjmUXNQ1T+dUBvlhVo= github.com/antonfisher/nested-logrus-formatter v1.3.0/go.mod h1:6WTfyWFkBc9+zyBaKIqRrg/KwMqBbodBjgbHjDz7zjA= github.com/aws/aws-sdk-go v1.38.3/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go-v2 v1.16.7 h1:zfBwXus3u14OszRxGcqCDS4MfMCv10e8SMJ2r8Xm0Ns= +github.com/aws/aws-sdk-go-v2 v1.16.7/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw= +github.com/aws/aws-sdk-go-v2/config v1.15.14 h1:+BqpqlydTq4c2et9Daury7gE+o67P4lbk7eybiCBNc4= +github.com/aws/aws-sdk-go-v2/config v1.15.14/go.mod h1:CQBv+VVv8rR5z2xE+Chdh5m+rFfsqeY4k0veEZeq6QM= +github.com/aws/aws-sdk-go-v2/credentials v1.12.9 h1:DloAJr0/jbvm0iVRFDFh8GlWxrOd9XKyX82U+dfVeZs= +github.com/aws/aws-sdk-go-v2/credentials v1.12.9/go.mod h1:2Vavxl1qqQXJ8MUcQZTsIEW8cwenFCWYXtLRPba3L/o= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.8 h1:VfBdn2AxwMbFyJN/lF/xuT3SakomJ86PZu3rCxb5K0s= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.8/go.mod h1:oL1Q3KuCq1D4NykQnIvtRiBGLUXhcpY5pl6QZB2XEPU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.14 h1:2C0pYHcUBmdzPj+EKNC4qj97oK6yjrUhc1KoSodglvk= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.14/go.mod h1:kdjrMwHwrC3+FsKhNcCMJ7tUVj/8uSD5CZXeQ4wV6fM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.8 h1:2J+jdlBJWEmTyAwC82Ym68xCykIvnSnIN18b8xHGlcc= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.8/go.mod h1:ZIV8GYoC6WLBW5KGs+o4rsc65/ozd+eQ0L31XF5VDwk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.15 h1:QquxR7NH3ULBsKC+NoTpilzbKKS+5AELfNREInbhvas= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.15/go.mod h1:Tkrthp/0sNBShQQsamR7j/zY4p19tVTAs+nnqhH6R3c= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.8 h1:oKnAXxSF2FUvfgw8uzU/v9OTYorJJZ8eBmWhr9TWVVQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.8/go.mod h1:rDVhIMAX9N2r8nWxDUlbubvvaFMnfsm+3jAV7q+rpM4= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.12 h1:760bUnTX/+d693FT6T6Oa7PZHfEQT9XMFZeM5IQIB0A= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.12/go.mod h1:MO4qguFjs3wPGcCSpQ7kOFTwRvb+eu+fn+1vKleGHUk= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.9 h1:yOfILxyjmtr2ubRkRJldlHDFBhf5vw4CzhbwWIBmimQ= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.9/go.mod h1:O1IvkYxr+39hRf960Us6j0x1P8pDqhTX+oXM5kQNl/Y= +github.com/aws/smithy-go v1.12.0 h1:gXpeZel/jPoWQ7OEmLIgCUnhkFftqNfwWUwAHSlp1v0= +github.com/aws/smithy-go v1.12.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -273,8 +295,9 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= diff --git a/internal/api/third/aws_storage_credential.go b/internal/api/third/aws_storage_credential.go new file mode 100644 index 000000000..4b3b7d08a --- /dev/null +++ b/internal/api/third/aws_storage_credential.go @@ -0,0 +1,76 @@ +package apiThird + +import ( + api "Open_IM/pkg/base_info" + "Open_IM/pkg/common/config" + "Open_IM/pkg/common/constant" + "Open_IM/pkg/common/log" + "Open_IM/pkg/common/token_verify" + "Open_IM/pkg/utils" + "context" + "net/http" + + "github.com/aws/aws-sdk-go-v2/aws" + awsConfig "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/credentials" + "github.com/aws/aws-sdk-go-v2/service/sts" + "github.com/gin-gonic/gin" +) + +func AwsStorageCredential(c *gin.Context) { + var ( + req api.AwsStorageCredentialReq + resp api.AwsStorageCredentialResp + ) + if err := c.BindJSON(&req); err != nil { + log.NewError("0", utils.GetSelfFuncName(), "BindJSON failed ", err.Error()) + c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": err.Error()}) + return + } + log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req) + var ok bool + var errInfo string + ok, _, errInfo = token_verify.GetUserIDFromToken(c.Request.Header.Get("token"), req.OperationID) + if !ok { + errMsg := req.OperationID + " " + "GetUserIDFromToken failed " + errInfo + " token:" + c.Request.Header.Get("token") + log.NewError(req.OperationID, errMsg) + c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": errMsg}) + return + } + //原始帐号信息 + awsSourceConfig, err := awsConfig.LoadDefaultConfig(context.TODO(), awsConfig.WithRegion(config.Config.Credential.Aws.Region), + awsConfig.WithCredentialsProvider(credentials.StaticCredentialsProvider{ + Value: aws.Credentials{ + AccessKeyID: config.Config.Credential.Aws.AccessKeyID, + SecretAccessKey: config.Config.Credential.Aws.AccessKeySecret, + Source: "Open IM OSS", + }, + })) + if err != nil { + errMsg := req.OperationID + " " + "Init AWS S3 Credential failed " + err.Error() + " token:" + c.Request.Header.Get("token") + log.NewError(req.OperationID, errMsg) + c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": errMsg}) + return + } + //帐号转化 + awsStsClient := sts.NewFromConfig(awsSourceConfig) + StsRole, err := awsStsClient.AssumeRole(context.Background(), &sts.AssumeRoleInput{ + RoleArn: aws.String(config.Config.Credential.Aws.RoleArn), + DurationSeconds: aws.Int32(constant.AwsDurationTimes), + RoleSessionName: aws.String(config.Config.Credential.Aws.RoleSessionName), + ExternalId: aws.String(config.Config.Credential.Aws.ExternalId), + }) + if err != nil { + errMsg := req.OperationID + " " + "AWS S3 AssumeRole failed " + err.Error() + " token:" + c.Request.Header.Get("token") + log.NewError(req.OperationID, errMsg) + c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": errMsg}) + return + } + resp.CosData.AccessKeyId = string(*StsRole.Credentials.AccessKeyId) + resp.CosData.SecretAccessKey = string(*StsRole.Credentials.SecretAccessKey) + resp.CosData.SessionToken = string(*StsRole.Credentials.SessionToken) + resp.CosData.Bucket = config.Config.Credential.Aws.Bucket + resp.CosData.RegionID = config.Config.Credential.Aws.Region + resp.CosData.FinalHost = config.Config.Credential.Aws.FinalHost + c.JSON(http.StatusOK, gin.H{"errCode": 0, "errMsg": "", "data": resp}) +} diff --git a/pkg/base_info/aws_api_struct.go b/pkg/base_info/aws_api_struct.go new file mode 100644 index 000000000..ebd26021e --- /dev/null +++ b/pkg/base_info/aws_api_struct.go @@ -0,0 +1,20 @@ +package base_info + +type AwsStorageCredentialReq struct { + OperationID string `json:"operationID"` +} + +type AwsStorageCredentialRespData struct { + AccessKeyId string `json:"accessKeyID"` + SecretAccessKey string `json:"secretAccessKey"` + SessionToken string `json:"sessionToken"` + RegionID string `json:"regionId"` + Bucket string `json:"bucket"` + FinalHost string `json:"FinalHost"` +} + +type AwsStorageCredentialResp struct { + CommResp + CosData AwsStorageCredentialRespData + Data map[string]interface{} `json:"data"` +} diff --git a/pkg/common/config/config.go b/pkg/common/config/config.go index 6c0e1a499..e84e2c526 100644 --- a/pkg/common/config/config.go +++ b/pkg/common/config/config.go @@ -73,6 +73,16 @@ type config struct { EndpointInnerEnable bool `yaml:"endpointInnerEnable"` StorageTime int `yaml:"storageTime"` } `yaml:"minio"` + Aws struct { + AccessKeyID string `yaml:"accessKeyID"` + AccessKeySecret string `yaml:"accessKeySecret"` + Region string `yaml:"region"` + Bucket string `yaml:"bucket"` + FinalHost string `yaml:"finalHost"` + RoleArn string `yaml:"roleArn"` + ExternalId string `yaml:"externalId"` + RoleSessionName string `yaml:"roleSessionName"` + } `yaml:"aws"` } Dtm struct { diff --git a/pkg/common/constant/constant.go b/pkg/common/constant/constant.go index ad5caf19f..0f2a07e84 100644 --- a/pkg/common/constant/constant.go +++ b/pkg/common/constant/constant.go @@ -184,7 +184,8 @@ const ( //Minio MinioDurationTimes = 3600 - + //Aws + AwsDurationTimes = 3600 // verificationCode used for VerificationCodeForRegister = 1 VerificationCodeForReset = 2