github.com/psyb0t/mattermost-server@v4.6.1-0.20180125161845-5503a1351abf+incompatible/api/oauth.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package api
     5  
     6  import (
     7  	"net/http"
     8  
     9  	"github.com/gorilla/mux"
    10  	"github.com/mattermost/mattermost-server/model"
    11  )
    12  
    13  func (api *API) InitOAuth() {
    14  	api.BaseRoutes.OAuth.Handle("/register", api.ApiUserRequired(registerOAuthApp)).Methods("POST")
    15  	api.BaseRoutes.OAuth.Handle("/list", api.ApiUserRequired(getOAuthApps)).Methods("GET")
    16  	api.BaseRoutes.OAuth.Handle("/app/{client_id}", api.ApiUserRequired(getOAuthAppInfo)).Methods("GET")
    17  	api.BaseRoutes.OAuth.Handle("/allow", api.ApiUserRequired(allowOAuth)).Methods("GET")
    18  	api.BaseRoutes.OAuth.Handle("/authorized", api.ApiUserRequired(getAuthorizedApps)).Methods("GET")
    19  	api.BaseRoutes.OAuth.Handle("/delete", api.ApiUserRequired(deleteOAuthApp)).Methods("POST")
    20  	api.BaseRoutes.OAuth.Handle("/{id:[A-Za-z0-9]+}/deauthorize", api.ApiUserRequired(deauthorizeOAuthApp)).Methods("POST")
    21  	api.BaseRoutes.OAuth.Handle("/{id:[A-Za-z0-9]+}/regen_secret", api.ApiUserRequired(regenerateOAuthSecret)).Methods("POST")
    22  	api.BaseRoutes.OAuth.Handle("/{service:[A-Za-z0-9]+}/login", api.AppHandlerIndependent(loginWithOAuth)).Methods("GET")
    23  	api.BaseRoutes.OAuth.Handle("/{service:[A-Za-z0-9]+}/signup", api.AppHandlerIndependent(signupWithOAuth)).Methods("GET")
    24  }
    25  
    26  func registerOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
    27  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_OAUTH) {
    28  		c.Err = model.NewAppError("registerOAuthApp", "api.command.admin_only.app_error", nil, "", http.StatusForbidden)
    29  		return
    30  	}
    31  
    32  	oauthApp := model.OAuthAppFromJson(r.Body)
    33  
    34  	if oauthApp == nil {
    35  		c.SetInvalidParam("registerOAuthApp", "app")
    36  		return
    37  	}
    38  
    39  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
    40  		oauthApp.IsTrusted = false
    41  	}
    42  
    43  	oauthApp.CreatorId = c.Session.UserId
    44  
    45  	rapp, err := c.App.CreateOAuthApp(oauthApp)
    46  
    47  	if err != nil {
    48  		c.Err = err
    49  		return
    50  	}
    51  
    52  	c.LogAudit("client_id=" + rapp.Id)
    53  	w.Write([]byte(rapp.ToJson()))
    54  }
    55  
    56  func getOAuthApps(c *Context, w http.ResponseWriter, r *http.Request) {
    57  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_OAUTH) {
    58  		c.Err = model.NewAppError("getOAuthApps", "api.command.admin_only.app_error", nil, "", http.StatusForbidden)
    59  		return
    60  	}
    61  
    62  	var apps []*model.OAuthApp
    63  	var err *model.AppError
    64  	if c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) {
    65  		apps, err = c.App.GetOAuthApps(0, 100000)
    66  	} else {
    67  		apps, err = c.App.GetOAuthAppsByCreator(c.Session.UserId, 0, 100000)
    68  	}
    69  
    70  	if err != nil {
    71  		c.Err = err
    72  		return
    73  	}
    74  
    75  	w.Write([]byte(model.OAuthAppListToJson(apps)))
    76  }
    77  
    78  func getOAuthAppInfo(c *Context, w http.ResponseWriter, r *http.Request) {
    79  	params := mux.Vars(r)
    80  	clientId := params["client_id"]
    81  
    82  	oauthApp, err := c.App.GetOAuthApp(clientId)
    83  
    84  	if err != nil {
    85  		c.Err = err
    86  		return
    87  	}
    88  
    89  	oauthApp.Sanitize()
    90  	w.Write([]byte(oauthApp.ToJson()))
    91  }
    92  
    93  func allowOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
    94  	responseType := r.URL.Query().Get("response_type")
    95  	if len(responseType) == 0 {
    96  		c.Err = model.NewAppError("allowOAuth", "api.oauth.allow_oauth.bad_response.app_error", nil, "", http.StatusBadRequest)
    97  		return
    98  	}
    99  
   100  	clientId := r.URL.Query().Get("client_id")
   101  	if len(clientId) != 26 {
   102  		c.Err = model.NewAppError("allowOAuth", "api.oauth.allow_oauth.bad_client.app_error", nil, "", http.StatusBadRequest)
   103  		return
   104  	}
   105  
   106  	redirectUri := r.URL.Query().Get("redirect_uri")
   107  	if len(redirectUri) == 0 {
   108  		c.Err = model.NewAppError("allowOAuth", "api.oauth.allow_oauth.bad_redirect.app_error", nil, "", http.StatusBadRequest)
   109  		return
   110  	}
   111  
   112  	scope := r.URL.Query().Get("scope")
   113  	state := r.URL.Query().Get("state")
   114  
   115  	c.LogAudit("attempt")
   116  
   117  	authRequest := &model.AuthorizeRequest{
   118  		ResponseType: responseType,
   119  		ClientId:     clientId,
   120  		RedirectUri:  redirectUri,
   121  		Scope:        scope,
   122  		State:        state,
   123  	}
   124  
   125  	redirectUrl, err := c.App.AllowOAuthAppAccessToUser(c.Session.UserId, authRequest)
   126  
   127  	if err != nil {
   128  		c.Err = err
   129  		return
   130  	}
   131  
   132  	c.LogAudit("")
   133  
   134  	w.Write([]byte(model.MapToJson(map[string]string{"redirect": redirectUrl})))
   135  }
   136  
   137  func getAuthorizedApps(c *Context, w http.ResponseWriter, r *http.Request) {
   138  	apps, err := c.App.GetAuthorizedAppsForUser(c.Session.UserId, 0, 10000)
   139  	if err != nil {
   140  		c.Err = err
   141  		return
   142  	}
   143  
   144  	w.Write([]byte(model.OAuthAppListToJson(apps)))
   145  }
   146  
   147  func loginWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
   148  	params := mux.Vars(r)
   149  	service := params["service"]
   150  	loginHint := r.URL.Query().Get("login_hint")
   151  	redirectTo := r.URL.Query().Get("redirect_to")
   152  
   153  	teamId, err := c.App.GetTeamIdFromQuery(r.URL.Query())
   154  	if err != nil {
   155  		c.Err = err
   156  		return
   157  	}
   158  
   159  	if authUrl, err := c.App.GetOAuthLoginEndpoint(w, r, service, teamId, model.OAUTH_ACTION_LOGIN, redirectTo, loginHint); err != nil {
   160  		c.Err = err
   161  		return
   162  	} else {
   163  		http.Redirect(w, r, authUrl, http.StatusFound)
   164  	}
   165  }
   166  
   167  func signupWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
   168  	params := mux.Vars(r)
   169  	service := params["service"]
   170  
   171  	if !c.App.Config().TeamSettings.EnableUserCreation {
   172  		c.Err = model.NewAppError("signupWithOAuth", "api.oauth.singup_with_oauth.disabled.app_error", nil, "", http.StatusNotImplemented)
   173  		return
   174  	}
   175  
   176  	teamId, err := c.App.GetTeamIdFromQuery(r.URL.Query())
   177  	if err != nil {
   178  		c.Err = err
   179  		return
   180  	}
   181  
   182  	if authUrl, err := c.App.GetOAuthSignupEndpoint(w, r, service, teamId); err != nil {
   183  		c.Err = err
   184  		return
   185  	} else {
   186  		http.Redirect(w, r, authUrl, http.StatusFound)
   187  	}
   188  }
   189  
   190  func deleteOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
   191  	props := model.MapFromJson(r.Body)
   192  
   193  	id := props["id"]
   194  	if len(id) == 0 {
   195  		c.SetInvalidParam("deleteOAuthApp", "id")
   196  		return
   197  	}
   198  
   199  	c.LogAudit("attempt")
   200  
   201  	if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_OAUTH) {
   202  		c.Err = model.NewAppError("deleteOAuthApp", "api.command.admin_only.app_error", nil, "", http.StatusForbidden)
   203  		return
   204  	}
   205  
   206  	oauthApp, err := c.App.GetOAuthApp(id)
   207  	if err != nil {
   208  		c.Err = err
   209  		return
   210  	}
   211  
   212  	if c.Session.UserId != oauthApp.CreatorId && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) {
   213  		c.LogAudit("fail - inappropriate permissions")
   214  		c.Err = model.NewAppError("deleteOAuthApp", "api.oauth.delete.permissions.app_error", nil, "user_id="+c.Session.UserId, http.StatusForbidden)
   215  		return
   216  	}
   217  
   218  	err = c.App.DeleteOAuthApp(id)
   219  	if err != nil {
   220  		c.Err = err
   221  		return
   222  	}
   223  
   224  	c.LogAudit("success")
   225  	ReturnStatusOK(w)
   226  }
   227  
   228  func deauthorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
   229  	params := mux.Vars(r)
   230  	id := params["id"]
   231  
   232  	err := c.App.DeauthorizeOAuthAppForUser(c.Session.UserId, id)
   233  	if err != nil {
   234  		c.Err = err
   235  		return
   236  	}
   237  
   238  	c.LogAudit("success")
   239  	ReturnStatusOK(w)
   240  }
   241  
   242  func regenerateOAuthSecret(c *Context, w http.ResponseWriter, r *http.Request) {
   243  	params := mux.Vars(r)
   244  	id := params["id"]
   245  
   246  	oauthApp, err := c.App.GetOAuthApp(id)
   247  	if err != nil {
   248  		c.Err = err
   249  		return
   250  	}
   251  
   252  	if oauthApp.CreatorId != c.Session.UserId && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) {
   253  		c.Err = model.NewAppError("regenerateOAuthSecret", "api.command.admin_only.app_error", nil, "", http.StatusForbidden)
   254  		return
   255  	}
   256  
   257  	oauthApp, err = c.App.RegenerateOAuthAppSecret(oauthApp)
   258  	if err != nil {
   259  		c.Err = err
   260  		return
   261  	}
   262  
   263  	w.Write([]byte(oauthApp.ToJson()))
   264  }