✨ Upload attachment requires permission check
This commit is contained in:
parent
8b71ec2e3f
commit
145c5563a5
8
.idea/.gitignore
vendored
8
.idea/.gitignore
vendored
@ -1,8 +0,0 @@
|
|||||||
# 默认忽略的文件
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# 基于编辑器的 HTTP 客户端请求
|
|
||||||
/httpRequests/
|
|
||||||
# Datasource local storage ignored files
|
|
||||||
/dataSources/
|
|
||||||
/dataSources.local.xml
|
|
@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
|
|
||||||
<data-source source="LOCAL" name="hy_paperclip@localhost" uuid="a2f70c83-03f8-4240-bb8b-ac697502cfe2">
|
|
||||||
<driver-ref>postgresql</driver-ref>
|
|
||||||
<synchronize>true</synchronize>
|
|
||||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
|
||||||
<jdbc-url>jdbc:postgresql://localhost:5432/hy_paperclip</jdbc-url>
|
|
||||||
<working-dir>$ProjectFileDir$</working-dir>
|
|
||||||
</data-source>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
@ -1,6 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<profile version="1.0">
|
|
||||||
<option name="myName" value="Project Default" />
|
|
||||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
|
||||||
</profile>
|
|
||||||
</component>
|
|
80
.idea/workspace.xml
Normal file
80
.idea/workspace.xml
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AutoImportSettings">
|
||||||
|
<option name="autoReloadType" value="ALL" />
|
||||||
|
</component>
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<list default="true" id="18dd0d68-b4b8-40db-9734-9119b5c848bd" name="更改" comment="">
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/.gitignore" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/Interactive.iml" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/dataSources.xml" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/inspectionProfiles/Project_Default.xml" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/go.mod" beforeDir="false" afterPath="$PROJECT_DIR$/go.mod" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/go.sum" beforeDir="false" afterPath="$PROJECT_DIR$/go.sum" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/pkg/grpc/client.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/grpc/client.go" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/pkg/server/attachments_api.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/server/attachments_api.go" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/pkg/services/accounts.go" beforeDir="false" />
|
||||||
|
</list>
|
||||||
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
|
</component>
|
||||||
|
<component name="GOROOT" url="file:///opt/homebrew/opt/go/libexec" />
|
||||||
|
<component name="Git.Settings">
|
||||||
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectColorInfo">{
|
||||||
|
"customColor": "",
|
||||||
|
"associatedIndex": 7
|
||||||
|
}</component>
|
||||||
|
<component name="ProjectId" id="2gauyxHu1OWsYigauXZCcaIhfso" />
|
||||||
|
<component name="ProjectViewState">
|
||||||
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
|
<option name="showLibraryContents" value="true" />
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent"><![CDATA[{
|
||||||
|
"keyToString": {
|
||||||
|
"Go 构建.Backend.executor": "Run",
|
||||||
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
|
"RunOnceActivity.go.formatter.settings.were.checked": "true",
|
||||||
|
"RunOnceActivity.go.migrated.go.modules.settings": "true",
|
||||||
|
"RunOnceActivity.go.modules.automatic.dependencies.download": "true",
|
||||||
|
"RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true",
|
||||||
|
"git-widget-placeholder": "master",
|
||||||
|
"go.import.settings.migrated": "true",
|
||||||
|
"go.sdk.automatically.set": "true",
|
||||||
|
"last_opened_file_path": "/Users/littlesheep",
|
||||||
|
"node.js.detected.package.eslint": "true",
|
||||||
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
|
"nodejs_package_manager_path": "npm",
|
||||||
|
"settings.editor.selected.configurable": "preferences.lookFeel"
|
||||||
|
}
|
||||||
|
}]]></component>
|
||||||
|
<component name="RunManager">
|
||||||
|
<configuration name="Backend" type="GoApplicationRunConfiguration" factoryName="Go Application">
|
||||||
|
<module name="Paperclip" />
|
||||||
|
<working_directory value="$PROJECT_DIR$" />
|
||||||
|
<kind value="FILE" />
|
||||||
|
<directory value="$PROJECT_DIR$" />
|
||||||
|
<filePath value="$PROJECT_DIR$/pkg/cmd/main.go" />
|
||||||
|
<output_directory value="$PROJECT_DIR$/dist" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
|
<component name="SharedIndexes">
|
||||||
|
<attachedChunks>
|
||||||
|
<set>
|
||||||
|
<option value="bundled-gosdk-33c477a475b1-b97fc8a1e17c-org.jetbrains.plugins.go.sharedIndexes.bundled-GO-241.14494.238" />
|
||||||
|
<option value="bundled-js-predefined-1d06a55b98c1-74d2a5396914-JavaScript-GO-241.14494.238" />
|
||||||
|
</set>
|
||||||
|
</attachedChunks>
|
||||||
|
</component>
|
||||||
|
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="应用程序级" UseSingleDictionary="true" transferred="true" />
|
||||||
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
<option name="version" value="3" />
|
||||||
|
</component>
|
||||||
|
<component name="VgoProject">
|
||||||
|
<settings-migrated>true</settings-migrated>
|
||||||
|
</component>
|
||||||
|
</project>
|
2
go.mod
2
go.mod
@ -3,7 +3,7 @@ module git.solsynth.dev/hydrogen/paperclip
|
|||||||
go 1.21.6
|
go 1.21.6
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.solsynth.dev/hydrogen/passport v0.0.0-20240504085931-7c418a3cd32f
|
git.solsynth.dev/hydrogen/passport v0.0.0-20240517121420-1e2d5e9f9d87
|
||||||
github.com/go-playground/validator/v10 v10.17.0
|
github.com/go-playground/validator/v10 v10.17.0
|
||||||
github.com/gofiber/fiber/v2 v2.52.4
|
github.com/gofiber/fiber/v2 v2.52.4
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.0
|
github.com/golang-jwt/jwt/v5 v5.2.0
|
||||||
|
2
go.sum
2
go.sum
@ -1,5 +1,7 @@
|
|||||||
git.solsynth.dev/hydrogen/passport v0.0.0-20240504085931-7c418a3cd32f h1:sKrQrKZc5C+dwefRsnc0uAGttzpSUWXUBoFaCXLkaTo=
|
git.solsynth.dev/hydrogen/passport v0.0.0-20240504085931-7c418a3cd32f h1:sKrQrKZc5C+dwefRsnc0uAGttzpSUWXUBoFaCXLkaTo=
|
||||||
git.solsynth.dev/hydrogen/passport v0.0.0-20240504085931-7c418a3cd32f/go.mod h1:3JRFPtf0dXRk2UQ1yVIgIspNfytM2yLBeBePJChgLZE=
|
git.solsynth.dev/hydrogen/passport v0.0.0-20240504085931-7c418a3cd32f/go.mod h1:3JRFPtf0dXRk2UQ1yVIgIspNfytM2yLBeBePJChgLZE=
|
||||||
|
git.solsynth.dev/hydrogen/passport v0.0.0-20240517121420-1e2d5e9f9d87 h1:r+x72tRB9LTJFH3F2rIKydQUXREc7lgxITDnjfFWwGw=
|
||||||
|
git.solsynth.dev/hydrogen/passport v0.0.0-20240517121420-1e2d5e9f9d87/go.mod h1:mEcDEKashAh3jvoGDbNLefK+HgsJaMj4xEc6vkLZ+Zc=
|
||||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
|
@ -8,9 +8,6 @@ import (
|
|||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Realms idpb.RealmsClient
|
|
||||||
var Friendships idpb.FriendshipsClient
|
|
||||||
var Notify idpb.NotifyClient
|
|
||||||
var Auth idpb.AuthClient
|
var Auth idpb.AuthClient
|
||||||
|
|
||||||
func ConnectPassport() error {
|
func ConnectPassport() error {
|
||||||
@ -18,9 +15,6 @@ func ConnectPassport() error {
|
|||||||
if conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())); err != nil {
|
if conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())); err != nil {
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
Realms = idpb.NewRealmsClient(conn)
|
|
||||||
Friendships = idpb.NewFriendshipsClient(conn)
|
|
||||||
Notify = idpb.NewNotifyClient(conn)
|
|
||||||
Auth = idpb.NewAuthClient(conn)
|
Auth = idpb.NewAuthClient(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"git.solsynth.dev/hydrogen/paperclip/pkg/grpc"
|
||||||
|
"git.solsynth.dev/hydrogen/passport/pkg/grpc/proto"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
@ -79,13 +82,25 @@ func createAttachment(c *fiber.Ctx) error {
|
|||||||
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("disallowed usage: %s", usage))
|
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("disallowed usage: %s", usage))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Add file size check with user permissions (BLOCKED BY Passport#3)
|
|
||||||
|
|
||||||
file, err := c.FormFile("file")
|
file, err := c.FormFile("file")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requiredPerm, _ := jsoniter.Marshal(file.Size)
|
||||||
|
if result, err := grpc.Auth.CheckPerm(context.Background(), &proto.CheckPermRequest{
|
||||||
|
Token: c.Locals("token").(string),
|
||||||
|
Key: "CreatePaperclipAttachments",
|
||||||
|
Value: requiredPerm,
|
||||||
|
}); err != nil {
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("failed to check permission: %v", err))
|
||||||
|
} else if !result.GetIsValid() {
|
||||||
|
return fiber.NewError(
|
||||||
|
fiber.StatusForbidden,
|
||||||
|
fmt.Sprintf("requires permission CreatePaperclipAttachments equals or greater than %d", file.Size),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var usermeta = make(map[string]any)
|
var usermeta = make(map[string]any)
|
||||||
_ = jsoniter.UnmarshalFromString(c.FormValue("metadata"), &usermeta)
|
_ = jsoniter.UnmarshalFromString(c.FormValue("metadata"), &usermeta)
|
||||||
|
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
package services
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.solsynth.dev/hydrogen/paperclip/pkg/database"
|
|
||||||
"git.solsynth.dev/hydrogen/paperclip/pkg/grpc"
|
|
||||||
"git.solsynth.dev/hydrogen/paperclip/pkg/models"
|
|
||||||
"git.solsynth.dev/hydrogen/passport/pkg/grpc/proto"
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetAccountFriend(userId, relatedId uint, status int) (*proto.FriendshipResponse, error) {
|
|
||||||
var user models.Account
|
|
||||||
if err := database.C.Where("id = ?", userId).First(&user).Error; err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var related models.Account
|
|
||||||
if err := database.C.Where("id = ?", relatedId).First(&related).Error; err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
return grpc.Friendships.GetFriendship(ctx, &proto.FriendshipTwoSideLookupRequest{
|
|
||||||
AccountId: uint64(user.ExternalID),
|
|
||||||
RelatedId: uint64(related.ExternalID),
|
|
||||||
Status: uint32(status),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func NotifyAccount(user models.Account, subject, content string, realtime bool, links ...*proto.NotifyLink) error {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
_, err := grpc.Notify.NotifyUser(ctx, &proto.NotifyRequest{
|
|
||||||
ClientId: viper.GetString("passport.client_id"),
|
|
||||||
ClientSecret: viper.GetString("passport.client_secret"),
|
|
||||||
Subject: subject,
|
|
||||||
Content: content,
|
|
||||||
Links: links,
|
|
||||||
RecipientId: uint64(user.ExternalID),
|
|
||||||
IsRealtime: realtime,
|
|
||||||
IsImportant: false,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
log.Warn().Err(err).Msg("An error occurred when notify account...")
|
|
||||||
} else {
|
|
||||||
log.Debug().Uint("external", user.ExternalID).Msg("Notified account.")
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user