• Stars
    star
    141
  • Rank 259,971 (Top 6 %)
  • Language
    Go
  • License
    MIT License
  • Created almost 6 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

⚡️ SharePoint SDK for Go

Gosip - SharePoint SDK for Go (Golang)

Authentication, HTTP client & fluent API wrapper

Build Status Go Report Card GoDoc License codecov FOSSA Status Mentioned in Awesome Go

Gosip

Main features

  • Unattended authentication using different strategies.
  • Fluent API syntax for SharePoint object model.
  • Simplified API consumption (REST, CSOM, SOAP).
  • SharePoint-aware embedded features (retries, header presets, error handling).

Supported SharePoint versions

  • SharePoint Online (SPO)
  • On-Premises (2019/2016/2013)

Supported auth strategies

  • SharePoint Online:

    • Azure Certificate (App Only) 🔗
    • Azure Username/Password 🔗
    • Azure Device Flow 🔗
    • SAML based with user credentials
    • Add-In only permissions
    • ADFS user credentials (automatically detects in SAML strategy)
    • On-Demand auth 🔗
  • SharePoint On-Premises 2019/2016/2013:

    • User credentials (NTLM)
    • ADFS user credentials (ADFS, WAP -> Basic/NTLM, WAP -> ADFS)
    • Behind a reverse proxy (Forefront TMG, WAP -> Basic/NTLM, WAP -> ADFS)
    • Form-based authentication (FBA)
    • On-Demand auth 🔗

Installation

go get github.com/koltyakov/gosip

Usage insights

1. Understand SharePoint environment type and authentication strategy.

Let's assume it's SharePoint Online and Add-In Only permissions. Then strategy "github.com/koltyakov/gosip/auth/addin" subpackage should be used.

package main

import (
	"github.com/koltyakov/gosip"
	"github.com/koltyakov/gosip/api"
	strategy "github.com/koltyakov/gosip/auth/addin"
)

2. Initiate an authentication object.

auth := &strategy.AuthCnfg{
	SiteURL:      os.Getenv("SPAUTH_SITEURL"),
	ClientID:     os.Getenv("SPAUTH_CLIENTID"),
	ClientSecret: os.Getenv("SPAUTH_CLIENTSECRET"),
}

AuthCnfg from different strategies contains different options relevant for a specified auth type.

The authentication options can be provided explicitly or can be read from a configuration file.

configPath := "./config/private.json"
auth := &strategy.AuthCnfg{}

err := auth.ReadConfig(configPath)
if err != nil {
	fmt.Printf("Unable to get config: %v\n", err)
	return
}

3. Bind auth client with Fluent API.

client := &gosip.SPClient{AuthCnfg: auth}

sp := api.NewSP(client)

res, err := sp.Web().Select("Title").Get()
if err != nil {
	fmt.Println(err)
}

fmt.Printf("%s\n", res.Data().Title)

Usage samples

Fluent API client

Fluent API gives a simple way of constructing API endpoint calls with IntelliSense and chainable syntax.

Fluent Sample

package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/koltyakov/gosip"
	"github.com/koltyakov/gosip/api"
	strategy "github.com/koltyakov/gosip/auth/addin"
)

func main() {
	// Getting auth params and client
	client, err := getAuthClient()
	if err != nil {
		log.Fatalln(err)
	}

	// Binding SharePoint API
	sp := api.NewSP(client)

	// Custom headers
	headers := map[string]string{
		"Accept": "application/json;odata=minimalmetadata",
		"Accept-Language": "de-DE,de;q=0.9",
	}
	config := &api.RequestConfig{Headers: headers}

	// Chainable request sample
	data, err := sp.Conf(config).Web().Lists().Select("Id,Title").Get()
	if err != nil {
		log.Fatalln(err)
	}

	// Response object unmarshalling (struct depends on OData mode and API method)
	res := &struct {
		Value []struct {
			ID    string `json:"Id"`
			Title string `json:"Title"`
		} `json:"value"`
	}{}

	if err := json.Unmarshal(data, &res); err != nil {
		log.Fatalf("unable to parse the response: %v", err)
	}

	for _, list := range res.Value {
		fmt.Printf("%+v\n", list)
	}

}

func getAuthClient() (*gosip.SPClient, error) {
	configPath := "./config/private.spo-addin.json"
	auth := &strategy.AuthCnfg{}
	if err := auth.ReadConfig(configPath); err != nil {
		return nil, fmt.Errorf("unable to get config: %v", err)
	}
	return &gosip.SPClient{AuthCnfg: auth}, nil
}

Generic HTTP client helper

Provides generic GET/POST helpers for REST operations, reducing the amount of http.NewRequest scaffolded code, can be used for custom or not covered with Fluent API endpoints.

package main

import (
	"fmt"
	"log"

	"github.com/koltyakov/gosip"
	"github.com/koltyakov/gosip/api"
	strategy "github.com/koltyakov/gosip/auth/ntlm"
)

func main() {
	configPath := "./config/private.ntlm.json"
	auth := &strategy.AuthCnfg{}

	if err := auth.ReadConfig(configPath); err != nil {
		log.Fatalf("unable to get config: %v\n", err)
	}

	sp := api.NewHTTPClient(&gosip.SPClient{AuthCnfg: auth})

	endpoint := auth.GetSiteURL() + "/_api/web?$select=Title"

	data, err := sp.Get(endpoint, nil)
	if err != nil {
		log.Fatalf("%v\n", err)
	}

	// sp.Post(endpoint, body, nil) // generic POST
	// sp.Delete(endpoint, nil) // generic DELETE helper crafts "X-Http-Method"="DELETE" header
	// sp.Update(endpoint, nil) // generic UPDATE helper crafts "X-Http-Method"="MERGE" header
	// sp.ProcessQuery(endpoint, body) // CSOM helper (client.svc/ProcessQuery)

	fmt.Printf("response: %s\n", data)
}

Low-level HTTP client usage

Low-lever SharePoint-aware HTTP client from github.com/koltyakov/gosip package for custom or not covered with a Fluent API client endpoints with granular control for an HTTP request, response, and http.Client parameters. The client is used internally but rarely required in consumer code.

client := &gosip.SPClient{AuthCnfg: auth}

var req *http.Request
// Initiate API request
// ...

resp, err := client.Execute(req)
if err != nil {
	fmt.Printf("Unable to request api: %v", err)
	return
}

SPClient has Execute method which is a wrapper function injecting SharePoint authentication and ending up calling http.Client's Do method.

Authentication strategies

Auth strategy should be selected corresponding to your SharePoint environment and its configuration.

Import path strategy "github.com/koltyakov/gosip/auth/{strategy}". Where /{strategy} stands for a strategy auth package.

Azure AD based strategies (recommended production use with SharePoint Online):

/{strategy} Description Credentials sample(s)
/azurecert Azure AD Certificate authentication details
/azurecreds Azure AD authorization with username and password details
/azureenv Azure AD environment-based authentication details
/device Azure AD Device Token authentication details

Other strategies:

/{strategy} SPO On-Prem Credentials sample(s)
/saml details
/addin details
/ntlm details
/adfs details
/fba details
/tmg details
/ondemand details

Environment should configured for a specific auth strategy. E.g. you won't succeed with adfs in SPO if it has not setup properly.

Below are the most commonly authentication methods in more details:

Azure AD application authentication

Azure AD application authentication is a recommended way for production use with SharePoint Online. It's based on OAuth 2.0 protocol and uses AAD application credentials for authentication.

Depending on an application type, there are different authentication strategies:

  • Azure AD Certificate authentication: for headless applications, which are not able to provide user interaction, like a background service or a daemon. It uses a certificate to authenticate an application.
  • Azure AD authorization with username and password: for applications which are able to provide user interaction, like a desktop application or CLI with credentials prompt. It uses a username and password to authenticate a user.
  • Azure AD device token authentication: for applications which are able to provide user interaction, like a desktop application or CLI. It uses a device code to authenticate a user. It also supports multi-factor authentication.

SAML Auth (SharePoint Online user credentials authentication)

This authentication option uses Microsoft Online Security Token Service https://login.microsoftonline.com/extSTS.srf and SAML tokens in order to obtain an authentication cookie.

// AuthCnfg - SAML auth config structure
type AuthCnfg struct {
	// SPSite or SPWeb URL, which is the context target for the API calls
	SiteURL string `json:"siteUrl"`
	// Username for SharePoint Online, for example `[user]@[company].onmicrosoft.com`
	Username string `json:"username"`
	// User or App password
	Password string `json:"password"`
}

AddIn Only Auth

This type of authentication uses AddIn Only policy and OAuth bearer tokens for authenticating HTTP requests.

// AuthCnfg - AddIn Only auth config structure
type AuthCnfg struct {
	// SPSite or SPWeb URL, which is the context target for the API calls
	SiteURL string `json:"siteUrl"`
	// Client ID obtained when registering the AddIn
	ClientID string `json:"clientId"`
	// Client Secret obtained when registering the AddIn
	ClientSecret string `json:"clientSecret"`
	// Your SharePoint Online tenant ID (optional)
	Realm string `json:"realm"`
}

Realm can be left empty or filled in, which will add small performance improvement. The easiest way to find the tenant is to open SharePoint Online site collection, click Site Settings -> Site App Permissions. Taking any random app, the tenant ID (realm) is the GUID part after the @.

See more details of AddIn Configuration and Permissions.

NTLM Auth (NTLM handshake)

This type of authentication uses an HTTP NTLM handshake to obtain an authentication header.

// AuthCnfg - NTLM auth config structure
type AuthCnfg struct {
	// SPSite or SPWeb URL, which is the context target for the API calls
	SiteURL  string `json:"siteUrl"`
	Domain   string `json:"domain"`   // AD domain name
	Username string `json:"username"` // AD user name
	Password string `json:"password"` // AD user password
}

Gosip uses github.com/Azure/go-ntlmssp NTLM negotiator, however, a custom one also can be provided in case of demand.

Secrets encoding

When storing credential in local private.json files, which can be handy in local development scenarios, we strongly recommend to encode secrets such as password or clientSecret using cpass. Class converts a secret to an encrypted representation, which can only be decrypted on the same machine where it was generated. That reduces accidental leaks, e.g. together with git commits.

Reference

Many auth flows have been "copied" from node-sp-auth library (used as a blueprint), which we intensively use in Node.js ecosystem for years.

Fluent API and wrapper syntax are inspired by PnPjs, which is also the first-class citizen on almost all our Node.js and front-end projects with SharePoint involved.

📦 Samples

License

FOSSA Status

More Repositories

1

sp-rest-proxy

🌐 SharePoint API Proxy for local development
TypeScript
172
star
2

generator-sppp

🐾 SP Pull-n-Push - Yeoman generator for SharePoint client-side applications
TypeScript
64
star
3

sppull

📎 Download files from SharePoint document libraries using Node.js without hassles
TypeScript
45
star
4

mvp-monitor

📊 Microsoft MVPs Monitor
PowerShell
32
star
5

sp-pnp-node

SharePoint JavaScript Core Library wrapper helper for Node.js
TypeScript
25
star
6

sp-live-reload

SharePoint pages live reload module for client side development
TypeScript
23
star
7

sp-jsom-node

🚴 SharePoint JavaScript Object Model for Node.js
JavaScript
21
star
8

node-sp-auth-config

🔧 Config options builder for node-sp-auth (SharePoint Authentication in Node.js)
TypeScript
20
star
9

sp-metadata

🔬 SharePoint Metadata Tracker
Go
18
star
10

cq-source-sharepoint

🔌 CloudQuery SharePoint Source Plugin
Go
17
star
11

sp-build-tasks

👷 SharePoint front-end projects automation and tasks tool-belt
TypeScript
16
star
12

sp-screwdriver

Adds missing and abstracts SharePoint APIs for transparent usage in Node.js applications
TypeScript
15
star
13

az-fun-go-sp

Azure Functions Golang & SharePoint Sample
Go
13
star
14

azure-openai-sample

Azure OpenAI sample
TypeScript
13
star
15

pnp-upload

SharePoint: Large files upload example using PnPjs from Node.js
TypeScript
13
star
16

sp-download

SharePoint files download client in Node.js
TypeScript
13
star
17

cpass

🔐 Simple secure string password convertor
TypeScript
12
star
18

spsync

🪢 Go library for robust cloud native SharePoint Lists synchronization or backup
Go
10
star
19

sppurge

Delete files from SharePoint document libraries using Node.js without hassles
TypeScript
9
star
20

gosip-docs

📚 Docs: SharePoint authentication, HTTP client & fluent API wrapper for Go (Golang)
9
star
21

sp-modernizer-kit

SharePoint Online classic sites modernizer kit
TypeScript
7
star
22

SPSyncN

SharePoint .Net assets sync via Node.js
JavaScript
6
star
23

sp-time-machine

⏳ Incrementally backup SharePoint Lists across tenants
Go
6
star
24

gosip-sandbox

🐣 Sandbox: Samples, experiments for Gosip client
Go
6
star
25

github-notify

:octocat: GitHub Notifications for desktop
Go
6
star
26

spvault

SharePoint Authentication Vault gRPC Server
Go
5
star
27

sp-auth-puppeteer-sample

Puppeteer & node-sp-auth example
TypeScript
5
star
28

SPAuthN

SharePoint .Net auth via Node.js
C#
5
star
29

sp-auth-electron-sample

Electron & node-sp-auth example
TypeScript
5
star
30

node-sharepoint-examples

Node.js SharePoint Examples
TypeScript
5
star
31

on-el-resize

On HTML element resize event fire helper
TypeScript
4
star
32

sp-sig-20180705-demo

PnP and SharePoint SIG / July 5th, 2018 / Demo Examples (List Items System Update options in Modern SPO Stack)
TypeScript
3
star
33

spfx-styled-components-sample

Styled Components and SPFx theming sample (SIG 2020/06/04)
TypeScript
3
star
34

spday-spb-2018-js-usecases

SharePoint Day 2018 - SharePoint JS API Consumption Examples
TypeScript
2
star
35

blogs-technet-grabber

blogs.technet.microsoft.com grabber
TypeScript
1
star
36

PnP-JS-Core-Debug

PnP-JS-Core Quick Debug in Node JS - a service project to allow quick interactive testing while contributing to sp-pnp-js
TypeScript
1
star
37

PnPjs-Debug

PnPjs Quick Debug in Node JS - a service project to allow quick interactive testing while contributing to PnPjs
TypeScript
1
star
38

sp-sig-20170608-demo

PnP and SharePoint SIG / June 8th, 2017 / Demo Examples
TypeScript
1
star
39

node-sp-auth-troubleshoot

Node.js SharePoint Auth Troubleshooting
JavaScript
1
star