Пример #1
0
        public Task Invoke(IDictionary<string, object> environment)
        {
            if (!environment.ContainsKey("owin.RequestPath"))
            {
                throw new ApplicationException("Invalid OWIN request. Expected owin.RequestPath, but not present.");
            }

            var path = Uri.UnescapeDataString((string)environment["owin.RequestPath"]);

            if (statelessAuthOptions != null)
            {
                foreach (var ignorePath in statelessAuthOptions.IgnorePaths)
                {
                    var mm = new Minimatcher(ignorePath, new Options(){IgnoreCase = true});

                    if (mm.IsMatch(path))
                    {
                        return nextFunc(environment);
                    }
                }
            }

            var requestHeaders = (IDictionary<string, string[]>)environment["owin.RequestHeaders"];
            if (!requestHeaders.ContainsKey("Authorization"))
            {
                SetResponseStatusCodeAndHeader(environment);
                return ReturnCompletedTask();
            }

            var token = requestHeaders["Authorization"].FirstOrDefault();
            if (string.IsNullOrWhiteSpace(token))
            {
                SetResponseStatusCodeAndHeader(environment);
                return ReturnCompletedTask();
            }

            var validatedUser = tokenValidator.ValidateUser(token);

            if (validatedUser == null)
            {
                SetResponseStatusCodeAndHeader(environment);
                return ReturnCompletedTask();
            }

            if (environment.ContainsKey(ServerUser))
            {
                environment[ServerUser] = validatedUser;
            }
            else
            {
                environment.Add(ServerUser, validatedUser);
            }

            return nextFunc(environment);
        }
Пример #2
0
        ///<summary>Filters a list of inputs against a single pattern.</summary>
        ///<remarks>This function reparses this input on each invocation.  For performance, avoid this function and reuse a Minimatcher instance instead.</remarks>
        public static IEnumerable <string> Filter(IEnumerable <string> list, string pattern, Options?options = null)
        {
            var mm = new Minimatcher(pattern, options);

            list = list.Where(mm.IsMatch);
            if (options != null && options.NoNull)
            {
                list = list.DefaultIfEmpty(pattern);
            }
            return(list);
        }
Пример #3
0
        ///<summary>Creates a filter function that tests input against a pattern.</summary>
        public static Func <string, bool> CreateFilter(string pattern, Options?options = null)
        {
            if (pattern == null)
            {
                throw new ArgumentNullException("pattern");
            }
            // "" only matches ""
            if (string.IsNullOrWhiteSpace(pattern))
            {
                return(string.IsNullOrEmpty);
            }

            var m = new Minimatcher(pattern, options);

            return(m.IsMatch);
        }
Пример #4
0
        public static bool TestWEIgnore(string sourcePath, string serviceToken, string serviceName)
        {
            string ignoreFile = GetIgnoreFile(Path.GetDirectoryName(sourcePath), ".weignore");

            if (string.IsNullOrEmpty(ignoreFile))
                return false;

            string searchPattern;

            using (StreamReader reader = File.OpenText(ignoreFile))
            {
                while ((searchPattern = reader.ReadLine()) != null)
                {
                    searchPattern = searchPattern.Trim();

                    if (string.IsNullOrEmpty(searchPattern) || searchPattern[0] == '!') // Negated pattern
                        continue;

                    int index = searchPattern.LastIndexOf('\t');

                    if (index > 0)
                    {
                        string[] subparts = searchPattern.Substring(++index, searchPattern.Length - index).Split(',')
                                           .Select(p => p.Trim().ToLowerInvariant()).ToArray();

                        if (!(subparts.Contains(serviceToken) || subparts.Contains(serviceName)) &&
                            (subparts.Contains("!" + serviceToken) || subparts.Contains("!" + serviceName) ||
                            !subparts.Any(s => s[0] == '!')))
                            continue;

                        searchPattern = searchPattern.Substring(0, index).Trim('\t');
                    }

                    Minimatcher miniMatcher = new Minimatcher(searchPattern, new Options { AllowWindowsPaths = true });

                    if (miniMatcher.IsMatch(sourcePath))
                        return true;
                }
            }

            return false;
        }
Пример #5
0
        /// <inheritdoc/>
        public override async Task<FtpResponse> Process(FtpCommand command, CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(command.Argument))
            {
                var taskStates = Server.GetBackgroundTaskStates();
                var statusMessage = new StringBuilder();
                statusMessage.AppendFormat("Server functional, {0} open connections", Server.Statistics.ActiveConnections);
                if (taskStates.Count != 0)
                    statusMessage.AppendFormat(", {0} active background transfers", taskStates.Count);
                return new FtpResponse(211, statusMessage.ToString());
            }

            var mask = command.Argument;
            if (!mask.EndsWith("*"))
                mask += "*";

            var mmOptions = new Options()
            {
                IgnoreCase = Data.FileSystem.FileSystemEntryComparer.Equals("a", "A"),
                NoGlobStar = true,
                Dot = true,
            };

            var mm = new Minimatcher(mask, mmOptions);

            var formatter = new LongListFormatter();
            await Connection.WriteAsync($"211-STAT {command.Argument}", cancellationToken);

            foreach (var entry in (await Data.FileSystem.GetEntriesAsync(Data.CurrentDirectory, cancellationToken)).Where(x => mm.IsMatch(x.Name)))
            {
                var line = formatter.Format(entry);
                Connection.Log?.Debug(line);
                await Connection.WriteAsync($" {line}", cancellationToken);
            }

            return new FtpResponse(211, "STAT");
        }
        public string GetSchemaFor(string fileLocation)
        {
            foreach (string url in _schemas.Keys)
            {
                try
                {
                    if (_schemas[url] == null)
                        continue;
                    foreach (string file in _schemas[url])
                    {
                        var pattern = "**/" + file.TrimStart('*', '/');

                        var matche = new Minimatcher(pattern, _options);
                        if (matche.IsMatch(fileLocation))
                            return url;
                    }
                }
                catch
                {
                    Logger.Log("JSON Schema: Couldn't parse " + _schemas[url] + " as a valid regex.");
                }
            }

            return null;
        }
        /// <inheritdoc/>
        public override async Task<FtpResponse> Process(FtpCommand command, CancellationToken cancellationToken)
        {
            await Connection.WriteAsync(new FtpResponse(150, "Opening data connection."), cancellationToken);
            ITcpSocketClient responseSocket;
            try
            {
                responseSocket = await Connection.CreateResponseSocket();
            }
            catch (Exception)
            {
                return new FtpResponse(425, "Can't open data connection.");
            }
            try
            {
                // Parse arguments in a way that's compatible with broken FTP clients
                var argument = new ListArguments(command.Argument);
                var showHidden = argument.All;

                // Instantiate the formatter
                IListFormatter formatter;
                if (string.Equals(command.Name, "NLST", StringComparison.OrdinalIgnoreCase))
                {
                    formatter = new ShortListFormatter();
                }
                else if (string.Equals(command.Name, "LS", StringComparison.OrdinalIgnoreCase))
                {
                    formatter = new LongListFormatter();
                }
                else
                {
                    formatter = new LongListFormatter();
                }

                // Parse the given path to determine the mask (e.g. when information about a file was requested)
                var directoriesToProcess = new Queue<DirectoryQueueItem>();

                // Use braces to avoid the definition of mask and path in the following parts
                // of this function.
                {
                    var mask = "*";
                    var path = Data.Path.Clone();

                    if (!string.IsNullOrEmpty(argument.Path))
                    {
                        var foundEntry = await Data.FileSystem.SearchEntryAsync(path, argument.Path, cancellationToken);
                        if (foundEntry?.Directory == null)
                            return new FtpResponse(550, "File system entry not found.");
                        var dirEntry = foundEntry.Entry as IUnixDirectoryEntry;
                        if (dirEntry == null)
                        {
                            mask = foundEntry.FileName;
                        }
                        else if (!dirEntry.IsRoot)
                        {
                            path.Push(dirEntry);
                        }
                    }
                    directoriesToProcess.Enqueue(new DirectoryQueueItem(path, mask));
                }

                var encoding = Data.NlstEncoding ?? Connection.Encoding;

                using (var stream = await Connection.CreateEncryptedStream(responseSocket.WriteStream))
                {
                    using (var writer = new StreamWriter(stream, encoding, 4096, true)
                    {
                        NewLine = "\r\n",
                    })
                    {
                        while (directoriesToProcess.Count != 0)
                        {
                            var queueItem = directoriesToProcess.Dequeue();

                            var currentPath = queueItem.Path;
                            var mask = queueItem.Mask;
                            var currentDirEntry = currentPath.Count != 0 ? currentPath.Peek() : Data.FileSystem.Root;

                            if (argument.Recursive)
                            {
                                var line = currentPath.ToDisplayString() + ":";
                                Connection.Log?.Debug(line);
                                await writer.WriteLineAsync(line);
                            }

                            var mmOptions = new Options()
                            {
                                IgnoreCase = Data.FileSystem.FileSystemEntryComparer.Equals("a", "A"),
                                NoGlobStar = true,
                                Dot = true,
                            };

                            var mm = new Minimatcher(mask, mmOptions);

                            var entries = await Data.FileSystem.GetEntriesAsync(currentDirEntry, cancellationToken);
                            var enumerator = new DirectoryListingEnumerator(entries, Data.FileSystem, currentPath, true);
                            while (enumerator.MoveNext())
                            {
                                var name = enumerator.Name;
                                if (!enumerator.IsDotEntry)
                                {
                                    if (!mm.IsMatch(name))
                                        continue;
                                    if (name.StartsWith(".") && !showHidden)
                                        continue;
                                }

                                var entry = enumerator.Entry;

                                if (argument.Recursive && !enumerator.IsDotEntry)
                                {
                                    var dirEntry = entry as IUnixDirectoryEntry;
                                    if (dirEntry != null)
                                    {
                                        var subDirPath = currentPath.Clone();
                                        subDirPath.Push(dirEntry);
                                        directoriesToProcess.Enqueue(new DirectoryQueueItem(subDirPath, "*"));
                                    }
                                }

                                var line = formatter.Format(entry, name);
                                Connection.Log?.Debug(line);
                                await writer.WriteLineAsync(line);
                            }
                        }
                    }
                }
            }
            finally
            {
                responseSocket.Dispose();
            }

            // Use 250 when the connection stays open.
            return new FtpResponse(250, "Closing data connection.");
        }
Пример #8
0
        /// <inheritdoc/>
        public override async Task<FtpResponse> Process(FtpCommand command, CancellationToken cancellationToken)
        {
            await Connection.WriteAsync(new FtpResponse(150, "Opening data connection."), cancellationToken);
            ITcpSocketClient responseSocket;
            try
            {
                responseSocket = await Connection.CreateResponseSocket();
            }
            catch (Exception)
            {
                return new FtpResponse(425, "Can't open data connection.");
            }
            try
            {
                var argument = command.Argument;
                IListFormatter formatter;
                if (string.Equals(command.Name, "NLST", StringComparison.OrdinalIgnoreCase))
                {
                    formatter = new ShortListFormatter();
                }
                else
                {
                    formatter = new LongListFormatter();
                }
                var mask = (string.IsNullOrEmpty(argument) || argument.StartsWith("-")) ? "*" : argument;

                var encoding = Data.NlstEncoding ?? Connection.Encoding;

                using (var stream = await Connection.CreateEncryptedStream(responseSocket.WriteStream))
                {
                    using (var writer = new StreamWriter(stream, encoding, 4096, true)
                    {
                        NewLine = "\r\n",
                    })
                    {
                        foreach (var line in formatter.GetPrefix(Data.CurrentDirectory))
                        {
                            Connection.Log?.Debug(line);
                            await writer.WriteLineAsync(line);
                        }

                        var mmOptions = new Options()
                        {
                            IgnoreCase = Data.FileSystem.FileSystemEntryComparer.Equals("a", "A"),
                            NoGlobStar = true,
                            Dot = true,
                        };

                        var mm = new Minimatcher(mask, mmOptions);

                        foreach (var entry in (await Data.FileSystem.GetEntriesAsync(Data.CurrentDirectory, cancellationToken)).Where(x => mm.IsMatch(x.Name)))
                        {
                            var line = formatter.Format(entry);
                            Connection.Log?.Debug(line);
                            await writer.WriteLineAsync(line);
                        }

                        foreach (var line in formatter.GetSuffix(Data.CurrentDirectory))
                        {
                            Connection.Log?.Debug(line);
                            await writer.WriteLineAsync(line);
                        }
                    }
                }
            }
            finally
            {
                responseSocket.Dispose();
            }

            // Use 250 when the connection stays open.
            return new FtpResponse(250, "Closing data connection.");
        }
Пример #9
0
 ///<summary>Filters a list of inputs against a single pattern.</summary>
 ///<remarks>This function reparses this input on each invocation.  For performance, avoid this function and reuse a Minimatcher instance instead.</remarks>
 public static IEnumerable<string> Filter(IEnumerable<string> list, string pattern, Options options = null)
 {
     var mm = new Minimatcher(pattern, options);
     list = list.Where(mm.IsMatch);
     if (options != null && options.NoNull)
         list = list.DefaultIfEmpty(pattern);
     return list;
 }
Пример #10
0
        ///<summary>Creates a filter function that tests input against a pattern.</summary>
        public static Func<string, bool> CreateFilter(string pattern, Options options = null)
        {
            if (pattern == null) throw new ArgumentNullException("pattern");
            // "" only matches ""
            if (String.IsNullOrWhiteSpace(pattern)) return String.IsNullOrEmpty;

            var m = new Minimatcher(pattern, options);
            return m.IsMatch;
        }
Пример #11
0
        public void                                Pattern(string pattern)
        {
            bool not = pattern.StartsWith("!", StringComparison.Ordinal);

            if (not)
            {
                pattern = pattern.Substring(1);
            }

            pattern = _absolutePattern(_cwd, pattern);
            var f = pattern.IndexOfAny(new char[] { '*', '?', '[', '(', '{', '+' });

            if (f < 0)
            {
                if (!not)
                {
                    if (File.Exists(pattern.Replace('/', '\\')))
                    {
                        var key = pattern.ToLowerInvariant();
                        if (!_files.ContainsKey(key))
                        {
                            _files.Add(key, pattern);
                        }
                    }
                }
                else
                {
                    var key = pattern.ToLowerInvariant();
                    if (_files.ContainsKey(key))
                    {
                        _files.Remove(key);
                    }
                }
            }
            else
            {
                f = pattern.LastIndexOf('/', f);
                if (f < 0)
                {
                    throw new FormatException("Can't deterim root.");
                }

                var root    = pattern.Substring(0, f);
                var matcher = new Minimatch.Minimatcher(pattern.Substring(f + 1));

                if (!not)
                {
                    foreach (var filename in Directory.EnumerateFiles(root.Replace('/', '\\'), "*", SearchOption.AllDirectories))
                    {
                        var key = filename.Replace('\\', '/').ToLowerInvariant();
                        if (!_files.ContainsKey(key) && matcher.IsMatch(key.Substring(f + 1)))
                        {
                            _files.Add(key, filename);
                        }
                    }
                }
                else
                {
                    root = (root + '/').ToLowerInvariant();
                    var toremove = new List <string>();
                    foreach (var key in _files.Keys)
                    {
                        if (key.StartsWith(root, StringComparison.Ordinal))
                        {
                            if (matcher.IsMatch(key.Substring(f + 1)))
                            {
                                toremove.Add(key);
                            }
                        }
                    }

                    foreach (var key in toremove)
                    {
                        _files.Remove(key);
                    }
                }
            }

//            var glob = Glob.Parse();
        }