mirror of
https://github.com/j3ssie/osmedeus.git
synced 2026-08-26 09:32:28 +02:00
206 lines
5.5 KiB
Go
206 lines
5.5 KiB
Go
package core
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"net/url"
|
|
"os"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// Dependencies defines workflow requirements
|
|
type Dependencies struct {
|
|
Commands []string `yaml:"commands"`
|
|
Files []string `yaml:"files"`
|
|
Variables []VariableDep `yaml:"variables"`
|
|
TargetTypes []TargetType `yaml:"target_types"`
|
|
FunctionsConditions []string `yaml:"functions_conditions"`
|
|
}
|
|
|
|
// VariableDep defines variable requirements
|
|
type VariableDep struct {
|
|
Name string `yaml:"name"`
|
|
Type VariableType `yaml:"type"`
|
|
Required bool `yaml:"required"`
|
|
}
|
|
|
|
// HasCommandDeps returns true if there are command dependencies
|
|
func (d *Dependencies) HasCommandDeps() bool {
|
|
return d != nil && len(d.Commands) > 0
|
|
}
|
|
|
|
// HasFileDeps returns true if there are file dependencies
|
|
func (d *Dependencies) HasFileDeps() bool {
|
|
return d != nil && len(d.Files) > 0
|
|
}
|
|
|
|
// HasVariableDeps returns true if there are variable dependencies
|
|
func (d *Dependencies) HasVariableDeps() bool {
|
|
return d != nil && len(d.Variables) > 0
|
|
}
|
|
|
|
// HasFunctionConditions returns true if there are function-based condition dependencies
|
|
func (d *Dependencies) HasFunctionConditions() bool {
|
|
return d != nil && len(d.FunctionsConditions) > 0
|
|
}
|
|
|
|
// GetRequiredVariables returns all required variable dependencies
|
|
func (d *Dependencies) GetRequiredVariables() []VariableDep {
|
|
if d == nil {
|
|
return nil
|
|
}
|
|
var required []VariableDep
|
|
for _, v := range d.Variables {
|
|
if v.Required {
|
|
required = append(required, v)
|
|
}
|
|
}
|
|
return required
|
|
}
|
|
|
|
var domainRegex = regexp.MustCompile(`^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$`)
|
|
var numericRegex = regexp.MustCompile(`^-?\d+(\.\d+)?$`)
|
|
var simpleRepoRegex = regexp.MustCompile(`^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$`)
|
|
var hostedRepoRegex = regexp.MustCompile(`^(?:(?:https?://)?(?:www\.)?(github\.com|gitlab\.com)/)([A-Za-z0-9_.-]+)/([A-Za-z0-9_.-]+?)(?:\.git)?/?$`)
|
|
var sshRepoRegex = regexp.MustCompile(`^git@[^:]+:([A-Za-z0-9_.-]+)/([A-Za-z0-9_.-]+?)(\.git)?$`)
|
|
|
|
func MatchesVariableType(value string, varType VariableType) (bool, error) {
|
|
switch varType {
|
|
case VarTypeDomain:
|
|
return domainRegex.MatchString(value), nil
|
|
case VarTypeSubdomain:
|
|
if !domainRegex.MatchString(value) {
|
|
return false, nil
|
|
}
|
|
return strings.Count(value, ".") >= 2, nil
|
|
case VarTypeURL:
|
|
u, err := url.Parse(value)
|
|
if err != nil {
|
|
return false, nil
|
|
}
|
|
if u.Scheme == "http" || u.Scheme == "https" {
|
|
return u.Host != "", nil
|
|
}
|
|
return false, nil
|
|
case VarTypeCIDR:
|
|
_, _, err := net.ParseCIDR(value)
|
|
return err == nil, nil
|
|
case VarTypeIP:
|
|
return net.ParseIP(value) != nil, nil
|
|
case VarTypeRepo:
|
|
return isRepo(value), nil
|
|
case VarTypePath, VarTypeFile, VarTypeFolder:
|
|
return value != "", nil
|
|
case VarTypeNumber:
|
|
return numericRegex.MatchString(value), nil
|
|
case VarTypeString:
|
|
return true, nil
|
|
default:
|
|
return false, fmt.Errorf("unknown variable type: %s", varType)
|
|
}
|
|
}
|
|
|
|
// MatchesAnyVariableType checks if value matches ANY of the comma-separated types.
|
|
// Returns true if value matches at least one type.
|
|
func MatchesAnyVariableType(value string, typeSpec VariableType) (bool, error) {
|
|
types := strings.Split(string(typeSpec), ",")
|
|
|
|
for _, t := range types {
|
|
t = strings.TrimSpace(t)
|
|
if t == "" {
|
|
continue
|
|
}
|
|
matches, err := MatchesVariableType(value, VariableType(t))
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if matches {
|
|
return true, nil
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
// MatchesAnyTargetType checks if target matches ANY of the comma-separated types.
|
|
// Returns true if target matches at least one type.
|
|
func MatchesAnyTargetType(target string, typeSpec TargetType) (bool, error) {
|
|
types := strings.Split(string(typeSpec), ",")
|
|
|
|
for _, t := range types {
|
|
t = strings.TrimSpace(t)
|
|
if t == "" {
|
|
continue
|
|
}
|
|
matches, err := MatchesTargetType(target, TargetType(t))
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if matches {
|
|
return true, nil
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func MatchesTargetType(target string, targetType TargetType) (bool, error) {
|
|
switch targetType {
|
|
case TargetTypeDomain:
|
|
return MatchesVariableType(target, VarTypeDomain)
|
|
case TargetTypeSubdomain:
|
|
return MatchesVariableType(target, VarTypeSubdomain)
|
|
case TargetTypeURL:
|
|
return MatchesVariableType(target, VarTypeURL)
|
|
case TargetTypeCIDR:
|
|
return MatchesVariableType(target, VarTypeCIDR)
|
|
case TargetTypeRepo:
|
|
return MatchesVariableType(target, VarTypeRepo)
|
|
case TargetTypePath:
|
|
return MatchesVariableType(target, VarTypePath)
|
|
case TargetTypeNumber:
|
|
return MatchesVariableType(target, VarTypeNumber)
|
|
case TargetTypeString:
|
|
return true, nil
|
|
case TargetTypeIP:
|
|
return MatchesVariableType(target, VarTypeIP)
|
|
case TargetTypeFile:
|
|
info, err := os.Stat(target)
|
|
if err != nil {
|
|
return false, nil
|
|
}
|
|
return !info.IsDir(), nil
|
|
case TargetTypeFolder:
|
|
info, err := os.Stat(target)
|
|
if err != nil {
|
|
return false, nil
|
|
}
|
|
return info.IsDir(), nil
|
|
default:
|
|
return false, fmt.Errorf("unknown target type: %s", targetType)
|
|
}
|
|
}
|
|
|
|
func isRepo(value string) bool {
|
|
if simpleRepoRegex.MatchString(value) {
|
|
return true
|
|
}
|
|
if hostedRepoRegex.MatchString(value) {
|
|
return true
|
|
}
|
|
if sshRepoRegex.MatchString(value) {
|
|
return true
|
|
}
|
|
u, err := url.Parse(value)
|
|
if err == nil && (u.Scheme == "http" || u.Scheme == "https" || u.Scheme == "ssh" || u.Scheme == "git") {
|
|
parts := strings.Split(strings.Trim(u.Path, "/"), "/")
|
|
if len(parts) >= 2 {
|
|
owner := parts[0]
|
|
repo := strings.TrimSuffix(parts[1], ".git")
|
|
if owner != "" && repo != "" {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|