A lot of delete and failed scream tests.
the build was successful

This commit is contained in:
2019-08-26 22:14:59 +02:00
parent 0e70e37038
commit e690e7ab97
41 changed files with 617 additions and 1240 deletions
+331
View File
@@ -0,0 +1,331 @@
package services
import (
"context"
"crypto/rand"
"encoding/base64"
"errors"
"fmt"
"git.aiterp.net/rpdata/api/models"
"git.aiterp.net/rpdata/api/repositories"
"github.com/dgrijalva/jwt-go"
"log"
"net/http"
"reflect"
"strings"
"time"
)
var contextKey = &struct{ data string }{"Token Context Key"}
// ErrNoKid is returned if the key id is missing from the jwt token header,
var ErrNoKid = errors.New("missing \"kid\" field in token")
// ErrKeyNotFound is returned if the key wasn't found.
var ErrKeyNotFound = errors.New("key not found")
// ErrInvalidClaims is returned by parseClaims if the claims cannot be parsed
var ErrInvalidClaims = errors.New("invalid claims in token")
// ErrExpired is returned by parseClaims if the expiry date is in the past
var ErrExpired = errors.New("claims have already expired")
// ErrWrongUser is returned by CheckToken if the key cannot represent this user
var ErrWrongUser = errors.New("key is not valid for this user")
// ErrDeletedUser is returned by CheckToken if the key can represent this user, but the user doesn't exist.
var ErrDeletedUser = errors.New("user was not found")
// ErrUnauthenticated is returned when the user is not authenticated
var ErrUnauthenticated = errors.New("you are not authenticated")
// ErrUnauthorized is returned when the user doesn't have access to this resource
var ErrUnauthorized = errors.New("you are not authorized to perform this action")
// ErrInvalidOperation is returned for operations that should never be allowed
var ErrInvalidOperation = errors.New("no permission exists for this operation")
// AuthService is a service for handling the 'orizations and 'entications.
type AuthService struct {
keys repositories.KeyRepository
users repositories.UserRepository
}
// FindKey finds a key by id.
func (s *AuthService) FindKey(ctx context.Context, id string) (*models.Key, error) {
return s.keys.Find(ctx, id)
}
// FindKey finds a key by id.
func (s *AuthService) FindUser(ctx context.Context, id string) (*models.User, error) {
return s.users.Find(ctx, id)
}
// CreateKey generates a new key for the user and name. This
// does not allow generating wildcard keys, they have to be
// manually inserted into the DB.
func (s *AuthService) CreateKey(ctx context.Context, name, user string) (*models.Key, error) {
if user == "*" {
return nil, errors.New("auth: wildcard keys not allowed")
}
secret, err := s.generateSecret()
if err != nil {
return nil, err
}
key := &models.Key{
Name: name,
User: user,
Secret: secret,
}
key, err = s.keys.Insert(ctx, *key)
if err != nil {
return nil, err
}
return key, nil
}
// CheckPermission does some magic.
func (s *AuthService) CheckPermission(ctx context.Context, op string, obj interface{}) error {
token := s.TokenFromContext(ctx)
if token == nil {
return ErrUnauthenticated
}
if v := reflect.ValueOf(obj); v.Kind() == reflect.Struct {
ptr := reflect.PtrTo(v.Type())
ptrValue := reflect.New(ptr.Elem())
ptrValue.Elem().Set(v)
obj = ptrValue.Interface()
}
var authorized = false
switch v := obj.(type) {
case *models.Channel:
authorized = token.Permitted("channel." + op)
case *models.Character:
authorized = token.PermittedUser(v.Author, "member", "character."+op)
case *models.Chapter:
authorized = token.PermittedUser(v.Author, "member", "chapter."+op)
case *models.Comment:
if op == "add" && v.Author != token.UserID {
return ErrInvalidOperation
}
authorized = token.PermittedUser(v.Author, "member", "comment."+op)
case *models.File:
authorized = token.PermittedUser(v.Author, "member", "file."+op)
case *models.Log:
authorized = token.Permitted("log." + op)
case *models.Post:
authorized = token.Permitted("post." + op)
case *models.Story:
authorized = token.PermittedUser(v.Author, "member", "story."+op)
case *models.User:
authorized = token.Permitted("user." + op)
default:
log.Panicf("Invalid model %T: %#+v", v, v)
}
if !authorized {
return ErrUnauthorized
}
return nil
}
// TokenFromContext gets the token from context.
func (s *AuthService) TokenFromContext(ctx context.Context) *models.Token {
token, ok := ctx.Value(contextKey).(*models.Token)
if !ok {
return nil
}
return token
}
// RequestWithToken either returns the request, or the request with a new context that
// has the token.
func (s *AuthService) RequestWithToken(r *http.Request) *http.Request {
header := r.Header.Get("Authorization")
if header == "" {
return r
}
if !strings.HasPrefix(header, "Bearer ") {
return r
}
token, err := s.CheckToken(r.Context(), header[7:])
if err != nil {
return r
}
return r.WithContext(context.WithValue(r.Context(), contextKey, &token))
}
// CheckToken reads the token string and returns a token if everything is kosher.
func (s *AuthService) CheckToken(ctx context.Context, tokenString string) (token models.Token, err error) {
var key *models.Key
jwtToken, err := jwt.Parse(tokenString, func(jwtToken *jwt.Token) (interface{}, error) {
if _, ok := jwtToken.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", jwtToken.Header["alg"])
}
kid, ok := jwtToken.Header["kid"].(string)
if !ok {
return nil, ErrNoKid
}
key, err = s.FindKey(ctx, kid)
if err != nil || key.ID == "" {
return nil, ErrKeyNotFound
}
return []byte(key.Secret), nil
})
if err != nil {
return models.Token{}, err
}
userid, permissions, err := s.parseClaims(jwtToken.Claims)
if err != nil {
return models.Token{}, err
}
if !key.ValidForUser(userid) {
return models.Token{}, ErrWrongUser
}
user, err := s.ensureUser(ctx, userid)
if err != nil {
return models.Token{}, ErrDeletedUser
}
acceptedPermissions := make([]string, 0, len(user.Permissions))
if len(permissions) > 0 {
for _, permission := range permissions {
found := false
for _, userPermission := range user.Permissions {
if permission == userPermission {
found = true
break
}
}
if found {
acceptedPermissions = append(acceptedPermissions, permission)
}
}
} else {
acceptedPermissions = append(acceptedPermissions, user.Permissions...)
}
return models.Token{UserID: user.ID, Permissions: acceptedPermissions}, nil
}
// AllPermissions gets all permissions and their purpose
func (s *AuthService) AllPermissions() map[string]string {
return map[string]string{
"member": "Can add/edit/remove own content",
"user.edit": "Can edit non-owned users",
"character.add": "Can add non-owned characters",
"character.edit": "Can edit non-owned characters",
"character.remove": "Can remove non-owned characters",
"channel.add": "Can add channels",
"channel.edit": "Can edit channels",
"channel.remove": "Can remove channels",
"comment.edit": "Can edit non-owned comments",
"comment.remove": "Can remove non-owned comments",
"log.add": "Can add logs",
"log.edit": "Can edit logs",
"log.remove": "Can remove logs",
"post.add": "Can add posts",
"post.edit": "Can edit posts",
"post.move": "Can move posts",
"post.remove": "Can remove posts",
"story.add": "Can add non-owned stories",
"story.edit": "Can edit non-owned stories",
"story.remove": "Can remove non-owned stories",
"story.unlisted": "Can view non-owned unlisted stories",
"file.upload": "Can upload files",
"file.list": "Can list non-owned files",
"file.view": "Can view non-owned files",
"file.edit": "Can edit non-owned files",
"file.remove": "Can remove non-owned files",
}
}
func (s *AuthService) parseClaims(jwtClaims jwt.Claims) (userid string, permissions []string, err error) {
mapClaims, ok := jwtClaims.(jwt.MapClaims)
if !ok {
return "", nil, ErrInvalidClaims
}
if !mapClaims.VerifyExpiresAt(time.Now().Unix(), true) {
return "", nil, ErrExpired
}
if userid, ok = mapClaims["user"].(string); !ok {
return "", nil, ErrInvalidClaims
}
if claimedPermissions, ok := mapClaims["permissions"].([]interface{}); ok {
for _, permission := range claimedPermissions {
if permission, ok := permission.(string); ok {
permissions = append(permissions, permission)
}
}
if len(permissions) == 0 {
return "", nil, ErrInvalidClaims
}
}
return
}
func (s *AuthService) generateSecret() (string, error) {
var data [64]byte
_, err := rand.Read(data[:])
if err != nil {
return "", err
}
return base64.RawURLEncoding.EncodeToString(data[:]), nil
}
func (s *AuthService) ensureUser(ctx context.Context, id string) (*models.User, error) {
user, err := s.users.Find(ctx, id)
if err == repositories.ErrNotFound {
user = &models.User{
ID: id,
Nick: "",
Permissions: []string{
"member",
"log.edit",
"post.edit",
"post.move",
"post.remove",
"file.upload",
},
}
user, err = s.users.Insert(ctx, *user)
if err != nil {
return nil, err
}
} else if err != nil {
return nil, err
}
return user, err
}
+7 -6
View File
@@ -2,7 +2,6 @@ package services
import (
"context"
"git.aiterp.net/rpdata/api/internal/auth"
"git.aiterp.net/rpdata/api/internal/notifier"
"git.aiterp.net/rpdata/api/models"
"git.aiterp.net/rpdata/api/repositories"
@@ -12,7 +11,8 @@ import (
)
type ChangeService struct {
changes repositories.ChangeRepository
changes repositories.ChangeRepository
authService *AuthService
mutex sync.RWMutex
buffer []models.Change
@@ -31,7 +31,7 @@ func (s *ChangeService) List(ctx context.Context, filter models.ChangeFilter) ([
}
func (s *ChangeService) Submit(ctx context.Context, model models.ChangeModel, op string, listed bool, keys []models.ChangeKey, objects ...interface{}) {
token := auth.TokenFromContext(ctx)
token := s.authService.TokenFromContext(ctx)
if token == nil {
panic("no token!")
}
@@ -127,15 +127,16 @@ func (s *ChangeService) Subscribe(ctx context.Context, filter models.ChangeFilte
func (s *ChangeService) loop() {
for change := range s.submitQueue {
timeout, cancel := context.WithTimeout(context.Background(), time.Second*15)
timeout, cancel := context.WithTimeout(context.Background(), time.Second*5)
change, err := s.changes.Insert(timeout, *change)
if err != nil {
log.Println("Failed to insert change:")
} else {
log.Println("Change", change.ID, "inserted.")
continue
}
log.Println("Change", change.ID, "inserted.")
s.mutex.Lock()
s.buffer = append(s.buffer, *change)
if len(s.buffer) > 16 {
+4 -4
View File
@@ -2,7 +2,6 @@ package services
import (
"context"
"git.aiterp.net/rpdata/api/internal/auth"
"git.aiterp.net/rpdata/api/models"
"git.aiterp.net/rpdata/api/models/changekeys"
"git.aiterp.net/rpdata/api/repositories"
@@ -14,6 +13,7 @@ type ChannelService struct {
channels repositories.ChannelRepository
loader *loaders.ChannelLoader
changeService *ChangeService
authService *AuthService
}
func (s *ChannelService) Find(ctx context.Context, id string) (*models.Channel, error) {
@@ -44,7 +44,7 @@ func (s *ChannelService) List(ctx context.Context, filter models.ChannelFilter)
}
func (s *ChannelService) Create(ctx context.Context, name string, logged, hub bool, eventName, locationName string) (*models.Channel, error) {
err := auth.CheckPermission(ctx, "add", &models.Channel{})
err := s.authService.CheckPermission(ctx, "add", &models.Channel{})
if err != nil {
return nil, err
}
@@ -91,7 +91,7 @@ func (s *ChannelService) Update(ctx context.Context, name string, update models.
return nil, err
}
err = auth.CheckPermission(ctx, "edit", channel)
err = s.authService.CheckPermission(ctx, "edit", channel)
if err != nil {
return nil, err
}
@@ -114,7 +114,7 @@ func (s *ChannelService) Delete(ctx context.Context, name string) (*models.Chann
return nil, err
}
err = auth.CheckPermission(ctx, "remove", channel)
err = s.authService.CheckPermission(ctx, "remove", channel)
if err != nil {
return nil, err
}
+8 -8
View File
@@ -3,7 +3,6 @@ package services
import (
"context"
"errors"
"git.aiterp.net/rpdata/api/internal/auth"
"git.aiterp.net/rpdata/api/models"
"git.aiterp.net/rpdata/api/models/changekeys"
"git.aiterp.net/rpdata/api/repositories"
@@ -16,6 +15,7 @@ type CharacterService struct {
characters repositories.CharacterRepository
loader *loaders.CharacterLoader
changeService *ChangeService
authService *AuthService
}
// Find uses the loader to find the character by the ID.
@@ -65,9 +65,9 @@ func (s *CharacterService) List(ctx context.Context, filter models.CharacterFilt
}
func (s *CharacterService) Create(ctx context.Context, nick, name, shortName, author, description string) (*models.Character, error) {
token := auth.TokenFromContext(ctx)
token := s.authService.TokenFromContext(ctx)
if token == nil {
return nil, auth.ErrUnauthenticated
return nil, ErrUnauthenticated
}
if name == "" {
@@ -91,7 +91,7 @@ func (s *CharacterService) Create(ctx context.Context, nick, name, shortName, au
Description: description,
}
err := auth.CheckPermission(ctx, "add", character)
err := s.authService.CheckPermission(ctx, "add", character)
if err != nil {
return nil, err
}
@@ -112,7 +112,7 @@ func (s *CharacterService) Update(ctx context.Context, id string, name, shortNam
return nil, err
}
err = auth.CheckPermission(ctx, "edit", character)
err = s.authService.CheckPermission(ctx, "edit", character)
if err != nil {
return nil, err
}
@@ -140,7 +140,7 @@ func (s *CharacterService) AddNick(ctx context.Context, id string, nick string)
return nil, err
}
err = auth.CheckPermission(ctx, "edit", character)
err = s.authService.CheckPermission(ctx, "edit", character)
if err != nil {
return nil, err
}
@@ -164,7 +164,7 @@ func (s *CharacterService) RemoveNick(ctx context.Context, id string, nick strin
return nil, err
}
err = auth.CheckPermission(ctx, "edit", character)
err = s.authService.CheckPermission(ctx, "edit", character)
if err != nil {
return nil, err
}
@@ -188,7 +188,7 @@ func (s *CharacterService) Delete(ctx context.Context, id string) (*models.Chara
return nil, err
}
err = auth.CheckPermission(ctx, "edit", character)
err = s.authService.CheckPermission(ctx, "edit", character)
if err != nil {
return nil, err
}
+6 -6
View File
@@ -3,7 +3,6 @@ package services
import (
"context"
"errors"
"git.aiterp.net/rpdata/api/internal/auth"
"git.aiterp.net/rpdata/api/models"
"git.aiterp.net/rpdata/api/repositories"
"github.com/h2non/filetype"
@@ -19,7 +18,8 @@ var ErrCouldNotUploadFile = errors.New("could not upload file")
// FileService is a service for files.
type FileService struct {
files repositories.FileRepository
files repositories.FileRepository
authService *AuthService
}
func (s *FileService) Find(ctx context.Context, id string) (*models.File, error) {
@@ -29,7 +29,7 @@ func (s *FileService) Find(ctx context.Context, id string) (*models.File, error)
}
if !file.Public {
err := auth.CheckPermission(ctx, "view", file)
err := s.authService.CheckPermission(ctx, "view", file)
if err != nil {
return nil, repositories.ErrNotFound
}
@@ -39,7 +39,7 @@ func (s *FileService) Find(ctx context.Context, id string) (*models.File, error)
}
func (s *FileService) List(ctx context.Context, filter models.FileFilter) ([]*models.File, error) {
token := auth.TokenFromContext(ctx)
token := s.authService.TokenFromContext(ctx)
if filter.Public != nil {
if *filter.Public == false {
@@ -48,7 +48,7 @@ func (s *FileService) List(ctx context.Context, filter models.FileFilter) ([]*mo
}
if !token.PermittedUser(*filter.Author, "member", "file.list") {
return nil, auth.ErrUnauthorized
return nil, ErrUnauthorized
}
}
}
@@ -83,7 +83,7 @@ func (s *FileService) Edit(ctx context.Context, id string, name *string, public
return nil, err
}
err = auth.CheckPermission(ctx, "edit", file)
err = s.authService.CheckPermission(ctx, "edit", file)
if err != nil {
if !file.Public {
return nil, repositories.ErrNotFound
+13 -14
View File
@@ -3,10 +3,8 @@ package services
import (
"context"
"errors"
"git.aiterp.net/rpdata/api/internal/auth"
"git.aiterp.net/rpdata/api/models"
"git.aiterp.net/rpdata/api/models/changekeys"
"git.aiterp.net/rpdata/api/models/channels"
"git.aiterp.net/rpdata/api/repositories"
"git.aiterp.net/rpdata/api/services/parsers"
"golang.org/x/sync/errgroup"
@@ -23,6 +21,7 @@ type LogService struct {
changeService *ChangeService
channelService *ChannelService
characterService *CharacterService
authService *AuthService
unknownNicks map[string]int
unknownNicksMutex sync.Mutex
@@ -93,7 +92,7 @@ func (s *LogService) Create(ctx context.Context, title, description, channelName
Open: open,
}
if err := auth.CheckPermission(ctx, "add", log); err != nil {
if err := s.authService.CheckPermission(ctx, "add", log); err != nil {
return nil, err
}
@@ -114,7 +113,7 @@ func (s *LogService) Create(ctx context.Context, title, description, channelName
// Import creates new logs from common formats.
func (s *LogService) Import(ctx context.Context, importer models.LogImporter, date time.Time, tz *time.Location, channelName string, data string) ([]*models.Log, error) {
if err := auth.CheckPermission(ctx, "add", &models.Log{}); err != nil {
if err := s.authService.CheckPermission(ctx, "add", &models.Log{}); err != nil {
return nil, err
}
@@ -126,7 +125,7 @@ func (s *LogService) Import(ctx context.Context, importer models.LogImporter, da
}
eventName := ""
if channel, err := channels.FindName(channelName); err == nil {
if channel, err := s.channelService.Find(ctx, channelName); err == nil {
eventName = channel.EventName
}
@@ -212,7 +211,7 @@ func (s *LogService) Update(ctx context.Context, id string, update models.LogUpd
return nil, err
}
if err := auth.CheckPermission(ctx, "edit", log); err != nil {
if err := s.authService.CheckPermission(ctx, "edit", log); err != nil {
return nil, err
}
@@ -232,7 +231,7 @@ func (s *LogService) SplitLog(ctx context.Context, logId string, startPostId str
if err != nil {
return nil, err
}
if err := auth.CheckPermission(ctx, "add", l); err != nil {
if err := s.authService.CheckPermission(ctx, "add", l); err != nil {
return nil, err
}
@@ -314,11 +313,11 @@ func (s *LogService) SplitLog(ctx context.Context, logId string, startPostId str
func (s *LogService) MergeLogs(ctx context.Context, targetID string, sourceID string, removeAfter bool) (*models.Log, error) {
// Check permissions
if err := auth.CheckPermission(ctx, "edit", &models.Log{}); err != nil {
if err := s.authService.CheckPermission(ctx, "edit", &models.Log{}); err != nil {
return nil, err
}
if removeAfter {
if err := auth.CheckPermission(ctx, "remove", &models.Log{}); err != nil {
if err := s.authService.CheckPermission(ctx, "remove", &models.Log{}); err != nil {
return nil, err
}
}
@@ -393,7 +392,7 @@ func (s *LogService) AddPost(ctx context.Context, logId string, time time.Time,
Time: time,
}
if err := auth.CheckPermission(ctx, "add", post); err != nil {
if err := s.authService.CheckPermission(ctx, "add", post); err != nil {
return nil, err
}
@@ -424,7 +423,7 @@ func (s *LogService) EditPost(ctx context.Context, id string, update models.Post
return nil, err
}
if err := auth.CheckPermission(ctx, "edit", post); err != nil {
if err := s.authService.CheckPermission(ctx, "edit", post); err != nil {
return nil, err
}
@@ -460,7 +459,7 @@ func (s *LogService) MovePost(ctx context.Context, id string, position int) ([]*
return nil, err
}
if err := auth.CheckPermission(ctx, "move", post); err != nil {
if err := s.authService.CheckPermission(ctx, "move", post); err != nil {
return nil, err
}
@@ -491,7 +490,7 @@ func (s *LogService) DeletePost(ctx context.Context, id string) (*models.Post, e
return nil, err
}
if err := auth.CheckPermission(ctx, "remove", post); err != nil {
if err := s.authService.CheckPermission(ctx, "remove", post); err != nil {
return nil, err
}
@@ -523,7 +522,7 @@ func (s *LogService) Delete(ctx context.Context, id string) (*models.Log, error)
return nil, err
}
if err := auth.CheckPermission(ctx, "remove", log); err != nil {
if err := s.authService.CheckPermission(ctx, "remove", log); err != nil {
return nil, err
}
+16 -1
View File
@@ -13,24 +13,37 @@ type Bundle struct {
Logs *LogService
Channels *ChannelService
Stories *StoryService
Auth *AuthService
Files *FileService
}
// NewBundle creates a new bundle.
func NewBundle(db database.Database) *Bundle {
bundle := &Bundle{}
bundle.Auth = &AuthService{
keys: db.Keys(),
users: db.Users(),
}
bundle.Files = &FileService{
files: nil,
authService: bundle.Auth,
}
bundle.Changes = &ChangeService{
changes: db.Changes(),
changes: db.Changes(),
authService: bundle.Auth,
}
bundle.Tags = &TagService{tags: db.Tags()}
bundle.Characters = &CharacterService{
characters: db.Characters(),
loader: loaders.CharacterLoaderFromRepository(db.Characters()),
changeService: bundle.Changes,
authService: bundle.Auth,
}
bundle.Channels = &ChannelService{
channels: db.Channels(),
loader: loaders.ChannelLoaderFromRepository(db.Channels()),
changeService: bundle.Changes,
authService: bundle.Auth,
}
bundle.Logs = &LogService{
logs: db.Logs(),
@@ -38,6 +51,7 @@ func NewBundle(db database.Database) *Bundle {
changeService: bundle.Changes,
channelService: bundle.Channels,
characterService: bundle.Characters,
authService: bundle.Auth,
unknownNicks: make(map[string]int, 512),
}
@@ -47,6 +61,7 @@ func NewBundle(db database.Database) *Bundle {
comments: db.Comments(),
changeService: bundle.Changes,
characterService: bundle.Characters,
authService: bundle.Auth,
}
return bundle
+25 -25
View File
@@ -3,7 +3,6 @@ package services
import (
"context"
"errors"
"git.aiterp.net/rpdata/api/internal/auth"
"git.aiterp.net/rpdata/api/internal/generate"
"git.aiterp.net/rpdata/api/models"
"git.aiterp.net/rpdata/api/models/changekeys"
@@ -18,6 +17,7 @@ type StoryService struct {
comments repositories.CommentRepository
changeService *ChangeService
characterService *CharacterService
authService *AuthService
}
func (s *StoryService) FindStory(ctx context.Context, id string) (*models.Story, error) {
@@ -46,9 +46,9 @@ func (s *StoryService) ListComments(ctx context.Context, chapter models.Chapter,
func (s *StoryService) CreateStory(ctx context.Context, name string, author *string, category models.StoryCategory, listed, open bool, tags []models.Tag, createdDate, fictionalDate time.Time) (*models.Story, error) {
if author == nil {
token := auth.TokenFromContext(ctx)
token := s.authService.TokenFromContext(ctx)
if token == nil {
return nil, auth.ErrUnauthenticated
return nil, ErrUnauthenticated
}
author = &token.UserID
@@ -66,7 +66,7 @@ func (s *StoryService) CreateStory(ctx context.Context, name string, author *str
UpdatedDate: createdDate,
}
if err := auth.CheckPermission(ctx, "add", story); err != nil {
if err := s.authService.CheckPermission(ctx, "add", story); err != nil {
return nil, err
}
@@ -82,9 +82,9 @@ func (s *StoryService) CreateStory(ctx context.Context, name string, author *str
func (s *StoryService) CreateChapter(ctx context.Context, story models.Story, title, source string, author *string, createdDate time.Time, fictionalDate *time.Time, commentMode models.ChapterCommentMode) (*models.Chapter, error) {
if author == nil {
token := auth.TokenFromContext(ctx)
token := s.authService.TokenFromContext(ctx)
if token == nil {
return nil, auth.ErrUnauthenticated
return nil, ErrUnauthenticated
}
author = &token.UserID
@@ -106,11 +106,11 @@ func (s *StoryService) CreateChapter(ctx context.Context, story models.Story, ti
}
if story.Open {
if !auth.TokenFromContext(ctx).Permitted("member", "chapter.add") {
return nil, auth.ErrUnauthorized
if !s.authService.TokenFromContext(ctx).Permitted("member", "chapter.add") {
return nil, ErrUnauthorized
}
} else {
if err := auth.CheckPermission(ctx, "add", chapter); err != nil {
if err := s.authService.CheckPermission(ctx, "add", chapter); err != nil {
return nil, err
}
}
@@ -143,10 +143,10 @@ func (s *StoryService) CreateComment(ctx context.Context, chapter models.Chapter
}
if author == "" {
if token := auth.TokenFromContext(ctx); token != nil {
if token := s.authService.TokenFromContext(ctx); token != nil {
author = token.UserID
} else {
return nil, auth.ErrUnauthenticated
return nil, ErrUnauthenticated
}
}
@@ -162,7 +162,7 @@ func (s *StoryService) CreateComment(ctx context.Context, chapter models.Chapter
EditedDate: createdDate,
Source: source,
}
if err := auth.CheckPermission(ctx, "add", comment); err != nil {
if err := s.authService.CheckPermission(ctx, "add", comment); err != nil {
return nil, err
}
@@ -185,7 +185,7 @@ func (s *StoryService) EditStory(ctx context.Context, story *models.Story, name
panic("StoryService.Edit called with nil story")
}
if err := auth.CheckPermission(ctx, "edit", story); err != nil {
if err := s.authService.CheckPermission(ctx, "edit", story); err != nil {
return nil, err
}
@@ -206,7 +206,7 @@ func (s *StoryService) EditStory(ctx context.Context, story *models.Story, name
}
func (s *StoryService) AddStoryTag(ctx context.Context, story models.Story, tag models.Tag) (*models.Story, error) {
if err := auth.CheckPermission(ctx, "edit", &story); err != nil {
if err := s.authService.CheckPermission(ctx, "edit", &story); err != nil {
return nil, err
}
@@ -223,7 +223,7 @@ func (s *StoryService) AddStoryTag(ctx context.Context, story models.Story, tag
}
func (s *StoryService) RemoveStoryTag(ctx context.Context, story models.Story, tag models.Tag) (*models.Story, error) {
if err := auth.CheckPermission(ctx, "edit", &story); err != nil {
if err := s.authService.CheckPermission(ctx, "edit", &story); err != nil {
return nil, err
}
@@ -249,7 +249,7 @@ func (s *StoryService) EditChapter(ctx context.Context, chapter *models.Chapter,
panic("StoryService.EditChapter called with nil chapter")
}
if err := auth.CheckPermission(ctx, "edit", chapter); err != nil {
if err := s.authService.CheckPermission(ctx, "edit", chapter); err != nil {
return nil, err
}
@@ -274,16 +274,16 @@ func (s *StoryService) EditChapter(ctx context.Context, chapter *models.Chapter,
}
func (s *StoryService) MoveChapter(ctx context.Context, chapter *models.Chapter, from, to models.Story) (*models.Chapter, error) {
if err := auth.CheckPermission(ctx, "move", chapter); err != nil {
if err := s.authService.CheckPermission(ctx, "move", chapter); err != nil {
return nil, err
}
if to.Open {
if !auth.TokenFromContext(ctx).Permitted("member", "chapter.add") {
return nil, auth.ErrUnauthorized
if !s.authService.TokenFromContext(ctx).Permitted("member", "chapter.add") {
return nil, ErrUnauthorized
}
} else {
if err := auth.CheckPermission(ctx, "add", chapter); err != nil {
if err := s.authService.CheckPermission(ctx, "add", chapter); err != nil {
return nil, err
}
}
@@ -304,7 +304,7 @@ func (s *StoryService) EditComment(ctx context.Context, comment *models.Comment,
panic("StoryService.EditChapter called with nil chapter")
}
if err := auth.CheckPermission(ctx, "edit", comment); err != nil {
if err := s.authService.CheckPermission(ctx, "edit", comment); err != nil {
return nil, err
}
@@ -343,7 +343,7 @@ func (s *StoryService) EditComment(ctx context.Context, comment *models.Comment,
}
func (s *StoryService) RemoveStory(ctx context.Context, story *models.Story) error {
if err := auth.CheckPermission(ctx, "add", story); err != nil {
if err := s.authService.CheckPermission(ctx, "add", story); err != nil {
return err
}
@@ -358,7 +358,7 @@ func (s *StoryService) RemoveStory(ctx context.Context, story *models.Story) err
}
func (s *StoryService) RemoveChapter(ctx context.Context, chapter *models.Chapter) error {
if err := auth.CheckPermission(ctx, "remove", chapter); err != nil {
if err := s.authService.CheckPermission(ctx, "remove", chapter); err != nil {
return err
}
@@ -377,7 +377,7 @@ func (s *StoryService) RemoveChapter(ctx context.Context, chapter *models.Chapte
}
func (s *StoryService) RemoveComment(ctx context.Context, comment *models.Comment) error {
if err := auth.CheckPermission(ctx, "remove", comment); err != nil {
if err := s.authService.CheckPermission(ctx, "remove", comment); err != nil {
return err
}
@@ -409,7 +409,7 @@ func (s *StoryService) permittedCharacter(ctx context.Context, permissionKind, c
return errors.New("character could not be found")
}
token := auth.TokenFromContext(ctx)
token := s.authService.TokenFromContext(ctx)
if character.Author != token.UserID && !token.Permitted(permissionKind+".edit") {
return errors.New("you are not permitted to use others' character")
}