Skip to content

Commit

Permalink
refactor getObjectLockConfig and setObjectLockConfig to ts
Browse files Browse the repository at this point in the history
  • Loading branch information
prakashsvmx committed Aug 10, 2023
1 parent 83fb55e commit 7f41e54
Show file tree
Hide file tree
Showing 11 changed files with 190 additions and 186 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ The full API Reference is available here.
- [set-bucket-lifecycle.js](https://github.com/minio/minio-js/blob/master/examples/set-bucket-lifecycle.js)
- [get-bucket-lifecycle.js](https://github.com/minio/minio-js/blob/master/examples/get-bucket-lifecycle.js)
- [remove-bucket-lifecycle.js](https://github.com/minio/minio-js/blob/master/examples/remove-bucket-lifecycle.js)
- [get-object-lock-config.js](https://github.com/minio/minio-js/blob/master/examples/get-object-lock-config.js)
- [set-object-lock-config.js](https://github.com/minio/minio-js/blob/master/examples/set-object-lock-config.js)
- [get-object-lock-config.mjs](https://github.com/minio/minio-js/blob/master/examples/get-object-lock-config.mjs)
- [set-object-lock-config.mjs](https://github.com/minio/minio-js/blob/master/examples/set-object-lock-config.mjs)
- [set-bucket-replication.mjs](https://github.com/minio/minio-js/blob/master/examples/set-bucket-replication.mjs)
- [get-bucket-replication.mjs](https://github.com/minio/minio-js/blob/master/examples/get-bucket-replication.mjs)
- [remove-bucket-replication.mjs](https://github.com/minio/minio-js/blob/master/examples/remove-bucket-replication.mjs)
Expand Down
37 changes: 10 additions & 27 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -765,33 +765,22 @@ Set Object lock config on a Bucket

**Parameters**

| Param | Type | Description |
| --------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `bucketName` | _string_ | Name of the bucket. |
| `lockConfig` | _object_ | Lock Configuration can be either `{}` to reset or object with all of the following key/value pairs: `{mode: ["COMPLIANCE"/'GOVERNANCE'], unit: ["Days"/"Years"], validity: <a-valid-number-for-unit>}` |
| `callback(err)` | _function_ | Callback is called with `err` in case of error. |
| Param | Type | Description |
| ------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `bucketName` | _string_ | Name of the bucket. |
| `lockConfig` | _object_ | Lock Configuration can be either `{}` to reset or object with all of the following key/value pairs: `{mode: ["COMPLIANCE"/'GOVERNANCE'], unit: ["Days"/"Years"], validity: <a-valid-number-for-unit>}` |

**Example 1**

```js
s3Client.setObjectLockConfig('my-bucketname', { mode: 'COMPLIANCE', unit: 'Days', validity: 10 }, function (err) {
if (err) {
return console.log(err)
}
console.log('Success')
})
await minioClient.setObjectLockConfig('my-bucketname', { mode: 'COMPLIANCE', unit: 'Days', validity: 10 })
```

**Example 2**
To reset/remove object lock config on a bucket.

```js
s3Client.setObjectLockConfig('my-bucketname', {}, function (err) {
if (err) {
return console.log(err)
}
console.log('Success')
})
await s3Client.setObjectLockConfig('my-bucketname', {})
```

<a name="getObjectLockConfig"></a>
Expand All @@ -802,21 +791,15 @@ Get Lock config on a Bucket

**Parameters**

| Param | Type | Description |
| --------------------------- | ---------- | ----------------------------------------------------------------------------------------- |
| `bucketName` | _string_ | Name of the bucket. |
| `callback(err, lockConfig)` | _function_ | Callback is called with `err` in case of error. else it is called with lock configuration |
| Param | Type | Description |
| ------------ | -------- | ------------------- |
| `bucketName` | _string_ | Name of the bucket. |

**Example **
Get object lock configuration on a Bucket

```js
s3Client.getObjectLockConfig('my-bucketname', function (err, lockConfig) {
if (err) {
return console.log(err)
}
console.log(lockConfig)
})
await minioClient.getObjectLockConfig('my-bucketname')
```

<a name="setBucketEncryption"></a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
// dummy values, please replace them with original values.

var Minio = require('minio')
import * as Minio from 'minio'

var s3Client = new Minio.Client({
const s3Client = new Minio.Client({
endPoint: 's3.amazonaws.com',
accessKey: 'YOUR-ACCESSKEYID',
secretKey: 'YOUR-SECRETACCESSKEY',
})

s3Client.getObjectLockConfig('my-bucketname', function (err, lockConfig) {
if (err) {
return console.log(err)
}
console.log(lockConfig)
})
try {
const lockConfig = await s3Client.getObjectLockConfig('my-bucketname')
console.log('Success', lockConfig)
} catch (err) {
console.log('Error ', err.message)
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,27 @@
// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are
// dummy values, please replace them with original values.

var Minio = require('minio')
import * as Minio from 'minio'

var s3Client = new Minio.Client({
const s3Client = new Minio.Client({
endPoint: 's3.amazonaws.com',
accessKey: 'YOUR-ACCESSKEYID',
secretKey: 'YOUR-SECRETACCESSKEY',
})

//Set Object lock on a bucket
s3Client.setObjectLockConfig('my-bucketname', { mode: 'COMPLIANCE', unit: 'Days', validity: 10 }, function (err) {
if (err) {
return console.log(err)
}
try {
await s3Client.setObjectLockConfig('my-bucketname', { mode: 'GOVERNANCE', unit: 'Days', validity: 20 })
console.log('Success')
})
} catch (err) {
console.log('Error::', err.message)
}

//To reset/remove object lock config.
s3Client.setObjectLockConfig('my-bucketname', {}, function (err) {
if (err) {
return console.log(err)
}
//Set Object lock on a bucket
try {
await s3Client.setObjectLockConfig('my-bucketname', {})
console.log('Success')
})
} catch (err) {
console.log('Error::', err.message)
}
90 changes: 89 additions & 1 deletion src/internal/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import xml2js from 'xml2js'

import { CredentialProvider } from '../CredentialProvider.ts'
import * as errors from '../errors.ts'
import { DEFAULT_REGION } from '../helpers.ts'
import { DEFAULT_REGION, RETENTION_MODES, RETENTION_VALIDITY_UNITS } from '../helpers.ts'
import { signV4 } from '../signing.ts'
import { Extensions } from './extensions.ts'
import {
Expand Down Expand Up @@ -44,6 +44,8 @@ import type {
BucketItemFromList,
BucketItemStat,
IRequest,
ObjectLockConfigParam,
ObjectLockInfo,
ReplicationConfig,
ReplicationConfigOpts,
RequestHeaders,
Expand Down Expand Up @@ -1031,4 +1033,90 @@ export class TypedClient {
const xmlResult = await readAsString(httpRes)
return xmlParsers.parseReplicationConfig(xmlResult)
}

getObjectLockConfig(bucketName: string, callback: ResultCallback<ObjectLockInfo>): void
// @ts-ignore
async getObjectLockConfig(bucketName: string): Promise<ObjectLockInfo>
async getObjectLockConfig(bucketName: string) {
if (!isValidBucketName(bucketName)) {
throw new errors.InvalidBucketNameError('Invalid bucket name: ' + bucketName)
}
const method = 'GET'
const query = 'object-lock'

const httpRes = await this.makeRequestAsync({ method, bucketName, query })
const xmlResult = await readAsString(httpRes)
return xmlParsers.parseObjectLockConfig(xmlResult)
}

setObjectLockConfig(
bucketName: string,
lockConfigOpts: Omit<ObjectLockInfo, 'objectLockEnabled'>,
callback: NoResultCallback,
): void
// @ts-ignore
async setObjectLockConfig(
bucketName: string,
lockConfigOpts: Omit<ObjectLockInfo, 'objectLockEnabled'>,
): Promise<void>
async setObjectLockConfig(bucketName: string, lockConfigOpts: Omit<ObjectLockInfo, 'objectLockEnabled'>) {
const retentionModes = [RETENTION_MODES.COMPLIANCE, RETENTION_MODES.GOVERNANCE]
const validUnits = [RETENTION_VALIDITY_UNITS.DAYS, RETENTION_VALIDITY_UNITS.YEARS]

if (!isValidBucketName(bucketName)) {
throw new errors.InvalidBucketNameError('Invalid bucket name: ' + bucketName)
}

if (lockConfigOpts.mode && !retentionModes.includes(lockConfigOpts.mode)) {
throw new TypeError(`lockConfigOpts.mode should be one of ${retentionModes}`)
}
if (lockConfigOpts.unit && !validUnits.includes(lockConfigOpts.unit)) {
throw new TypeError(`lockConfigOpts.unit should be one of ${validUnits}`)
}
if (lockConfigOpts.validity && !isNumber(lockConfigOpts.validity)) {
throw new TypeError(`lockConfigOpts.validity should be a number`)
}

const method = 'PUT'
const query = 'object-lock'

const config: ObjectLockConfigParam = {
ObjectLockEnabled: 'Enabled',
}
const configKeys = Object.keys(lockConfigOpts)

const isAllKeysSet = ['unit', 'mode', 'validity'].every((lck) => configKeys.includes(lck))
// Check if keys are present and all keys are present.
if (configKeys.length > 0) {
if (!isAllKeysSet) {
throw new TypeError(
`lockConfigOpts.mode,lockConfigOpts.unit,lockConfigOpts.validity all the properties should be specified.`,
)
} else {
config.Rule = {
DefaultRetention: {},
}
if (lockConfigOpts.mode) {
config.Rule.DefaultRetention.Mode = lockConfigOpts.mode
}
if (lockConfigOpts.unit === RETENTION_VALIDITY_UNITS.DAYS) {
config.Rule.DefaultRetention.Days = lockConfigOpts.validity
} else if (lockConfigOpts.unit === RETENTION_VALIDITY_UNITS.YEARS) {
config.Rule.DefaultRetention.Years = lockConfigOpts.validity
}
}
}

const builder = new xml2js.Builder({
rootName: 'ObjectLockConfiguration',
renderOpts: { pretty: false },
headless: true,
})
const payload = builder.buildObject(config)

const headers: RequestHeaders = {}
headers['Content-MD5'] = toMd5(payload)

await this.makeRequestAsyncOmit({ method, bucketName, query, headers }, payload)
}
}
29 changes: 28 additions & 1 deletion src/internal/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type Encryption =
KMSMasterKeyID?: string
}

export type EnabledOrDisabledStatus = 'Enabled' | 'Disabled'
export enum ENCRYPTION_TYPES {
/**
* SSEC represents server-side-encryption with customer provided keys
Expand Down Expand Up @@ -129,7 +130,7 @@ export type StatObjectOpts = {

/* Replication Config types */
export type ReplicationRuleStatus = {
Status: 'Enabled' | 'Disabled'
Status: EnabledOrDisabledStatus
}

export type Tag = {
Expand Down Expand Up @@ -187,3 +188,29 @@ export type ReplicationConfig = {
/* Replication Config types */

export type ResultCallback<T> = (error: Error | null, result: T) => void

export type EmptyObject = Record<string, never>

export type ObjectLockInfo =
| {
objectLockEnabled: EnabledOrDisabledStatus
mode: RETENTION_MODES
unit: RETENTION_VALIDITY_UNITS
validity: number
}
| EmptyObject

export type ObjectLockConfigParam = {
ObjectLockEnabled?: 'Enabled' | undefined
Rule?:
| {
DefaultRetention:
| {
Mode: RETENTION_MODES
Days: number
Years: number
}
| EmptyObject
}
| EmptyObject
}
34 changes: 33 additions & 1 deletion src/internal/xml-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { XMLParser } from 'fast-xml-parser'
import * as errors from '../errors.ts'
import { parseXml, sanitizeETag, sanitizeObjectKey, toArray } from './helper.ts'
import { readAsString } from './response.ts'
import type { BucketItemFromList, BucketItemWithMetadata, ReplicationConfig } from './type.ts'
import type { BucketItemFromList, BucketItemWithMetadata, ObjectLockInfo, ReplicationConfig } from './type.ts'
import { RETENTION_VALIDITY_UNITS } from './type.ts'

// parse XML response for bucket region
export function parseBucketRegion(xml: string): string {
Expand Down Expand Up @@ -241,3 +242,34 @@ export function parseReplicationConfig(xml: string): ReplicationConfig {
},
}
}

export function parseObjectLockConfig(xml: string): ObjectLockInfo {
const xmlObj = parseXml(xml)
let lockConfigResult = {} as ObjectLockInfo
if (xmlObj.ObjectLockConfiguration) {
lockConfigResult = {
objectLockEnabled: xmlObj.ObjectLockConfiguration.ObjectLockEnabled,
} as ObjectLockInfo
let retentionResp
if (
xmlObj.ObjectLockConfiguration &&
xmlObj.ObjectLockConfiguration.Rule &&
xmlObj.ObjectLockConfiguration.Rule.DefaultRetention
) {
retentionResp = xmlObj.ObjectLockConfiguration.Rule.DefaultRetention || {}
lockConfigResult.mode = retentionResp.Mode
}
if (retentionResp) {
const isUnitYears = retentionResp.Years
if (isUnitYears) {
lockConfigResult.validity = isUnitYears
lockConfigResult.unit = RETENTION_VALIDITY_UNITS.YEARS
} else {
lockConfigResult.validity = retentionResp.Days
lockConfigResult.unit = RETENTION_VALIDITY_UNITS.DAYS
}
}
}

return lockConfigResult
}
Loading

0 comments on commit 7f41e54

Please sign in to comment.