golink: listen on HTTPS and redirect HTTP traffic
Updates tailscale/golink#9Fixestailscale/golink#29
On tailnets with HTTPS enabled golink will serve the primary endpoints via
HTTPS. With HTTPS enabled golink will respond to HTTP traffic with a
separate redirectHandler which redirects requests to their HTTPS equivalent.
Update documented examples of `curl` to include the `-L` flog to follow these
redirects if present.
Add a HTTPS section to the README documenting all of the above.
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
I didn't think the order mattered (as long as none of the response body
had been written), but I guess I was wrong. Currently, it's returning
the 302 status, but no Location header. And tests, at least some of
which should be passing through this full code path, are passing. I'll
look into adding better testing later, but for now this fixes the
immediate issue.
Updates #91
Signed-off-by: Will Norris <will@tailscale.com>
Both http.ServeMux as well as the http.Redirect method pass the request
URL through `cleanPath` which, among other things, collapses double
slashes `//` to a single slash `/`. Most of the time this is fine, since
most servers treat those as identical anyway. But some destination
servers need the original path unmodified. Since we're just redirecting,
we don't need to be concerned with the additional benefits of
`cleanPath` such as eliminating `../` path components, since that is the
responsibility of the destination server to clean if needed.
This change adds a separate root http.Handler for golink requests. It
still uses http.ServeMux for internal endpoints, but serves golinks
directly without passing the request through ServeMux. Additionally,
this sets the redirect status and Location header directly rather than
calling http.Redirect, since that also modifies the URL it is given.
Fixes#89
Signed-off-by: Will Norris <will@tailscale.com>
The "tailscale.com/golink" peercap includes a single "admin" bool field.
When set, this grants the user the ability to edit all links stored in
the system.
Update currentUser to return a simple user struct instead of just a bare
username. Rename checkLinkOwnership to canEditLink and change to a bool
return value.
Signed-off-by: Will Norris <will@tailscale.com>
The detail page of a link only displays the form if the link is editable
for the logged in user.
Therefore, it's not necessary to disable the input fields within the
form if the link isn't editable.
Signed-off-by: Marco Hofstetter <marco.hofstetter@bluewin.ch>
Even in dev mode, the user `tagged-devices` should not be
reported as existing user.
This allows editing & deleting links owned by `taggged-devices`
in dev mode.
Signed-off-by: Marco Hofstetter <marco.hofstetter@bluewin.ch>
It should be possible to delete links owned by non-existing users
(tagged-devices or deleted) in the same ways as it's possible
to edit these links.
Signed-off-by: Marco Hofstetter <marco.hofstetter@bluewin.ch>
When resolving a go link, combine the query string parameters from the
request and long URL.
Updates #77
Signed-off-by: Will Norris <will@tailscale.com>
return a *url.URL value from expandLink rather than a string, and both
accept and return a *url.URL value from resolveLink rather than a
string. These are both unexported funcs, so this has no changes to the
current behavior. It does prevent a few unnecessary conversions back and
forth between url.URL and string values, and will make it simpler to
retain request query strings.
Updates #77
Signed-off-by: Will Norris <will@tailscale.com>
Previously, we were parsing from r.RequestURI, which includes both the
path and query string. This causes problem for requests like go/who?q
which try to lookup a link named "who?q" rather than "who" (see #77).
For now, this just ignores the request query string. Eventually we
should probably retain the query string, but this begins by parsing out
the short name properly.
Updates #77
Signed-off-by: Will Norris <will@tailscale.com>
bump version again, back to the latest commit on main, rather than the
latest released version. Otherwise, this causes issues in tailscale's
corp repo (sadly).
Signed-off-by: Will Norris <will@tailscale.com>
If the current user can't be determined (either because of a legitimate
error within the localapi client, or the user is coming through a subnet
router and doesn't have a Tailscale IP address), and the
-allow-unknown-users flag is set, then go ahead and save new links
without an owner.
By saving links without an owner, these unknown users can continue to
modify the link, and actual Tailscale users can take ownership. Once the
link is owned, it can no longer be modified by anyone other than the
owner.
Links that use the current user by having `{{ .User }}` in their long
URL cannot be resolved by unknown users and will return an error.
Fixes#60
Signed-off-by: Will Norris <will@tailscale.com>
To delete a link, go to its page in `.detail` and click on the "Delete"
button. Stats for the deleted link are removed as well.
Co-authored-by: Will Norris <will@tailscale.com>
Signed-off-by: Gabriel Wong <gabriel@bifrost.ai>
Signed-off-by: Will Norris <will@tailscale.com>
Also check error returned from tmpl.Execute. Refactor currentUser to
make the logic a little simpler, and make it a package var for easier
testing.
Signed-off-by: Will Norris <will@tailscale.com>
It's not uncommon to have multiple links pointing to the same
destination, for example to handle different spellings of a word or
because different people created them at different times.
A common best practice is to select one as the "primary" link and point
the others to that link as "aliases". This change updates resolveLink
to follow those aliases so that the final destination is returned when
using `golink -resolve-from-backup`.
Signed-off-by: Will Norris <will@tailscale.com>
Add "User" to the expansion environment for links. The intent here it
support personalized go links such as:
go/mycal => https://calendar.google.com/calendar/embed?src={{.User}}
That's not a terribly interesting example, but there are others I intend
to use internally.
Signed-off-by: Will Norris <will@tailscale.com>
PR #12 changes directory used by Docker image. This commit updates the fly.io
instructions to use the same directory.
Signed-off-by: Gabriel Wong <gabriel@bifrost.ai>
* Add Flake file (Nix package, NixOS module)
This commit adds a Flake.nix file allowing Nix users to consume this
repo with `nix build`, `nix run` and adds a NixOS module to quickly spin
up the service.
* add github action file for nix build
---------
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
Co-authored-by: Xe Iaso <me@xeiaso.net>
Use a build image built for the native architecture so that it doesn't
run in emulation mode.
Switch to Chainguard's wolfi/glibc build image. This limits our build
architectures to just amd64 and arm64, but that is sufficient for our
needs.
Updates #42
Updates #43
Signed-off-by: Will Norris <will@tailscale.com>
Currently, the special "tagged-devices" user (which exists for any
tagged devices in the tailnet) can own go links. This change permits
tagged devices to continue to create go links, but skips over them for
ownership checks, allowing any human user can take over ownership.
Fixes#37
Signed-off-by: Will Norris <will@tailscale.com>
When loading stats from the database, map IDs back to their canonical
short name, which is what we want to show in the frontend. This is only
called once on cold start, so performance of loading all links isn't a
big concern.
Fixes#13
Signed-off-by: Will Norris <will@tailscale.com>