import { Cluster } from './cluster' ; import { CouchbaseError , GroupNotFoundError , UserNotFoundError } from './errors' ; import { HttpExecutor , HttpMethod , HttpServiceType } from './httpexecutor' ; import { RequestSpan } from './tracing' ; import { cbQsStringify , NodeCallback , PromiseHelper } from './utilities' ; category export class Origin { /**
     * The type of this origin.
     */ type : string ; /**
     * The name of this origin.
     */ name : string ; internal constructor ( data ) { this . type = data . type ; this . name = data . name ; } internal static _fromNsData ( data ) { return new Origin ( { type : data . type , name : data . name , } ) ; } } category export class Role { /**
     * The name of the role.
     */ name : string ; /**
     * The bucket this role applies to.
     */ bucket : string | undefined ; /**
     * The scope this role applies to.
     */ scope : string | undefined ; /**
     * The collection this role applies to.
     */ collection : string | undefined ; internal constructor ( data ) { this . name = data . name ; this . bucket = data . bucket ; this . scope = data . scope ; this . collection = data . collection ; } internal static _fromNsData ( data ) { return new Role ( { name : data . role , bucket : data . bucket_name , scope : data . scope_name , collection : data . collection_name , } ) ; } internal static _toNsStr ( role ) { if ( typeof role === 'string' ) { return role ; } if ( role . bucket && role . scope && role . collection ) { return `${ role . name }[${ role . bucket }:${ role . scope }:${ role . collection }]` ; } else if ( role . bucket && role . scope ) { return `${ role . name }[${ role . bucket }:${ role . scope }]` ; } else if ( role . bucket ) { return `${ role . name }[${ role . bucket }]` ; } else { return role . name ; } } } category export class RoleAndDescription extends Role { /**
     * The user-friendly display name for this role.
     */ displayName : string ; /**
     * The description of this role.
     */ description : string ; internal constructor ( data ) { super ( data ) ; this . displayName = data . displayName ; this . description = data . description ; } internal static _fromNsData ( data ) { return new RoleAndDescription ( { ... Role . _fromNsData ( data ) , displayName : data . name , description : data . description , } ) ; } } category export class RoleAndOrigin extends Role { /**
     * The origins for this role.
     */ origins : Origin [ ] ; internal constructor ( data ) { super ( data ) ; this . origins = data . origins ; } internal static _fromNsData ( data ) { let origins ; if ( data . origins ) { origins = data . origins . map ( ( originData ) => Origin . _fromNsData ( originData ) ) ; } else { origins = [ ] ; } return new RoleAndOrigin ( { ... Role . _fromNsData ( data ) , origins , } ) ; } } category export interface IUser { /**
     * The username of the user.
     */ username : string ; /**
     * The display name of the user.
     */ displayName ? : string ; /**
     * The groups associated with this user.
     */ groups ? : string [ ] ; /**
     * The roles associates with this user.
     */ roles ? : ( Role | string ) [ ] ; /**
     * The password for this user.
     */ password ? : string ; } category export class User implements IUser { /**
     * The username of the user.
     */ username : string ; /**
     * The display name of the user.
     */ displayName : string ; /**
     * The groups associated with this user.
     */ groups : string [ ] ; /**
     * The roles associates with this user.
     */ roles : Role [ ] ; /**
     * This is never populated in a result returned by the server.
     */ password : undefined ; internal constructor ( data ) { this . username = data . username ; this . displayName = data . displayName ; this . groups = data . groups ; this . roles = data . roles ; } internal static _fromNsData ( data ) { let roles ; if ( data . roles ) { roles = data . roles . filter ( ( roleData ) => { if ( ! roleData . origins || roleData . origins . length === 0 ) { return false ; } return ! ! roleData . origins . find ( ( originData ) => originData . type === 'user' ) ; } ) . map ( ( roleData ) => Role . _fromNsData ( roleData ) ) ; } else { roles = [ ] ; } return new User ( { username : data . id , displayName : data . name , groups : data . groups , roles : roles , password : undefined , } ) ; } internal static _toNsData ( user ) { let groups = undefined ; if ( user . groups && user . groups . length > 0 ) { groups = user . groups ; } let roles = undefined ; if ( user . roles && user . roles . length > 0 ) { roles = user . roles . map ( ( role ) => Role . _toNsStr ( role ) ) . join ( ',' ) ; } return { name : user . displayName , groups : groups , password : user . password , roles : roles , } ; } } category export class UserAndMetadata extends User { /**
     * The domain this user is part of.
     */ domain : string ; /**
     * The effective roles that are associated with this user.
     */ effectiveRoles : RoleAndOrigin [ ] ; /**
     * The last time the users password was changed.
     */ passwordChanged : Date ; /**
     * The external groups that this user is associated with.
     */ externalGroups : string [ ] ; /**
     * Same as  effectiveRoles , which already contains the roles
     * including their origins.
     *
     *  deprecated Use  effectiveRoles instead.
      get effectiveRolesAndOrigins ( ) : RoleAndOrigin [ ] { return this . effectiveRoles ; } internal constructor ( data ) { super ( data ) ; this . domain = data . domain ; this . effectiveRoles = data . effectiveRoles ; this . passwordChanged = data . passwordChanged ; this . externalGroups = data . externalGroups ; } internal static _fromNsData ( data ) { let effectiveRoles ; if ( data . roles ) { effectiveRoles = data . roles . map ( ( roleData ) => RoleAndOrigin . _fromNsData ( roleData ) ) ; } else { effectiveRoles = [ ] ; } return new UserAndMetadata ( { ... User . _fromNsData ( data ) , domain : data . domain , effectiveRoles : effectiveRoles , effectiveRolesAndOrigins : effectiveRoles , passwordChanged : new Date ( data . password_change_date ) , externalGroups : data . external_groups , } ) ; } } category export interface IGroup { /**
     * The name of the group.
     */ name : string ; /**
     * The description for the group.
     */ description ? : string ; /**
     * The roles which are associated with this group.
     */ roles ? : ( Role | string ) [ ] ; /**
     * The LDAP group that this group is associated with.
     */ ldapGroupReference ? : string ; } category export class Group { /**
     * The name of the group.
     */ name : string ; /**
     * The description for the group.
     */ description : string ; /**
     * The roles which are associated with this group.
     */ roles : Role [ ] ; /**
     * The LDAP group that this group is associated with.
     */ ldapGroupReference : string | undefined ; internal constructor ( data ) { this . name = data . name ; this . description = data . description ; this . roles = data . roles ; this . ldapGroupReference = data . ldapGroupReference ; } internal static _fromNsData ( data ) { let roles ; if ( data . roles ) { roles = data . roles . map ( ( roleData ) => Role . _fromNsData ( roleData ) ) ; } else { roles = [ ] ; } return new Group ( { name : data . id , description : data . description , roles : roles , ldapGroupReference : data . ldap_group_reference , } ) ; } internal static _toNsData ( group ) { let roles = undefined ; if ( group . roles && group . roles . length > 0 ) { roles = group . roles . map ( ( role ) => Role . _toNsStr ( role ) ) . join ( ',' ) ; } return { description : group . description , roles : roles , ldap_group_reference : group . ldapGroupReference , } ; } } category export interface GetUserOptions { /**
     * The domain to look in for the user.
     */ domainName ? : string ; /**
     * The parent tracing span that this operation will be part of.
     */ parentSpan ? : RequestSpan ; /**
     * The timeout for this operation, represented in milliseconds.
     */ timeout ? : number ; } category export interface GetAllUsersOptions { /**
     * The domain to look in for users.
     */ domainName ? : string ; /**
     * The parent tracing span that this operation will be part of.
     */ parentSpan ? : RequestSpan ; /**
     * The timeout for this operation, represented in milliseconds.
     */ timeout ? : number ; } category export interface UpsertUserOptions { /**
     * The domain to upsert the user within.
     */ domainName ? : string ; /**
     * The parent tracing span that this operation will be part of.
     */ parentSpan ? : RequestSpan ; /**
     * The timeout for this operation, represented in milliseconds.
     */ timeout ? : number ; } category export interface DropUserOptions { /**
     * The domain to drop the user from.
     */ domainName ? : string ; /**
     * The parent tracing span that this operation will be part of.
     */ parentSpan ? : RequestSpan ; /**
     * The timeout for this operation, represented in milliseconds.
     */ timeout ? : number ; } category export interface GetRolesOptions { /**
     * The parent tracing span that this operation will be part of.
     */ parentSpan ? : RequestSpan ; /**
     * The timeout for this operation, represented in milliseconds.
     */ timeout ? : number ; } category export interface GetGroupOptions { /**
     * The parent tracing span that this operation will be part of.
     */ parentSpan ? : RequestSpan ; /**
     * The timeout for this operation, represented in milliseconds.
     */ timeout ? : number ; } category export interface GetAllGroupsOptions { /**
     * The parent tracing span that this operation will be part of.
     */ parentSpan ? : RequestSpan ; /**
     * The timeout for this operation, represented in milliseconds.
     */ timeout ? : number ; } category export interface UpsertGroupOptions { /**
     * The parent tracing span that this operation will be part of.
     */ parentSpan ? : RequestSpan ; /**
     * The timeout for this operation, represented in milliseconds.
     */ timeout ? : number ; } category export interface DropGroupOptions { /**
     * The parent tracing span that this operation will be part of.
     */ parentSpan ? : RequestSpan ; /**
     * The timeout for this operation, represented in milliseconds.
     */ timeout ? : number ; } category export class UserManager { private _cluster : Cluster ; internal constructor ( cluster ) { this . _cluster = cluster ; } private get _http ( ) { return new HttpExecutor ( this . _cluster . _getClusterConn ( ) ) ; } param username param options param callback async getUser ( username , options ? , callback ? ) { if ( options instanceof Function ) { callback = arguments [ 1 ] ; options = undefined ; } if ( ! options ) { options = { } ; } const domainName = options . domainName || 'local' ; const parentSpan = options . parentSpan ; const timeout = options . timeout ; return PromiseHelper . wrapAsync ( async ( ) => { const res = await this . _http . request ( { type : HttpServiceType . Management , method : HttpMethod . Get , path : `/settings/rbac/users/${ domainName }/${ username }` , parentSpan : parentSpan , timeout : timeout , } ) ; if ( res . statusCode !== 200 ) { const errCtx = HttpExecutor . errorContextFromResponse ( res ) ; if ( res . statusCode === 404 ) { throw new UserNotFoundError ( undefined , errCtx ) ; } throw new CouchbaseError ( 'failed to get the user' , undefined , errCtx ) ; } const userData = JSON . parse ( res . body . toString ( ) ) ; return UserAndMetadata . _fromNsData ( userData ) ; } , callback ) ; } param options param callback async getAllUsers ( options ? , callback ? ) { if ( options instanceof Function ) { callback = arguments [ 0 ] ; options = undefined ; } if ( ! options ) { options = { } ; } const domainName = options . domainName || 'local' ; const parentSpan = options . parentSpan ; const timeout = options . timeout ; return PromiseHelper . wrapAsync ( async ( ) => { const res = await this . _http . request ( { type : HttpServiceType . Management , method : HttpMethod . Get , path : `/settings/rbac/users/${ domainName }` , parentSpan : parentSpan , timeout : timeout , } ) ; if ( res . statusCode !== 200 ) { const errCtx = HttpExecutor . errorContextFromResponse ( res ) ; throw new CouchbaseError ( 'failed to get users' , undefined , errCtx ) ; } const usersData = JSON . parse ( res . body . toString ( ) ) ; const users = usersData . map ( ( userData ) => UserAndMetadata . _fromNsData ( userData ) ) ; return users ; } , callback ) ; } param user param options param callback async upsertUser ( user , options ? , callback ? ) { if ( options instanceof Function ) { callback = arguments [ 1 ] ; options = undefined ; } if ( ! options ) { options = { } ; } const domainName = options . domainName || 'local' ; const parentSpan = options . parentSpan ; const timeout = options . timeout ; return PromiseHelper . wrapAsync ( async ( ) => { const userData = User . _toNsData ( user ) ; const res = await this . _http . request ( { type : HttpServiceType . Management , method : HttpMethod . Put , path : `/settings/rbac/users/${ domainName }/${ user . username }` , contentType : 'application/x-www-form-urlencoded' , body : cbQsStringify ( userData ) , parentSpan : parentSpan , timeout : timeout , } ) ; if ( res . statusCode !== 200 ) { const errCtx = HttpExecutor . errorContextFromResponse ( res ) ; throw new CouchbaseError ( 'failed to upsert user' , undefined , errCtx ) ; } } , callback ) ; } param username param options param callback async dropUser ( username , options ? , callback ? ) { if ( options instanceof Function ) { callback = arguments [ 1 ] ; options = undefined ; } if ( ! options ) { options = { } ; } const domainName = options . domainName || 'local' ; const parentSpan = options . parentSpan ; const timeout = options . timeout ; return PromiseHelper . wrapAsync ( async ( ) => { const res = await this . _http . request ( { type : HttpServiceType . Management , method : HttpMethod . Delete , path : `/settings/rbac/users/${ domainName }/${ username }` , parentSpan : parentSpan , timeout : timeout , } ) ; if ( res . statusCode !== 200 ) { const errCtx = HttpExecutor . errorContextFromResponse ( res ) ; if ( res . statusCode === 404 ) { throw new UserNotFoundError ( undefined , errCtx ) ; } throw new CouchbaseError ( 'failed to drop the user' , undefined , errCtx ) ; } } , callback ) ; } param options param callback async getRoles ( options ? , callback ? ) { if ( options instanceof Function ) { callback = arguments [ 0 ] ; options = undefined ; } if ( ! options ) { options = { } ; } const parentSpan = options . parentSpan ; const timeout = options . timeout ; return PromiseHelper . wrapAsync ( async ( ) => { const res = await this . _http . request ( { type : HttpServiceType . Management , method : HttpMethod . Get , path : `/settings/rbac/roles` , parentSpan : parentSpan , timeout : timeout , } ) ; if ( res . statusCode !== 200 ) { const errCtx = HttpExecutor . errorContextFromResponse ( res ) ; throw new CouchbaseError ( 'failed to get roles' , undefined , errCtx ) ; } const rolesData = JSON . parse ( res . body . toString ( ) ) ; const roles = rolesData . map ( ( roleData ) => RoleAndDescription . _fromNsData ( roleData ) ) ; return roles ; } , callback ) ; } param groupName param options param callback async getGroup ( groupName , options ? , callback ? ) { if ( options instanceof Function ) { callback = arguments [ 1 ] ; options = undefined ; } if ( ! options ) { options = { } ; } const parentSpan = options . parentSpan ; const timeout = options . timeout ; return PromiseHelper . wrapAsync ( async ( ) => { const res = await this . _http . request ( { type : HttpServiceType . Management , method : HttpMethod . Get , path : `/settings/rbac/groups/${ groupName }` , parentSpan : parentSpan , timeout : timeout , } ) ; if ( res . statusCode !== 200 ) { const errCtx = HttpExecutor . errorContextFromResponse ( res ) ; if ( res . statusCode === 404 ) { throw new GroupNotFoundError ( undefined , errCtx ) ; } throw new CouchbaseError ( 'failed to get the group' , undefined , errCtx ) ; } const groupData = JSON . parse ( res . body . toString ( ) ) ; return Group . _fromNsData ( groupData ) ; } , callback ) ; } param options param callback async getAllGroups ( options ? , callback ? ) { if ( options instanceof Function ) { callback = arguments [ 0 ] ; options = undefined ; } if ( ! options ) { options = { } ; } const parentSpan = options . parentSpan ; const timeout = options . timeout ; return PromiseHelper . wrapAsync ( async ( ) => { const res = await this . _http . request ( { type : HttpServiceType . Management , method : HttpMethod . Get , path : `/settings/rbac/groups` , parentSpan : parentSpan , timeout : timeout , } ) ; if ( res . statusCode !== 200 ) { const errCtx = HttpExecutor . errorContextFromResponse ( res ) ; throw new CouchbaseError ( 'failed to get groups' , undefined , errCtx ) ; } const groupsData = JSON . parse ( res . body . toString ( ) ) ; const groups = groupsData . map ( ( groupData ) => Group . _fromNsData ( groupData ) ) ; return groups ; } , callback ) ; } param group param options param callback async upsertGroup ( group , options ? , callback ? ) { if ( options instanceof Function ) { callback = arguments [ 1 ] ; options = undefined ; } if ( ! options ) { options = { } ; } const parentSpan = options . parentSpan ; const timeout = options . timeout ; return PromiseHelper . wrapAsync ( async ( ) => { const groupData = Group . _toNsData ( group ) ; const res = await this . _http . request ( { type : HttpServiceType . Management , method : HttpMethod . Put , path : `/settings/rbac/groups/${ group . name }` , contentType : 'application/x-www-form-urlencoded' , body : cbQsStringify ( groupData ) , parentSpan : parentSpan , timeout : timeout , } ) ; if ( res . statusCode !== 200 ) { const errCtx = HttpExecutor . errorContextFromResponse ( res ) ; throw new CouchbaseError ( 'failed to upsert group' , undefined , errCtx ) ; } } , callback ) ; } param groupName param options param callback async dropGroup ( groupName , options ? , callback ? ) { if ( options instanceof Function ) { callback = arguments [ 1 ] ; options = undefined ; } if ( ! options ) { options = { } ; } const parentSpan = options . parentSpan ; const timeout = options . timeout ; return PromiseHelper . wrapAsync ( async ( ) => { const res = await this . _http . request ( { type : HttpServiceType . Management , method : HttpMethod . Delete , path : `/settings/rbac/groups/${ groupName }` , parentSpan : parentSpan , timeout : timeout , } ) ; if ( res . statusCode !== 200 ) { const errCtx = HttpExecutor . errorContextFromResponse ( res ) ; if ( res . statusCode === 404 ) { throw new GroupNotFoundError ( undefined , errCtx ) ; } throw new CouchbaseError ( 'failed to drop the group' , undefined , errCtx ) ; } } , callback ) ; } }