diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a6caeb0..15aa593 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,8 +27,8 @@ jobs: - name: Set up Elixir uses: erlef/setup-beam@v1 # https://github.com/erlef/setup-beam with: - elixir-version: '1.14.2' # Define the elixir version [required] - otp-version: '24.3.4' # Define the OTP version [required] + elixir-version: '1.18.4' # Define the elixir version [required] + otp-version: '28.0.1' # Define the OTP version [required] - name: Restore dependencies cache uses: actions/cache@v4 with: diff --git a/.gitignore b/.gitignore index 81433f2..3bf5313 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,5 @@ _logs/ id_rsa_fly id_rsa_fly-cert.pub .vscode -backup.sql \ No newline at end of file +backup.sql +backup.sql.zip \ No newline at end of file diff --git a/README.md b/README.md index 4b9b2dd..6093155 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@
-![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/dwyl/hits/ci.yml?label=build&style=flat-square&branch=main) +[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/dwyl/hits/ci.yml?label=build&style=flat-square&branch=main)](https://github.com/dwyl/hits/actions/workflows/ci.yml) [![codecov.io](https://img.shields.io/codecov/c/github/dwyl/hits/master.svg?style=flat-square)](https://codecov.io/github/dwyl/hits?branch=master) [![HitCount](https://hits.dwyl.com/dwyl/hits.svg)](https://github.com/dwyl/hits) [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat-square)](https://github.com/dwyl/hits/issues/74) diff --git a/lib/hits/validate.ex b/lib/hits/validate.ex new file mode 100644 index 0000000..67f7879 --- /dev/null +++ b/lib/hits/validate.ex @@ -0,0 +1,14 @@ +defmodule Hits.Validate do + @doc """ + Validate GitHub user/org and repository name (Strings). + """ + + # ^[[:alnum:]-_.]+$ means the name is composed of + # one or multiple alphanumeric character + # or "-_." characters + def repository_valid?(repo), do: String.match?(repo, ~r/^[[:alnum:]\-_.]+$/) + + # see: https://github.com/dwyl/hits/issues/154 + # alphanumeric follow by one or zero "-" or just alphanumerics + def user_valid?(user), do: String.match?(user, ~r/^([[:alnum:]]+-)*[[:alnum:]]+$/) +end diff --git a/lib/hits_web/controllers/hit_controller.ex b/lib/hits_web/controllers/hit_controller.ex index 3998980..b6faf19 100644 --- a/lib/hits_web/controllers/hit_controller.ex +++ b/lib/hits_web/controllers/hit_controller.ex @@ -2,7 +2,7 @@ defmodule HitsWeb.HitController do use HitsWeb, :controller # use Phoenix.Channel # import Ecto.Query - alias Hits.{Hit, Repository, User, Useragent} + alias Hits.{Hit, Repository, User, Useragent, Validate} use Params @@ -39,9 +39,11 @@ defmodule HitsWeb.HitController do params = Params.data(schema) params_map = Params.to_map(schema) - if schema.valid? and user_valid?(user) and repository_valid?(repo) do + if schema.valid? + and Validate.user_valid?(user) + and Validate.repository_valid?(repo) do # insert hit. Note: the .svg is for legacy reasons 🙄 - {_user_schema, _useragent_schema, repo} = insert_hit(conn, user, "#{repo}.svg") + {_user_schema, _ua_schema, repo} = insert_hit(conn, user, "#{repo}.svg") count = if params.show == "unique" do @@ -203,13 +205,4 @@ defmodule HitsWeb.HitController do |> send_resp(404, Hits.make_badge(404, params["style"])) end end - - # see: https://github.com/dwyl/hits/issues/154 - # alphanumeric follow by one or zero "-" or just alphanumerics - defp user_valid?(user), do: String.match?(user, ~r/^([[:alnum:]]+-)*[[:alnum:]]+$/) - - # ^[[:alnum:]-_.]+$ means the name is composed of - # one or multiple alphanumeric character - # or "-_." characters - defp repository_valid?(repo), do: String.match?(repo, ~r/^[[:alnum:]-_.]+$/) end diff --git a/mix.exs b/mix.exs index e0b497e..8c802d9 100644 --- a/mix.exs +++ b/mix.exs @@ -12,15 +12,21 @@ defmodule Hits.MixProject do aliases: aliases(), deps: deps(), test_coverage: [tool: ExCoveralls], - preferred_cli_env: [ + package: package(), + description: "Track page views on any GitHub page" + ] + end + + def cli do + [ + preferred_envs: [ c: :test, coveralls: :test, "coveralls.detail": :test, "coveralls.post": :test, - "coveralls.html": :test - ], - package: package(), - description: "Track page views on any GitHub page" + "coveralls.html": :test, + docs: :docs + ] ] end diff --git a/test/hits/validate_test.exs b/test/hits/validate_test.exs new file mode 100644 index 0000000..00a31fa --- /dev/null +++ b/test/hits/validate_test.exs @@ -0,0 +1,18 @@ +defmodule Hits.ValidateTest do + use ExUnit.Case, async: true + alias Hits.Validate + + test "user_valid?/1 returns true if the string is a valid GitHub username" do + user = "pink-fluffy-unicorns-123" + # dbg(user) + assert Validate.user_valid?(user) == true + assert Validate.user_valid?("c@t") == false + end + + test "repository_valid?/1 returns true if a string is a valid GitHub repo" do + repo = "pink-fluffy-unicorns_123" + # dbg(repo) + assert Validate.repository_valid?(repo) == true + assert Validate.repository_valid?("c@t") == false + end +end