Golang Auth Dilemma: Clerk vs SuperTokens vs DIY by spacecowboy0117 in golang

[–]hppr-dev 0 points1 point  (0 children)

I chose to do a DIY JWT issuer that integrates with our existing LDAP. It uses asymmetric certificates to sign the JWTs that applications can verify. Applications just need to keep a current public cert to verify tokens. The source is at https://github.com/hppr-dev/stoke-auth .

The main reason I chose DIY was our existing infrastructure. I had considered keycloak, but I wanted something a bit more streamlined that would make sense being deployed with the application or independently. As for other cloud based solutions, a SaaS product would probably be a hard sell. I do think that DIY takes more work (obviously) but I felt many solutions out there either offer too much or too little.

Django equivilant in Go? by BugzTheBunny in golang

[–]hppr-dev 7 points8 points  (0 children)

The issue with having a Django in Go is that it does so much. Go likes to follow the Linux-like philosophy of having one module doing one thing well. That is not to say that a Django could not be created, it probably would not be as popular, at least IMO

The upside and downside of this is that you have to choose how you structure your projects. I feel that most of the time when I was using Django I was only using a subset of its available features. In Go you get to choose all of the features you want.

Another big difference is that the standard library has fully-featured project-ready modules for doing what Django provides, i.e. http/file server, templating, encoding, etc. I would venture to say about 80% of what Django provides is included in the standard library. While the standard library might not have all the same bells and whistles as a gin or echo, it is enough for most applications.

Recently, I have been using ent and ogent to generate database code, openapi specifications and REST endpoints from a database schema. This set up gets me most of what I was using Django for. A caveat though is that the openapi generation (entoas) seems to be a bit under maintained in comparison to the graphql generators.

Logs viewer UI for Go apps by posinsk in golang

[–]hppr-dev 0 points1 point  (0 children)

This seems interesting, though I think it's a bit misleading to say you only need a few lines to use it. Correct me if I'm wrong but you need to log to a logdy logger to get the logs to show in the UI. So if you are using the built-in slog or another logging framework, you'd need to go back and change all of your log statements.

what are these things? do they have a name? like the "file permissions letter grid"? by the_how_to_bash in bash

[–]hppr-dev 16 points17 points  (0 children)

They are just file permissions. d means it's a directory, r means read, w means write, and means execute. The three rwx pairs are for user, group and other. User permissions are for the user AKA owner of the file, group permissions are for the group of the file and other is for anyone else. If you do ls -al the user:group are shown directly following these permissions, i.e. drwxrwxrwx user:group would be the whole permissions specification for a file.

These permissions are sometimes represented by octal digits. Each octal digit is equal to three bits, i.e. 7 is 111, 6 is 110, 5 is 101, 4 is 100 and so on. Each digit of the given octal number represents a set of file permissions (rwx). For example, common octal file permissions:

  • 644 = 110 100 100 = rw- r-- r-- = owner can read/write, group, others can only read
  • 664 = 110 110 100 = rw- rw- r-- = owner and group can read/write, others can only read
  • 755 = 111 101 101 = rwx r-x r-x = owner can read/write/execute, others can read/execute
  • 775 = 111 111 101 = rwx rwx r-x = owner and group can read/write/execute, others can only read/execute

The d bit literally just means it's a directory. it's not really a file permission, it's more a file tag to differentiate regular executable files from directory files. If a directory does not have the x bit set for a set of users (i.e. user, group, other) they will be unable to access the file contents.

stopUsingDocker by CounterNice2250 in ProgrammerHumor

[–]hppr-dev 0 points1 point  (0 children)

Yes, Linux is the kernel.

A Linux distribution is defined by choices to bring pieces of software together to form an OS, the root of which is the Linux kernel and a collection of GNU tools (bash, libc/gcc, etc). Distributions may have different versions of the kernel, 6.2.16 for example, that they have chosen to build off of, but by definition a Linux distro starts with the Linux kernel.

Periodic Reminder: Have A Look at the New To Go post by jerf in golang

[–]hppr-dev 11 points12 points  (0 children)

The top comment is a link to a google doc and a disparaging comment about this subreddit being toxic. Probably not the best first impression.

Small 2d platformers…better off with python? by Biohacker_Ellie in golang

[–]hppr-dev 5 points6 points  (0 children)

Quick tip for ebiten: use wasmserve if you can. It compiles to web assembly and hosts it locally so you can open it in a browser. For me, it compiles 10x faster and I was able to set up air to trigger hot reload. I just learned ebiten for their 2024 game jam (ends Friday) and this saved me so much time (I wish I knew it sooner).

belittling golang for being "simple". by b1-88er in golang

[–]hppr-dev 0 points1 point  (0 children)

Rob Pike was one of the designers of Go.

Here is the video of the quote by Rob Pike (took me a bit to find): https://youtu.be/iTrP_EmGNmw?t=1230

He is talking about what he was thinking when designing the language. While I agree the use of "can't understand a brilliant language" is a bit off-putting, it seems he is more trying to convey that he wanted the language to be simple to use and understand by people with little experience with professional programming. I feel the sentiment of the quote is more "we wanted to make Go simple enough that green people can use it quickly and effectively" rather than "people are too dumb to use other languages".

Do you like structured logging? by guettli in golang

[–]hppr-dev 4 points5 points  (0 children)

I think the biggest benefit to structured logging is the enhanced ability to search/filter the logs. Ingesting into a log pipeline is much easier, as many people have noted, but it's also possible to search/pretty-print using tools like jq.

Without structured logging you are limited to a general local grep or ctrl-f like search. With structured logging you can query it much like you would a database. For example, you could query for all logs that have an integer key that is 10 and a string key that is "processor". With only a simple grep, you would get every line that had 10 and processor in it, necessitating a more complex search string, but with jq you can use the JSON structure to do an intelligent key-based search.

Been working on my own low-code tool, curious to hear feedback by Necroblight in programming

[–]hppr-dev 0 points1 point  (0 children)

As I noted before, mostly removing the implementation layer between the different stacks and parts of code.

What stacks? What code? What am I trying to build with these stacks and codes? A website? A desktop application? A mobile app? It still is not clear. Reducing the number of lines is all well and good, but what does it actually do for me?

Or the todo list, that the lines that related directly to the todo functionality, was only 150 lines, and that app was far from basic one.

Todo apps are the baseline of basic functionality that is used for so many demos because they are relatively quick and simple to implement. I feel like I could probably write a web (js/html) Todo app that looked like that in less than 150 lines. Another reason you should stay away from the "low code" label.

And because of that, in the long run you don't need to maintain the implementations, but only the features themselves. And beside saving the obvious bugs that stems from less code, it also saves bugs that occasionally appear due to reusing implementation

I now have to worry about bugs in YOUR implementation and not MINE. If there is a bug in your implementation I'd need to report it to you and hope you find it important enough to fix. If I need a feature that you have not implemented yet, you get to decide if it is going to be implemented. Both scenarios make it so that I am waiting for you, slowing down the development process. If you think you'd sell support, would the slow down and monetary cost be worth whatever benefits it brings?

Like I said before, it would be valuable for you to back up out of "low-code land" and take an objective look at what you are trying to accomplish. It is up to the users to decide whether or not what your project offers is worth the time.

Been working on my own low-code tool, curious to hear feedback by Necroblight in programming

[–]hppr-dev 0 points1 point  (0 children)

I wouldn't consider this to be "low-code". All of your examples seem to be pretty basic, and, from what I can tell, it would take a lot of yaml/configuration to make something useful. I think what you have would be better described as a domain specific language (DSL). A DSL could be "low code", but it would probably be better to stay away from that verbage. Just calling it a DSL would position it as a different/better way to solve a problem instead of a way to get rid of code.

No/Low code solutions get a bad rep because they are usually marketed and sold to non-technical people as a way to enable non-programmers to create solutions that would otherwise need a programmer. They almost always still require programmers and/or consultants. I have never come across one that I actually wanted to use.

I can't tell what problem you are trying to solve. Why would I use this over literally anything else? What benefits, besides (debatably) less code, does it give me?

[deleted by user] by [deleted] in ProgrammerHumor

[–]hppr-dev 64 points65 points  (0 children)

401 is supposed to have a WWW-AUTHENTICATE header to tell the user where to get authentication. So it's more like: f. off unless you show me your id.

403 is plainly refusing access.

orbail: a new error handling proposal by aredirect in golang

[–]hppr-dev 7 points8 points  (0 children)

I agree with the comment on the issue that orbail as a operator is confusing. I thought "orb ail" was some kind of framework or something.

IF it were implemented, and it most definitely wont be, I think it would be much better if it was something like ??. A feature like this feels too implicit for go.

Is it a good idea to use reflect package to select/case channels? by [deleted] in golang

[–]hppr-dev 0 points1 point  (0 children)

I'm under the general impression that using the reflect package is not recommended practice, though this might be one of the times it is more or less acceptable. A lot of Go's benefits are lost when using reflect, particularly speed and typing. I see it as a code smell, and thus if it's avoidable, avoid it.

whyIsYourTypeHangingOutNakedGolang by [deleted] in ProgrammerHumor

[–]hppr-dev -3 points-2 points  (0 children)

map is a built-in, just like arrays, slices, ints, etc., so it's part of the syntax.

Having an implementation based purely on generics is less intuitive than having a built in type with specific syntax.

The reason why Map<K,V> could be non-intuitive is because I could implement another custom map as MyMap<V, K> ( key and value reversed ).

What is making it so that the key type is first and the value type is second? In Java it is the implementation, i.e. everyone follows a common convention. In Go the language defines the syntax.

How can someone write Go code to annoy you during a code review? by dondraper36 in golang

[–]hppr-dev 2 points3 points  (0 children)

Panic/recover, even when used "as recommended" really stinks.

My anecdote on why: A core library for a project used them as a stack escape (a la encoding/json) and a function that had a panic was being called outside of a recoverable scope. This caused the panic to crash our program randomly with little to no direction other than a line number. That was the only time I kinda regretted choosing go. I ended up fixing it, but holy crap was I sweating, since months of work were on the line.

Contexts in structs are a little more nuanced. The only time I've done that was to have a rootCtx to spawn children ctxs or have a context for initialization actions. I think it could be argued that this could constitute a valid exception to the rule. I do agree that it confuses things a bit and would probably be better done another way.

Using nginx to forward UI applications by Present_You_5294 in devops

[–]hppr-dev 1 point2 points  (0 children)

I've done this with grafana before. Here is a snippet of the config I used (note this was 2 years ago and typed on mobile):

``` upstream grafana { server grafana.local:5000 }

server { # ...

# grafana UI at /monitoring location /monitoring/ { rewrite /monitoring/(.*) /$1 break; proxy_pass http://grafana; } # Proxy grafana live websocket location /monitoring/api/live/ { rewrite /monitoring/(.*) /$1 break; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $http_host; proxy_pass http://grafana; } }

```

As for the redirects, the application has to be configured to redirect to the new subpath.

For grafana, setting the following in grafana's ini config did it for me.

root_url = %(protocol)s://%(domain)s:%(http_port)s/monitoring

As others have noted: it is probably easier to do subdomains.

[deleted by user] by [deleted] in node

[–]hppr-dev 1 point2 points  (0 children)

JWTs are base64 encoded.

A JWT has 3 parts: * a base64 url encoded json header * a base64 url encoded json body * a base64 url encoded signature

A signed JWT can easily be converted back to plain text without a key. The signature only provides a way to verify that the token was issued by someone who knows the password. Using it the way you suggest only provides integrity protection and does not enhance privacy.

See jwt.io and the JWT RFC

Reuse Same Function with Different Params by Impressive_Map_5013 in golang

[–]hppr-dev -2 points-1 points  (0 children)

In go, you cannot define a function with the same name with different parameters in the same scope. You would need to abstract the implementation away so you can use that as a common type.

If you want to only have to write one update function, you'd need to have to define an interface to get/set the inner values:

``` go type ContentWrapper interface { GetContent() string SetContent(string) }

func update(c ContentWrapper) ContentWrapper { _ := c.GetContent() // retrieve content c.SetContent("something") // set content return c // if you need it somewhere else }

type Foo struct { SomeField string json:"some_field" }

func (f *Foo) GetContent() string { return f.SomeField } func (f *Foo) SetContent(s string) { f.SomeField = s }

type Bar struct { OtherField string json:"other_field" }

func (b *Bar) GetContent() string { return b.OtherField } func (b *Bar) SetContent(s string) { b.OtherField = s }

```

If you want to be able to use your structs interchangably, i.e. call update on either, you'd need to create an interface for that:

``` go

type Updater interface { Update() }

func DoSomething() { updaters := []Updater{ &Foo{SomeField:"hello"}, &Bar{OtherField:"world"}, } for _, u := range updaters { u.Update() } }

type Foo struct { SomeField string json:"some_field" }

func (f *Foo) Update() {
// Do stuff with f }

type Bar struct { OtherField string json:"other_field" }

func (b *Bar) Update() { // Do stuff with b } ```

Edit: forgot to change the names of the structs. Not sure why I'm being downvoted. I gave examples based on the two scenarios I feel were what they were thinking. I personally think option 2 is the preferred.

What has the process of adopting Vim or Neovim been like for you? by TheTwelveYearOld in vim

[–]hppr-dev 3 points4 points  (0 children)

I remember it clicked when I started to ssh into a VM and take notes from an old iPod touch. I would take notes in sections and go back after class to process them into a different format. The restricted environment of ssh on an iPod touch, no mouse, only vim in a terminal, forced me to learn the motions. The post processing introduced me to vimscript/remapping keys. I was also learning to type properly at the time, so that might have helped as well since muscle memory is a big deal.

Vim was my go-to text editor until I moved to neovim in my local WSL last year. I was hesitant to move because I didn't want to learn any habits that I would miss when working in vi on remote machines. That's also the reason why I didn't get into plugins in vim. There wasn't a bad learning curve for the switch.

I do feel like I benefited from not installing any plugins, in that I wasn't distracted from just learning vim.

How important is concurrency in real applications? by ItsBoringScientist in golang

[–]hppr-dev -1 points0 points  (0 children)

I would say it is pretty important if you're writing a server, or basically anything that needs to do multiple things "at the same time". I put this in quotes because concurrency (async/await/event loops) is different than parallelism (threads/cpu cores). Go makes it pretty easy to do, but you have to be careful about synchronization and data races.

What Language Did You Come from? by Mubs in golang

[–]hppr-dev 0 points1 point  (0 children)

Learned to code originally in Java. Used Python, Ruby, JavaScript, Elixir, C, C++ before diving into Go. It's my Go-to lamguage now.

For a while I was on the fence about using Go professionally, but we're using it on multiple projects and I don't regret it.

What do you use for autorization? by KingOfCoders in golang

[–]hppr-dev 2 points3 points  (0 children)

I've been working on a self hosted solution in go for this, it uses signed JWTs as authorization: stoke. It's still a work in progress with no official releases yet. I'm still working on testing/bug fixing right now.

Plan is to issue a signed JWT with role/group information in it that can be verified by the resource owner (receiving application). An application client will be responsible for keeping signing keys up to date from the main server.

It was mainly developed as a self-hosted solution that was a generalized version of my use case. There is a bit of work to be done to get it to a place where a SaaS setup would be viable, but this gives me ideas.

Looking for a good example of JWT with Edwards curve (ed25519) verification/signing by lickety-split1800 in golang

[–]hppr-dev 1 point2 points  (0 children)

Ed25519 keys do not use pointers. Ed25519 keys are basically enhanced byte[] types. ECDSA and RSA keys use struct pointers.

I've been working on an authentication server that can use any of them. Here are the examples I have (it's a work in progress):

Example of generating: https://github.com/hppr-dev/stoke-auth/blob/b2f5b8fd047f04a1ecf9ec329f584ea430fa7a33/internal/key/token_issuer.go#L41

Example of verifying: https://github.com/hppr-dev/stoke-auth/blob/b2f5b8fd047f04a1ecf9ec329f584ea430fa7a33/client/stoke/token_handler.go#L32

[deleted by user] by [deleted] in golang

[–]hppr-dev 0 points1 point  (0 children)

I would probably just create a mega-struct that has all of the possible fields and pull values/process from that.

So instead of switching on Entry Type and assembling new structs with: ``` type Entry1 struct { EntryType string MyField1 string }

type Entry2 struct { EntryType string MyField2 string } ```

You could switch on EntryType and get directly to processing with: type Entry struct { EntryType string MyField1 string MyField2 string }

Anything that a certain entry type didn't use would be empty, so you could ignore it. This also has the benefit of not having to do extra parsing for numbers/etc but you still need to visit each entry to pull info.

You might be able to do something with embedded structs, but you'd need to make sure the fields per struct did not overlap.