Giter Site home page Giter Site logo

netgolynx's Introduction

DotNet Go Lynx

Go links implementation in .NET!

What

Go links are a popular internal corporate url shortener system. Instead of going to https://confluence.internal.domain.corp.local/this/isan/obnoxious/url/tofind/each/time/youneed/it/ugh you can use go/wiki instead!

Why?

My company didn't have one and it sounded like a fun learning experiment.

What can it do?

Like any URL shortener, it can take a valid URL string (anything other than {} | ^ ~ [] ` ; /\ ? : @ # = % & <> and spaces). This includes emoji ๐Ÿ‘! You can add and delete URLs as much as you like.

There's just one exception: the redirect _ is reserved for the user interface and the API.

Contributing

PRs accepted! Please make sure your code follows the editorconfig in the repository and otherwise adheres to standard C# development practices.

Running

GoLynx is designed to be deployed as a docker container with a SQLite database file located nearby, preferably in a mounted volume of some sort. Add a DNS CNAME entry for your default DNS resolution domain for go, such as go.contoso.local, directing to wherever you've hosted the app. At that point you're off to the races.

โš  Keep in mind that this is effectively a wide open DNS resolver. You really should avoid running this on unsecured networks. It can be used for all sorts of phishing and reflection attacks. You have been warned.

I just want to run the thing to look at it!

Unfortunately you'll need to have an HTTPS cert to be able to log into the app. Chrome, Edge, and other browsers have a security requirement around cookies that makes OAuth fail if you try to run NetGoLynx on non-HTTPS connections.

Fortunately it's easy to get set up with a development certificate locally with dotnet dev-certs.

To run it quickly:

  1. Clone the repo.
  2. Create a GitHub App using the config guide below.
  1. Add the GitHub ClientId and ClientSecret to the appsettings.json file, it should look something like the configuration example below
  2. Delete the "Google" and "Okta" sections out of the appsettings.json file.
  3. From the NetGoLynx directory:

PowerShell on Windows:

# Generate the certificate
$pass = "{TypeSomeRandomCharactersHere}"
dotnet dev-certs https -ep $env:USERPROFILE\.aspnet\https\NetGoLynx.pfx -p $pass
dotnet dev-certs https --trust

# Build the docker container
cd ./NetGoLynx
docker build . -t netgolynx-personal

# Run it with the dev cert
docker run --rm -it -p 8001:443 -e ASPNETCORE_URLS="https://+" -e ASPNETCORE_HTTPS_PORT=8001 -e ASPNETCORE_Kestrel__Certificates__Default__Password="$pass" -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/NetGoLynx.pfx -v $env:USERPROFILE\.aspnet\https:/https/ netgolynx-personal

Open https://localhost:8001 in your browser and you should be good to go. Log in, add a link, then use https://localhost:8001/your-link to resolve it. If you're feeling really fancy you can add a hosts file redirect for go on your machine to really give it a spin.

Keep in mind that as soon as you close that powershell terminal or stop the process you will lose all your links, you should only use this for testing!

Configuration Example

{
  "ConnectionStrings": {
    "Sqlite": "Data Source=redirects.db"
  },
  "AllowedHosts": "*",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "AccountSettings": {
    "AdminList": "your_github_email_address"
  },
  "Authentication": {
    "GitHub": {
      "ClientId": "Your_ClientID_from_step_2",
      "ClientSecret": "Your_Client_Secret_from_step_2",
      "AuthorizationEndpoint": "https://github.com/login/oauth/authorize",
      "TokenEndpoint": "https://github.com/login/oauth/access_token",
      "UserInformationEndpoint": "https://api.github.com/user",
      "UserEmailsEndpoint": "https://api.github.com/user/emails"
    }
  }
}

Configuration

For more details on configuration see the configuration docs.

Running on Nomad

For an example jobspec for Nomad see the configuration example.

Health checks

When running in a cluster management of some sort you'll probably want to configure a healthcheck at /_/health. By default this will run a handful of fairly lightweight checks to ensure that the app can support redirecting URLs. If the app is in a state where it cannot resolve redirects it will show as unhealthy.

Why not use the more standard /health endpoint? Simple: that's a valid shortlink! It could be a link to your company's health practices, or maybe the gym membership signup information. All API endpoints are under the /_/ path, including the health endpoint.

netgolynx's People

Contributors

cellivar avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

stjordanis

netgolynx's Issues

Alternate Database Backends

Currently NetGoLynx will only use a built-in SQLite database file mapped to the local filesystem somewhere.

Make the database layer agnostic and able to support remote DB endpoints, especially PostgreSQL as that appears to be the db du juor. MySQL is a nice bonus. Realistically anything that supports the same SQL subset should be sufficient for storage.

Make sure that performance won't be harmed much by adding a remote DB. It's likely in live deployments that it'll not be as fast on first pull but once it's cached it should be quicker.

Add in ratelimiting

To discourage use as a cheap and hacky internal DNS service add in some rate limiting so that people don't try to use it in an automated fashion.

Okta Sign In

A number of people have mentioned Okta support would be cool (and probably easier than getting GSuite/Google auth working).

Admin accounts

It seems prudent to have accounts which can view all links in the system.

Usage metrics

Right now there's no insight into what the system is doing or how healthy it is. This makes monitoring, uh, difficult.

Investigate various ways of exposing metrics (safely!) that would be useful for monitoring and observation.

Consider how SLO's work according to SRE practices and make it easy to expose those metrics specifically.

Apparently exposing Prometheus formatted JSON is the way to go these days and is relatively easy to do. Add a meta endpoint under the underscore URL for /healthz and /metricz, and while we're at it why not add a /readyz endpoint to indicate that it's up, running, has a db connection, and is good to go.

Slack integration

Dropping go/thing into a slack conversation and having it either rewrite it to a link or just have a bot chime in with the link would be nice.

Export SQLite DB function for admins

There are apparently situations where accessing the underlying SQLite database file is non-trivial for backup purposes. Add an ability for admin accounts to perform a SQLite database dump via the web interface so they can perform backups.

Template URLs

Introduce a feature for URL templates. This is akin to URL rewrite modules.

Currently the format of a link is go/, which is a static redirect to a specific URL.

Modify this format to allow for go//, which will then take the and inject it into the URL in the appropriate location.

Example:
go/jira/JIRAID
redirects to
https://jira.somecompany.com/browse/{JIRAID}

Navigating the browser to http://go/jira/JIRA-53 would redirect to https://jira.somecompany.com/browse/JIRA-53

This is obviously a hilarious phishing opportunity which drives home the idea that this should be run only internally.

Transfer ownership of link

If a user no longer wishes to own a link the only way to relinquish that ownership is to delete it. Provide a mechanism to transfer the link to another account.

Add distributed caching and explicit cache invalidation

Links ultimately end up as extremely read heavy operations, they're generated once and can be served many more times than they will be modified. They're an excellent target for heavy long-lived caching with distributed caches such as Redis.

Currently there is an in-memory cache that will temporarily cache entries for a set amount of time before purging. This mostly only helps with rapid repeat queries and only helps individual instances. If a cluster of instances are running as HA round-robin style the benefits of the in-memory cache go way down.

Add support for an external caching service that will automatically disable the in-memory cache in favor of the external distributed cache. For a first implementation go for Redis support since it seems to be both pretty easy as well as pretty popular.

The specific detail to implement here would be support for cache updates on deletes and re-creates. Because 'editing' a golink isn't a relevant concept at the moment we can simply forcibly delete the cache entry for a link when we delete it out of the database.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.