Fork me on GitHub
#beginners
<
2021-02-12
>
Adrian Imanuel11:02:08

Hi Guys, i'd like to connect clojure with google sheets. https://github.com/SparkFund/google-apps-clj Question is where should i put this in the project.clj ? [google-apps-clj "0.6.1"] is it under dependencies?

(defproject asdf "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url ""
  :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
            :url ""}
  :dependencies [[org.clojure/clojure "1.10.1"]]
  :main ^:skip-aot asdf.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all
                       :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}})

Adrian Imanuel14:02:00

@UEQPKG7HQ, ive tried to follow steps : Obtaining OAuth 2 Credentials but stuck at step 6, i've create the google-creds.edn, where should i save this?

Adrian Imanuel14:02:57

whenever i called (edn/read-string (slurp "config/google-creds.edn")) , repl error said no such namespace: edn

pavlosmelissinos15:02:23

there's no namespace called edn

pavlosmelissinos15:02:28

read-string is a function that exists in clojure.edn : Check out the examples here: https://clojuredocs.org/clojure.edn/read-string

raicotop14:02:40

Hi, I'm taking a look at https://github.com/bbatsov/clojure-style-guide#nil-punning

;; good
(defn print-seq [s]
  (when (seq s)
    (prn (first s))
    (recur (rest s))))

;; bad
(defn print-seq [s]
  (when-not (empty? s)
    (prn (first s))
    (recur (rest s))))
I always use empty? because I find it more clear and readable. Would anyone please explain why it's considered bad?

dharrigan14:02:02

It's not that it's bad or better, it's more idiomatic...

dharrigan14:02:18

user=> (doc empty?)
-------------------------
clojure.core/empty?
([coll])
  Returns true if coll has no items - same as (not (seq coll)).
  Please use the idiom (seq x) rather than (not (empty? x))
nil
user=> 

dharrigan14:02:26

The thing about seq is that it will return the collection, whereas empty? will simply return true or false

lispyclouds14:02:03

Also empty? is implemented as (not (seq coll)) so you're kinda doing a double negation.

lispyclouds14:02:46

you could use https://clojuredocs.org/clojure.core/not-empty if it helps with the reading, but has the same outputs as seq

dharrigan14:02:20

I would posit too that a clojurist reading clojure code would understand if they saw something like (when-let [foo (seq (get-data))] ... ) would know what's going on ๐Ÿ™‚

Adrian Imanuel14:02:47

Hi https://github.com/SparkFund/google-apps-clj i've tried to follow steps : Obtaining OAuth 2 Credentials but stuck at step 6, i've create the google-creds.edn, where should i save this? whenever i called (edn/read-string (slurp "config/google-creds.edn")) , repl error said no such namespace: edn

dharrigan14:02:48

You need to bring in the edn namespace,

dharrigan14:02:08

(require '[clojure.edn :as edn])

dharrigan14:02:24

user=> (require '[clojure.edn :as edn])
nil

dharrigan14:02:33

user=> (edn/read-string (slurp "/home/david/foo.edn"))
{:foo [1 2 3]}

Adrian Imanuel14:02:13

does clojre.edn , the "clojure" can be changed with my project name? (require '[asdf.edn :as edn])

dharrigan14:02:36

No, it's a "core" library, part of clojure

dharrigan14:02:46

it's namespace is clojure.edn

dharrigan14:02:53

it's like, in java doing an import java.time.LocalDate

Adrian Imanuel15:02:09

@dharrigan then in step 9 how do i call google-apps-clj.credentials/get-auth-map?

dharrigan15:02:56

I would imagine, without knowing the api at all, something like this:

dharrigan15:02:43

Their tests sorta show how it works

dharrigan15:02:59

so instead of calling default-credential you call get-auth-map passing in the slurped data from the edn file

dharrigan15:02:30

(gauth/get-auth-map (edn/read-string (slurp "/home/adrian/my-credentials.edn")) scope)

dharrigan15:02:32

with scope set to be "" or one of the other examples

Adrian Imanuel15:02:54

I'm lost here... Apologize bcs I'm still newbie here. I'd like to ask when we put this [google-apps-clj "0.6.1"]within dependencies in project.clj then i run lein deps in my cmd. it's kinda installing/downloading, where this library stored?

dharrigan15:02:45

that's okay, we're all beginners ๐Ÿ™‚

dharrigan15:02:19

Okay, so you are using leiningen, you have a project.clj?

dharrigan15:02:28

or are you using deps.edn?

Adrian Imanuel15:02:43

i use project.clj

dharrigan15:02:53

Take for example, the google apis project.clj

dharrigan15:02:07

you can see that the dependencies are in a block called dependencies

dharrigan15:02:21

in your project, you would add in the google-aps-clj into your dependencies block

Adrian Imanuel15:02:18

yes, i've add [google-apps-clj "0.6.1"] in my dependencies block

dharrigan15:02:22

so, now you can do lein repl to bring up a repl for experimentation

dharrigan15:02:52

great, so now you can require in the various libraries for playing around, such as the google apps library

Adrian Imanuel15:02:28

my repl now ready

dharrigan15:02:52

very good, now you can add in the requires, think of "imports" like you would in java

dharrigan15:02:10

their tests, which I linked previously, shows how to import their libraries

Adrian Imanuel15:02:27

OHHHHHHHHHHHH... like this? since i'm going to use google sheets, i take the require from https://github.com/SparkFund/google-apps-clj/blob/develop/test/google_apps_clj/google_sheets_v4_test.clj

dharrigan15:02:11

not quite, nealry

dharrigan15:02:20

you don't ns their stuff

dharrigan15:02:26

you require it into yours

Adrian Imanuel15:02:31

sorry, this is revised

dharrigan15:02:31

Let me show you...

dharrigan15:02:40

that is better

dharrigan15:02:50

now you have their stuff required into your namespace

dharrigan15:02:10

that should get you going now ๐Ÿ™‚

dharrigan15:02:49

It's okay, it's a warning

Adrian Imanuel15:02:16

step 9 still is really confusing.

Adrian Imanuel15:02:31

it doesn't result anything in repl.

pavlosmelissinos15:02:54

You're not using the function step 9 is telling you to call.

Adrian Imanuel15:02:20

I'm sorry, but how to call it?

dharrigan16:02:24

Is this your first time using Clojure may I ask?

Adrian Imanuel16:02:04

Sadly yes.. I'm learning from braveclojure until ch 9 now

Adrian Imanuel16:02:32

apologize if i really don't understand... i never touch java either

dharrigan16:02:40

I think, learning to do oauth2 authentication to google, is a big big step

๐Ÿ˜… 3
dharrigan16:02:30

Could you start with something smaller perhaps? Learn how to invoke functions, passing in arguments?

dharrigan16:02:59

loading (requiring) in namespaces and working with the functions defined within them?

dharrigan16:02:29

Very happy to help, but it does seem like more basics are required first, until you tackle the beast that is oauth2

dharrigan16:02:38

and trust me, oauth2 sucks

Adrian Imanuel16:02:18

allright, i'll re-learn again about the :require once i could do the csv api, but this google things... is very difficult

dharrigan16:02:08

I would also recommend the courses

dharrigan16:02:16

they are good too

Adrian Imanuel16:02:09

ahhh okay, thank you so much for the help... step 9 is like last boss... i'll go levelling first

Tim Robinson17:02:29

Hi all. I have 2 namespaces implementing the same functions and I'm trying to dynamically select one based on a configuration entry. I don't really want to get into dependency injection frameworks, interfaces, protocols and all of that stuff unless I have to. I've figured out that this seems to work: (let [namespace (if some-config-flag 'namespace1 'namespace2)] (require [namespace :as implementation])) (implementation/do-something) Is this considered a sensible thing to do, or an abominable hack?

Alex Miller (Clojure team)17:02:53

closer to the latter :)

dpsutton17:02:13

can you just require both? (if (= option :a) (the-a-choice/launch-missles) (tests/launch-console-text-missiles))

Alex Miller (Clojure team)17:02:51

using requiring-resolve with a fully-qualified var would be better

dharrigan17:02:07

I have a use case that I do for this, and yup, Alex beat me to it, (requiring-resolve)

Alex Miller (Clojure team)17:02:11

assuming you need the dynaload

Tim Robinson17:02:08

I have about 20 functions in the implementing namespace, and it's something that is used very heavily in my app (the main persistence module). does requiring-resolve make sense for that or would it have a high runtime overhead?

Tim Robinson17:02:16

also I don't need to load it dynamically - both implementations will be present in the released package

Alex Miller (Clojure team)17:02:40

I mean, from what you describe, I'd probably use a protocol

Alex Miller (Clojure team)17:02:21

and just use config to choose what to instantiate

Alex Miller (Clojure team)17:02:26

doing the conditional require stuff makes it a lot harder for editors, tools, etc to understand what you're doing (and possibly other developers as well)

Tim Robinson18:02:27

Thanks - yes I did notice that clj-kondo didn't like what I was doing ๐Ÿ™‚ I was put off protocols thinking they were really intended just for java interop, but it looks to me like the best match

ej19:02:26

I know very little about web application security, but I'm trying to learn more. I know it is normal to protect certain parts of an application, and require the user to be authenticated in order to be authorized to see whatever is protected. But what if I also wanted to encrypt the information going into the system from the client, so that the database administrator or someone who gained entry to the database would not be able to see whatever was stored there. Is this feasible, or common? Can the information be decrypted fast enough for the system to respond like a normal web application, or would that process be very slow? Does anyone know of any good resources for doing things like this in Clojure, or just a general overview of web application security? So far I have found this: https://purelyfunctional.tv/article/clojure-web-security/

hiredman19:02:03

given a hypothetical database that stores encrypted data, it would need to decrypt it to do all the good things databases do (build indices, enforce constraints, etc). so the database will need to be able to decrypt it, which means if someone has the highest level access to the database (typical of a database admin) that means they can also decrypt it

hiredman19:02:53

so no, not feasible

hiredman19:02:39

if you aren't interested in a database, and just want a blob key value store, it is feasible. if you aren't familiar, and haven't work with something like a sql database before, you might equate a database with a key value store, but they definitely are not the same thing

ej20:02:59

Thanks, this has given me something to consider!

Tim Robinson07:02:40

encryption of the data across the network is normally handled by HTTPS or similar. for encryption of stored data you would normally use disk-level encryption (like windows bitlocker) which would be configured in the hosting center. you can't easily protect the data from a system administrator or DBA who knows that they are doing - you could encrypt the contents of individual fields or blobs yourself but then you'd need to store the encryption key somewhere, and the administrator would be able to find it (plus, as hiredman says, it makes it really inconvenient to use). If you want secure encryption of the data, I'd recommend putting the database engine on your own VM using disk encryption, to which only you know they password, then protecting access to the database so you know who's accessing it. Whatever you decide to do, the performance overhead of enccryption is unlikely to be significant

dharrigan19:02:02

in my experience, encryption all the way to the database level is rare

dharrigan19:02:30

however, saying that, I know that our AWS RDS instances do encrypt the storage underneath

dharrigan19:02:58

however, that's at the block level, not at the application level, so I can easily psql into a RDS instance and do normal selects etc...

dharrigan19:02:51

our internal API calls are all TLS (which makes debugging a bit difficult, unless you plug in a MITM on your work machine ๐Ÿ™‚ )

dharrigan19:02:05

however, this is probably better discussed in #off-topic ๐Ÿ™‚

๐Ÿ‘ 3