---
title: "High level six functions"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{High level six functions}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---



High level `sixtyfour` functions - or "magical" methods - or we can call them "six methods" after the package name `sixtyfour` - are higher level functions to make your life easier.

It can perhaps best be understood by way of an example.

The function `aws_user_create()` creates a new user. However, there's some basic housekeeping that needs to be done for a new user to be truly useable. First, the just created user can't get information on herself. Second, the user has no credentials by default for accessing AWS programatically.

To create a smoother user experience `six_user_create()` creates a new user, including a) creating the appropriate policies if they don't exist yet, b) attaching the policies to the created user, and c) creating an AWS Access Key for the user (and copy an email template to your clipboard with the details the new user needs).

## Load sixtyfour


``` r
library(sixtyfour)
library(fs)
```

## All the magical methods

Here are all the magical methods:


```
#>  - six_admin_setup
#>  - six_bucket_add_user
#>  - six_bucket_change_user
#>  - six_bucket_delete
#>  - six_bucket_permissions
#>  - six_bucket_remove_user
#>  - six_bucket_upload
#>  - six_file_upload
#>  - six_group_delete
#>  - six_user_create
#>  - six_user_creds
#>  - six_user_delete
```

## Notes about magical methods

All of these methods have a `force` parameter that accepts `TRUE` or `FALSE`. The default is `FALSE` in which case you are given a prompt in your R session asking you to confirm that you really do want to create a bucket of a particular name. Sometimes you supply the bucket name, while other magic methods figure out a bucket name from an S3 file path (e.g., `s3://bucketname/some/file.csv`). Because we want this vignette to compile without human interaction, we're using `force=TRUE`, so you won't see the prompots that you'll see when you use these functions interactively.



## S3 magical methods

Make a random bucket name


``` r
bucket1 <- random_bucket()
```

### Upload to a bucket

A file


``` r
demo_rds_file <- file.path(system.file(), "Meta/demo.rds")
```

A directory with files


``` r
tdir <- path(path_temp(), "mytmp")
dir_create(tdir)
invisible(purrr::map(letters[1:13], \(l) file_create(path(tdir, l))))
dir_tree(tdir)
#> /var/folders/qt/fzq1m_bj2yb_7b2jz57s9q7c0000gp/T/RtmpILqIPZ/mytmp
#> ├── a
#> ├── b
#> ├── c
#> ├── d
#> ├── e
#> ├── f
#> ├── g
#> ├── h
#> ├── i
#> ├── j
#> ├── k
#> ├── l
#> └── m
```

Upload both the file and the directory of files to `bucket1`: bucket-yiqxfbrczesdmuwo


``` r
six_bucket_upload(path = c(demo_rds_file, tdir), remote = bucket1)
```

```
#>  [1] "s3://bucket-yiqxfbrczesdmuwo/demo.rds"
#>  [2] "s3://bucket-yiqxfbrczesdmuwo/mytmp/a"
#>  [3] "s3://bucket-yiqxfbrczesdmuwo/mytmp/b"
#>  [4] "s3://bucket-yiqxfbrczesdmuwo/mytmp/c"
#>  [5] "s3://bucket-yiqxfbrczesdmuwo/mytmp/d"
#>  [6] "s3://bucket-yiqxfbrczesdmuwo/mytmp/e"
#>  [7] "s3://bucket-yiqxfbrczesdmuwo/mytmp/f"
#>  [8] "s3://bucket-yiqxfbrczesdmuwo/mytmp/g"
#>  [9] "s3://bucket-yiqxfbrczesdmuwo/mytmp/h"
#> [10] "s3://bucket-yiqxfbrczesdmuwo/mytmp/i"
#> [11] "s3://bucket-yiqxfbrczesdmuwo/mytmp/j"
#> [12] "s3://bucket-yiqxfbrczesdmuwo/mytmp/k"
#> [13] "s3://bucket-yiqxfbrczesdmuwo/mytmp/l"
#> [14] "s3://bucket-yiqxfbrczesdmuwo/mytmp/m"
```


### File upload

Now that we have a bucket, we can upload a file to the existing bucket with `six_file_upload`.


``` r
links_file <- file.path(system.file(), "Meta/links.rds")
six_file_upload(links_file, bucket1)
```

```
#> [1] "s3://bucket-yiqxfbrczesdmuwo/links.rds"
```


### Add a user to a bucket

Now that we created a bucket, and added some files, let's add a user to this bucket.

Create a random user name and create the user in AWS.


``` r
user1 <- random_user()
aws_user_create(user1)
#> # A tibble: 1 × 6
#>   UserName         UserId    Path  Arn   CreateDate          PasswordLastUsed
#>   <chr>            <chr>     <chr> <chr> <dttm>              <dttm>
#> 1 CandiedMeasureme AIDA22PL… /     ***** 2025-03-12 22:41:35 NA
```

Now add the user to the bucket so they can access it with the permissions we're assigning to them.



``` r
six_bucket_add_user(
  bucket = bucket1,
  username = user1,
  permissions = "read"
)
#> ✔ CandiedMeasureme now has read access to bucket bucket-yiqxfbrczesdmuwo
```

### Get all user permissions for a bucket

You'll often want to get a summary of the permissions on a given bucket. `six_bucket_permissions()` gives you that summary.


``` r
six_bucket_permissions(bucket1)
```

```
#> # A tibble: 1 × 4
#>   user             permissions policy_read                          policy_admin
#>   <chr>            <chr>       <chr>                                <chr>
#> 1 CandiedMeasureme read        S3ReadOnlyAccessBucketyiqxfbrczesdm… <NA>
```



### Change a user's permissions for a bucket

After adding a user to a bucket you may want to change their permissions - for example, if they had read access only but need admin, or vice versa. The magic function `six_bucket_change_user()` is meant for these kinds of use cases.

First, let's see what permissions `user1` has right now using the previous magic function we learned about:


``` r
six_bucket_permissions(bucket1)
```

```
#> # A tibble: 1 × 4
#>   user             permissions policy_read                          policy_admin
#>   <chr>            <chr>       <chr>                                <chr>
#> 1 CandiedMeasureme read        S3ReadOnlyAccessBucketyiqxfbrczesdm… <NA>
```

`user1` has read access, but we'd like to change that to write access:


``` r
six_bucket_change_user(
  bucket = bucket1,
  username = user1,
  permissions = "write"
)
#> ✔ CandiedMeasureme now has write access to bucket bucket-yiqxfbrczesdmuwo
```

`six_bucket_change_user()` returns inivisibly. Let's check the permissions for this user and bucket after this change:


``` r
six_bucket_permissions(bucket1)
```

```
#> # A tibble: 1 × 4
#>   user             permissions policy_write                       policy_admin
#>   <chr>            <chr>       <chr>                              <chr>
#> 1 CandiedMeasureme write       S3FullAccessBucketyiqxfbrczesdmuwo <NA>
```


### Remove a user from a bucket

You may at some point want to remove a user from a bucket that you've previously added. The magic function `six_bucket_remove_user()` helps you do just that.


``` r
six_bucket_remove_user(bucket1, user1)
#> ✔ CandiedMeasureme access to bucket-yiqxfbrczesdmuwo has been removed
```


### Delete a bucket

Finally, there's a magic function to make deleting a bucket easier. For good reason AWS doesn't allow a bucket to be deleted if it has obejcts. `six_bucket_delete()` helps you delete a bucket by cleaning out any objects with prompts. Though, you can force deletion as well.

First, create a bucket with some objects


``` r
bucket2 <- random_bucket()
aws_bucket_create(bucket2)
#> [1] "http://bucket-vgbwzxqafyoudnpc.s3.amazonaws.com/"
demo_rds_file <- file.path(system.file(), "Meta/demo.rds")
links_file <- file.path(system.file(), "Meta/links.rds")
aws_file_upload(
  c(demo_rds_file, links_file),
  s3_path(bucket2, c(basename(demo_rds_file), basename(links_file)))
)
#> [1] "s3://bucket-vgbwzxqafyoudnpc/demo.rds"
#> [2] "s3://bucket-vgbwzxqafyoudnpc/links.rds"
aws_bucket_list_objects(bucket2)
#> # A tibble: 2 × 8
#>   bucket         key   uri     size type  etag  lastmodified        storageclass
#>   <glue>         <chr> <glu> <fs::> <chr> <chr> <dttm>              <chr>
#> 1 bucket-vgbwzx… demo… s3:/…    256 file  "\"7… 2025-03-12 22:42:11 STANDARD
#> 2 bucket-vgbwzx… link… s3:/…  13.2K file  "\"0… 2025-03-12 22:42:11 STANDARD
```

Then delete the bucket


``` r
six_bucket_delete(bucket2)
```

```
#> ℹ deleting bucket bucket-vgbwzxqafyoudnpc
```

## IAM magical methods

Right now we have magical methods for IAM related to managing user groups (`six_admin_setup()`) and users (`six_user*()` functions).

### Admin setup

`six_admin_setup()` is a helper function for administrators of AWS accounts. It creates an admin and a user group with the idea that many administrators are going to want two basic groups of people associated with their AWS account: users and admins, where users only have read and maybe write access, while admins have additional permissions in addition to reading and writing. To these two groups (users and admins) this function adds a set of five policies each that give appropriate levels of permissions for each group. You can of course change the policies, but we think these are a good default set of policies.



``` r
six_admin_setup(users_group = "myusers", admin_group = "myadmin")
#> ℹ whoami: *****
#> ℹ
#> ℹ myusers group created - add users to this group that do not require admin permissions
#> ℹ Added policies to the myusers group: AmazonRDSReadOnlyAccess, AmazonRedshiftReadOnlyAccess, AmazonS3ReadOnlyAccess,
#> AWSBillingReadOnlyAccess, and IAMReadOnlyAccess
#> ℹ
#> ℹ myadmin group created - add users to this group that require admin permissions
#> ℹ Added policies to the myadmin group: AdministratorAccess, Billing, CostOptimizationHubAdminAccess, AWSBillingReadOnlyAccess, and
#> AWSCostAndUsageReportAutomationPolicy
#> ℹ
#> ℹ Done!
```



### User management



There's currently 3 magic functions for managing users:


```
#>  - six_user_create
#>  - six_user_creds
#>  - six_user_delete
```

`six_user_creds()` is a helper function to create credentials for an existing users - credentials being an AWS secret access key and corresponding access key ID. That function is used inside of `six_user_create()` to create credentials for a new user. Let's see how it works. `six_user_create()` will:

- Create a new user
- Add a new `UserInfo` policy to your account if doesn't exist yet
- Attach the `UserInfo` policy to the newly created user
- Grants an access key to the new user, copying an email template to your clipboard



``` r
user2 <- random_user()
six_user_create(user2)
```

```
#> ℹ Added policy UserInfo to VanillaFries
#> ✔ Key pair created for VanillaFries
#> ℹ AccessKeyId: *****
#> ℹ SecretAccessKey: *****
```

It can't be shown here, but an email template is copied to your clipboard with the new credentials so you can give them to the person that is associated with the new user, whether that be via email, chat, or other means.

You can also delete a user. If a user has any attached policies or access keys the user can not be deleted. `six_user_delete()` does those tasks for you then deletes the user:


``` r
six_user_delete(user2)
#> ℹ Policy UserInfo detached
#> ✔ Access Key ID ***** deleted
#> ℹ VanillaFries deleted
```
