package auth import ( "context" "log" "reflect" "git.aiterp.net/rpdata/api/models" ) // CheckPermission does some magic. func CheckPermission(ctx context.Context, op string, obj interface{}) error { token := 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 }